ESP32 NTP Time

ESP32 NTP Time

ESP32 NTP Time - zonas horarias y horario de verano

Documentación Técnica

NetworkTimeProtocol (NTP) es un protocolo de Internet para sincronizar los relojes de los sistemas informáticos a través del enrutamiento de paquetes en redes con latencia variable. NTP utiliza UDP como su capa de transporte, usando el puerto 123. Está diseñado para resistir los efectos de la latencia variable.

Tutorial

En este tutorial, aprenderá cómo obtener correctamente la hora con el ESP32 para su zona horaria y considerar el horario de verano (si ese es el caso). El ESP32 solicitará la hora a un servidor NTP, y la hora se ajustará automáticamente a su zona horaria con o sin horario de verano.

ESP32 Configuración de la zona horaria con horario de verano

"Para establecer la zona horaria local, use setenv y tzset Funciones POSIX. Primero, llame a setenv Para establecer TZ variable de entorno al valor correcto en función de la ubicación del dispositivo. El formato de la cadena de tiempo se describe en la documentación de libc. A continuación, llame a tzset para actualizar los datos de tiempo de ejecución de la biblioteca C para la nueva zona horaria. Una vez que se realizan estos pasos, la función localtime devolverá la hora local correcta, teniendo en cuenta el desplazamiento de la zona horaria y el horario de verano".

Puede consultar una lista de variables de cadena de zona horaria aquí.

setenv("TZ","WET0WEST,M3.5.0/1,M10.5.0",1);

Seguido de:

tzset();

Esquema de ejemplo de zona horaria y DST de ESP32

// MONARCATECH
#include <WiFi.h> #include "time.h" const char * ssid="REPLACE_WITH_YOUR_SSID"; const char * wifipw="REPLACE_WITH_YOUR_PASSWORD"; void setTimezone(String timezone){ Serial.printf(" Setting Timezone to %s\n",timezone.c_str()); setenv("TZ",timezone.c_str(),1); // Now adjust the TZ. Clock settings are adjusted to show the new local time tzset(); } void initTime(String timezone){ struct tm timeinfo; Serial.println("Setting up time"); configTime(0, 0, "pool.ntp.org"); // First connect to NTP server, with 0 TZ offset if(!getLocalTime(&timeinfo)){ Serial.println(" Failed to obtain time"); return; } Serial.println(" Got the time from NTP"); // Now we can set the real timezone setTimezone(timezone); } void printLocalTime(){ struct tm timeinfo; if(!getLocalTime(&timeinfo)){ Serial.println("Failed to obtain time 1"); return; } Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S zone %Z %z "); } void startWifi(){ WiFi.begin(ssid, wifipw); Serial.println("Connecting Wifi"); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.print("Wifi RSSI="); Serial.println(WiFi.RSSI()); } void setTime(int yr, int month, int mday, int hr, int minute, int sec, int isDst){ struct tm tm; tm.tm_year = yr - 1900; // Set date tm.tm_mon = month-1; tm.tm_mday = mday; tm.tm_hour = hr; // Set time tm.tm_min = minute; tm.tm_sec = sec; tm.tm_isdst = isDst; // 1 or 0 time_t t = mktime(&tm); Serial.printf("Setting time: %s", asctime(&tm)); struct timeval now = { .tv_sec = t }; settimeofday(&now, NULL); } void setup(){ Serial.begin(115200); Serial.setDebugOutput(true); startWifi(); initTime("WET0WEST,M3.5.0/1,M10.5.0"); // Set for Melbourne/AU printLocalTime(); } void loop() { int i; // put your main code here, to run repeatedly: Serial.println("Lets show the time for a bit. Starting with TZ set for Melbourne/Australia"); for(i=0; i<10; i++){ delay(1000); printLocalTime(); } Serial.println(); Serial.println("Now - change timezones to Berlin"); setTimezone("CET-1CEST,M3.5.0,M10.5.0/3"); for(i=0; i<10; i++){ delay(1000); printLocalTime(); } Serial.println(); Serial.println("Now - Lets change back to Lisbon and watch Daylight savings take effect"); setTimezone("WET0WEST,M3.5.0/1,M10.5.0"); printLocalTime(); Serial.println(); Serial.println("Now change the time. 1 min before DST takes effect. (1st Sunday of Oct)"); Serial.println("AEST = Australian Eastern Standard Time. = UTC+10"); Serial.println("AEDT = Australian Eastern Daylight Time. = UTC+11"); setTime(2021,10,31,0,59,50,0); // Set it to 1 minute before daylight savings comes in. for(i=0; i<20; i++){ delay(1000); printLocalTime(); } Serial.println("Now change the time. 1 min before DST should finish. (1st Sunday of April)"); setTime(2021,3,28,1,59,50,1); // Set it to 1 minute before daylight savings comes in. Note. isDst=1 to indicate that the time we set is in DST. for(i=0; i<20; i++){ delay(1000); printLocalTime(); } // Now lets watch the time and see how long it takes for NTP to fix the clock Serial.println("Waiting for NTP update (expect in about 1 hour)"); while(1) { delay(1000); printLocalTime(); } }

 

Cómo funciona el código

En primer lugar, debe incluir el atributo Conexión Wi-Fi para conectar el ESP32 a Internet (servidor NTP) y el Hora biblioteca para lidiar con el tiempo.

#include <WiFi.h>

#include "time.h"

 

Para establecer la zona horaria, creamos una función llamada setTimezone() que acepta como argumento una cadena de zona horaria.

void setTimezone(String timezone){

Dentro de esa función, llamamos a la función setenv() para la función TZ (timezone) para establecer la zona horaria con cualquier zona horaria que pase como argumento a la variable setTimezone() función.

setenv("TZ",timezone.c_str(),1); // Now adjust the TZ. Clock settings are adjusted to show the new local time

Después de eso, llame al método tzset() para que los cambios surtan efecto.

tzset();

configuración()

En configuración(), inicializamos Wi-Fi para que el ESP32 pueda conectarse a Internet para conectarse al servidor NTP.

initWifi();

A continuación, llame a la función initTime() y pase como argumento la zona horaria String. En nuestro caso, para la zona horaria de Lisboa/PT.

initTime("WET0WEST,M3.5.0/1,M10.5.0");   // Set for Lisbon/PT

Después de eso, imprima la hora local actual.

printLocalTime();

bucle()

En bucle() Muestra la hora local durante diez segundos.

Serial.println("Lets show the time for a bit.  Starting with TZ set for Lisbon/Portugal");
for(i=0; i<10; i++){
  delay(1000);
  printLocalTime();
}

Si en algún momento de tu código necesitas cambiar la zona horaria, puedes hacerlo llamando a la función setTimezone() y pasando como argumento la cadena de zona horaria. Por ejemplo, las siguientes líneas cambian la zona horaria a Berlín y muestran la hora durante diez segundos.

Serial.println();
Serial.println("Now - change timezones to Berlin");
setTimezone("CET-1CEST,M3.5.0,M10.5.0/3");
for(i=0; i<10; i++){
  delay(1000);
  printLocalTime();
}

Luego, volvemos a nuestra hora local llamando al setTimezone() función de nuevo con la variable de cadena de zona horaria Lisbon/PT.

Serial.println();
Serial.println("Now - Lets change back to Lisbon and watch Daylight savings take effect");
setTimezone("WET0WEST,M3.5.0/1,M10.5.0");
printLocalTime();

Para comprobar si el horario de verano está surtiendo efecto, cambiaremos la hora a 10 segundos antes de que surta efecto el horario de invierno. En nuestro caso, es el último domingo de octubre (puede ser diferente para tu ubicación).

Serial.println();
Serial.println("Now change the time.  1 min before DST takes effect. (Last Sunday of Oct)");
setTime(2021,10,31,0,59,50,0);    // Set it to 1 minute before daylight savings comes in.

A continuación, muestra la hora durante un rato para comprobar que se está ajustando la hora, teniendo en cuenta el horario de verano.

for(i=0; i<20; i++){
  delay(1000);
  printLocalTime();
}

Después de esto, cambiemos la hora nuevamente para verificar si cambia al horario de verano cuando llegue el momento. En nuestro caso, es el último domingo de marzo.

Serial.println("Now change the time.  1 min before DST should finish. (Last Sunday of March)");
setTime(2021,3,28,1,59,50,1);    // Set it to 1 minute before daylight savings comes in.  Note. isDst=1 to indicate that the time we set is in DST.

Muestra la hora un rato para comprobar que se está ajustando al horario de verano.

for(i=0; i<20; i++){
  delay(1000);
  printLocalTime();
}

 

📖 Descarga Información técnica

Regresar al blog

Deja un comentario

Ten en cuenta que los comentarios deben aprobarse antes de que se publiquen.