Internet de les coses amb ESP32 i ESP8266

Exemples Referència Plaques   Recursos CITCEA
Projectes Programació Perifèrics   Inici

Rellotge de temps real

En el següent programa farem servir el rellotge de temps real (RTC) per mostrar la data i l'hora. En el moment d'inicialitzar el programa fem servir la funció getTime de la biblioteca WiFiNINA per posar el rellotge en hora.

// Aquest programa està parcialment basat en els exemples de la pàgina
// https://www.arduino.cc/en/Tutorial/WiFiRTC
#include <SPI.h>    // Carreguem la biblioteca SPI
#include <WiFiNINA.h>    // Carreguem la biblioteca WiFiNINA
#include <WiFiUdp.h>    // Farem servir el protocol UDP
#include <RTCZero.h>    // Per gestionar el rellotge de temps real
#define numIntents 6
const char idXarxa[] = "xarxa-wifi";    // Nom del punt d'accés 
const char contrasenya[] = "contrasenya-wifi";    // Contrasenya de connexió 
int status = WL_IDLE_STATUS;
const int GMT = 2;  // Valor que hem de sumar a l'hora GMT
RTCZero rtc;
void estatWiFi() {
  // Mostra les dades de la connexió
  Serial.print("Xarxa: ");
  Serial.println(WiFi.SSID());
  IPAddress ip = WiFi.localIP();
  Serial.print("Adreça IP: ");
  Serial.println(ip);
  long rssi = WiFi.RSSI();
  Serial.print("Qualitat del senyal (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}
void dosDigits(int valor) {
  if (valor < 10) {
    Serial.print("0");
  }
  Serial.print(valor);
}
void setup() {    // Inicialització
  unsigned long instant;
  Serial.begin(9600);
  // Comprovem si hi ha el mòdul Wi-Fi
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("No s'ha trobat el mòdul Wi-Fi");
    while (true);  // Es bloqueja aquí
  }
  // Anem a connectar a la xarxa
  while ( status != WL_CONNECTED) {
    Serial.println("Connectant...");
    status = WiFi.begin(idXarxa, contrasenya);
    // Esperem 10 s abans de tornar-ho a intentar
    delay(10000);
  }
  // Ja estem connectats, mostrem la informació
  estatWiFi();
  rtc.begin();  // Inicialitzem RTC
  // Anem a posar el rellotge en hora
  int intents = 0;
  do {
    instant = WiFi.getTime();
    intents++;
  } while ((instant == 0) && (intents < numIntents));
  if (intents == numIntents) {
    Serial.print("No s'ha pogut llegir l'hora!");
    while (1);  // Es bloqueja aquí
  } else {
    Serial.print("Instant rebut: ");
    Serial.println(instant);
    rtc.setEpoch(instant + 3600 * GMT);  // Ho posem, corregit, a RTC
    // Ja tenim el rellotge en hora, no cal tornar-ho a mirar a internet
    Serial.println();
  }
}
void loop() {    // Programa que es repeteix indefinidament
  Serial.print("Data: ");
  Serial.print(rtc.getDay());
  Serial.print("-");
  Serial.print(rtc.getMonth());
  Serial.print("-");
  Serial.println(rtc.getYear());
  Serial.print("Hora: ");
  dosDigits(rtc.getHours());
  Serial.print(".");
  dosDigits(rtc.getMinutes());
  Serial.print(".");
  dosDigits(rtc.getSeconds());
  Serial.println();
  delay(1000);
}

El següent programa és una variant de l'anterior que posa el NeoPixel de color vermell en el segon 12 de cada minut, verd en el segon 32 i blau en el segon 52.

// Aquest programa està parcialment basat en els exemples de la pàgina
// https://www.arduino.cc/en/Tutorial/WiFiRTC
#include <SPI.h>    // Carreguem la biblioteca SPI
#include <WiFiNINA.h>    // Carreguem la biblioteca WiFiNINA
#include <WiFiUdp.h>    // Farem servir el protocol UDP
#include <RTCZero.h>    // Per gestionar el rellotge de temps real
#include <Adafruit_NeoPixel.h>  // Per al NeoPixel
#define numIntents 6
Adafruit_NeoPixel cadena = Adafruit_NeoPixel(1, 1, NEO_GRB + NEO_KHZ800);
const char idXarxa[] = "xarxa-wifi";    // Nom del punt d'accés 
const char contrasenya[] = "contrasenya-wifi";    // Contrasenya de connexió 
int status = WL_IDLE_STATUS;
const int GMT = 2;  // Valor que hem de sumar a l'hora GMT
boolean descans = false;
RTCZero rtc;
void estatWiFi() {
  // Mostra les dades de la connexió
  Serial.print("Xarxa: ");
  Serial.println(WiFi.SSID());
  IPAddress ip = WiFi.localIP();
  Serial.print("Adreça IP: ");
  Serial.println(ip);
  long rssi = WiFi.RSSI();
  Serial.print("Qualitat del senyal (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}
void dosDigits(int valor) {
  if (valor < 10) {
    Serial.print("0");
  }
  Serial.print(valor);
}
void funcioAlarma() {
  if (rtc.getSeconds() >= 52){
    rtc.setAlarmTime(0, 0, 12);
    cadena.setPixelColor(0, 0, 0, 255);
  } else if (rtc.getSeconds() >= 32){ 
    rtc.setAlarmTime(0, 0, 52);
    cadena.setPixelColor(0, 0, 255, 0);
  } else if (rtc.getSeconds() >= 12){ 
    rtc.setAlarmTime(0, 0, 32);
    cadena.setPixelColor(0, 255, 0, 0);
  }
  cadena.show();
  descans = true;
}
void setup() {    // Inicialització
  unsigned long instant;
  Serial.begin(9600);
  // Comprovem si hi ha el mòdul Wi-Fi
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("No s'ha trobat el mòdul Wi-Fi");
    while (true);  // Es bloqueja aquí
  }
  // Anem a connectar a la xarxa
  while ( status != WL_CONNECTED) {
    Serial.println("Connectant...");
    status = WiFi.begin(idXarxa, contrasenya);
    // Esperem 10 s abans de tornar-ho a intentar
    delay(10000);
  }
  // Ja estem connectats, mostrem la informació
  estatWiFi();
  rtc.begin();  // Inicialitzem RTC
  // Anem a posar el rellotge en hora
  int intents = 0;
  do {
    instant = WiFi.getTime();
    intents++;
  } while ((instant == 0) && (intents < numIntents));
  if (intents == numIntents) {
    Serial.print("No s'ha pogut llegir l'hora!");
    while (1);  // Es bloqueja aquí
  } else {
    Serial.print("Instant rebut: ");
    Serial.println(instant);
    rtc.setEpoch(instant + 3600 * GMT);  // Ho posem, corregit, a RTC
    // Ja tenim el rellotge en hora, no cal tornar-ho a mirar a internet
    Serial.println();
  }
  cadena.begin();  // Inicialitza els NeoPixels				
  cadena.show();
  rtc.setAlarmTime(0, 0, 12);
  rtc.enableAlarm(rtc.MATCH_SS);
  rtc.attachInterrupt(funcioAlarma);}
void loop() {    // Programa que es repeteix indefinidament
  if (descans){
    rtc.standbyMode();
    descans = false;
  }
  Serial.print("Data: ");
  Serial.print(rtc.getDay());
  Serial.print("-");
  Serial.print(rtc.getMonth());
  Serial.print("-");
  Serial.println(rtc.getYear());
  Serial.print("Hora: ");
  dosDigits(rtc.getHours());
  Serial.print(".");
  dosDigits(rtc.getMinutes());
  Serial.print(".");
  dosDigits(rtc.getSeconds());
  Serial.println();
  delay(1000);
}

Observarem que ara gairebé no s'escriu res al canal sèrie. Cada cop que acaba la funció d'interrupció s'activa la variable descans que provoca que el microcontrolador entri en mode repòs, del que en sortirà a la següent interrupció.

 

 

 

 

 

 

 

 

 

 

Llicència de Creative Commons
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.