¿Alguna vez ha deseado obtener la fecha y hora exacta de un servidor NTP utilizando su ESP32? En este artículo, le mostraremos cómo puede lograrlo de forma sencilla y eficiente. Siga leyendo para descubrir cómo sincronizar su dispositivo ESP32 con un servidor NTP y obtener la hora correcta en todo momento. ¡No se pierda esta útil información!
De vez en cuando te encontrarás con una idea en la que mantener el tiempo es una prioridad absoluta. Por ejemplo, imagine un relé que debe activarse en un momento específico o un registrador de datos que necesita almacenar valores a intervalos precisos.
Lo primero que me viene a la mente es utilizar un chip RTC (Reloj en tiempo real). Sin embargo, dado que estos chips no son completamente precisos, deberá realizar ajustes manuales periódicos para mantenerlos sincronizados.
En cambio, es preferible utilizar ese Protocolo de tiempo de red (PNT). Si su proyecto ESP32 tiene acceso a Internet, puede obtener la fecha y la hora (con una precisión de unos pocos milisegundos UTC). GRATIS. Además, no necesita ningún hardware adicional.
¿Qué es un NTP?
NTP es una abreviatura de Protocolo de tiempo de red. Es un protocolo de Internet (IP) estándar para sincronizar los relojes de las computadoras a través de una red.
Este protocolo sincroniza todos los dispositivos en red. hora universal coordinada (UTC) en unos pocos milisegundos (50 milisegundos en la Internet pública y menos de 5 milisegundos en un entorno LAN).
La Hora Universal Coordinada (UTC) es un estándar de hora global similar a GMT (hora media de Greenwich). UTC no cambia; es lo mismo en todo el mundo.
La idea aquí es utilizar NTP para configurar los relojes de la computadora en UTC y luego aplicar cualquier zona horaria local o compensación del horario de verano. Esto nos permite sincronizar los relojes de nuestros ordenadores independientemente de la ubicación o las diferencias de zona horaria.
arquitectura NTP
NTP utiliza una arquitectura jerárquica. Cada nivel de la jerarquía se denomina capa.
En la parte superior se encuentran dispositivos de medición del tiempo de alta precisión, como relojes atómicos, GPS o relojes controlados por radio, los llamados relojes de hardware Stratum-0.
Los servidores Stratum 1 tienen una conexión directa a un reloj de hardware Stratum 0 y, por lo tanto, proporcionan la hora más precisa.
Cada capa de la jerarquía se sincroniza con la capa superior y actúa como servidor para las computadoras de las capas inferiores.
¿Cómo funciona NTP?
NTP puede funcionar de diferentes maneras. La configuración más común es operar en modo cliente-servidor.
El principio de funcionamiento básico es el siguiente:
- El dispositivo cliente, como el ESP32, se conecta al servidor NTP utilizando el Protocolo de datagramas de usuario (UDP) en el puerto 123.
- Luego, el cliente envía un paquete de solicitud al servidor NTP.
- En respuesta a esta solicitud, el servidor NTP envía un paquete de marca de tiempo. Un paquete de marca de tiempo contiene una variedad de datos, como una marca de tiempo UNIX, precisión, retraso o zona horaria.
- Luego, un cliente puede extraer la fecha y hora actuales de esto.
Preparando el IDE de Arduino
Debes tener el complemento ESP32 instalado en tu IDE de Arduino antes de continuar con este tutorial. Si aún no lo ha instalado, siga las instrucciones a continuación.
Obtener fecha y hora del servidor NTP
El siguiente esquema le muestra exactamente cómo obtener la fecha y la hora del servidor NTP.
#include <WiFi.h>
#include "time.h"
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;
void printLocalTime()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
void setup()
{
Serial.begin(115200);
//connect to WiFi
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");
//init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
//disconnect WiFi as it's no longer needed
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
}
void loop()
{
delay(1000);
printLocalTime();
}
Antes de comenzar a cargar el boceto, deberá realizar algunos cambios para asegurarse de que funcione para usted.
- Cambie las dos variables siguientes con sus credenciales de red para permitir que el ESP32 se conecte a una red existente.
const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASS";
- Ajuste el desplazamiento UTC para su zona horaria (en segundos). Mira esto Lista de compensaciones horarias UTC. A continuación se muestran algunos ejemplos para diferentes zonas horarias:
- Para UTC -5.00: -5 * 60 * 60: -18000
- Para UTC+1.00: 1*60*60: 3600
- Para UTC +0.00: 0 * 60 * 60: 0
const long gmtOffset_sec = 3600;
- Cambie la compensación de la luz del día (en segundos). Establezca el valor en 3600 si su país cumple con esto Hora de verano; de lo contrario, configúrelo en 0.
const int daylightOffset_sec = 3600;
Después de cargar el boceto, presione el botón EN en su ESP32. El monitor serie debe mostrar la fecha y la hora cada segundo.
Explicación del código
Echemos un vistazo rápido al código para ver cómo funciona. Primero, incluyamos las bibliotecas necesarias para este proyecto.
- WiFi.h es una biblioteca que contiene los métodos WiFi específicos de ESP32 que usaremos para conectarnos a una red.
- tiempo.h es la biblioteca de tiempo nativa ESP32 que maneja la sincronización del servidor NTP sin problemas.
#include <WiFi.h>
#include "time.h"
Luego se definen algunas constantes, p.e. B. SSID, contraseña de WiFi, compensación UTC y compensación de luz diurna.
const char* ssid = "YOUR_SSID";
const char* password = "YOUR_PASS";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;
También se especifica la dirección del servidor NTP. pool.ntp.org es un gran proyecto NTP abierto para este tipo de cosas.
const char* ntpServer = "pool.ntp.org";
pool.ntp.org selecciona automáticamente los servidores horarios que se encuentran físicamente cerca de usted. Sin embargo, si desea seleccionar un servidor específico, utilice una de las subzonas pool.ntp.org.
Área | nombre de host |
Mundial | piscina.ntp.org |
Asia | asia.pool.ntp.org |
Europa | europa.pool.ntp.org |
América del norte | norteamerica.pool.ntp.org |
Oceanía | oceania.pool.ntp.org |
Sudamerica | américa del sur.pool.ntp.org |
En el área de configuración, primero establecemos comunicación serial con la PC y luego nos conectamos a la red WiFi mediante la llamada WiFi.begin()
Función.
Serial.begin(115200);
//connect to WiFi
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");
Una vez que el ESP32 está conectado a la red, usamos eso configTime()
Función para inicializar el cliente NTP y obtener la fecha y hora del servidor NTP.
//init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Finalmente usamos la función personalizada. printLocalTime()
para imprimir la fecha y hora actuales.
El printLocalTime()
La función llama al getLocalTime()
Función interna. getLocalTime()
La función envía un paquete de solicitud a un servidor NTP, analiza el paquete de marca de tiempo recibido y almacena la información de fecha y hora en una estructura de tiempo llamada timeinfo.
void printLocalTime()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
En la siguiente tabla puedes ver cómo cada miembro de esta estructura temporal se relaciona con un dato específico.
%A | regresa entre semana |
%B | Devuelve el mes del año. |
%D | devuelve el día del mes |
%Y | Año de retorno |
%H | hora de regreso |
%METRO | devuelve minutos |
%S | devuelve segundos |
Obtenga la fecha y hora del servidor NTP usando ESP32
Cada cierto tiempo, te encontrarás con una idea donde mantener la hora es una prioridad. Por ejemplo, considera un relé que debe activarse a una hora específica o un registrador de datos que debe almacenar valores a intervalos precisos.
Lo primero que viene a la mente es utilizar un chip de RTC (Reloj de Tiempo Real). Sin embargo, debido a que estos chips no son perfectamente precisos, debes realizar ajustes manuales de forma regular para mantenerlos sincronizados.
En cambio, es preferible emplear el Protocolo de Tiempo de Red (NTP). Si tu proyecto ESP32 tiene acceso a Internet, puedes obtener la fecha y hora (con una precisión de unos pocos milisegundos de UTC) de forma GRATUITA. Además, no necesitas hardware adicional.
¿Qué es un NTP?
NTP es una abreviación de Protocolo de Tiempo de Red (Network Time Protocol). Es un Protocolo de Internet estándar para sincronizar los relojes de los ordenadores en una red.
Este protocolo sincroniza todos los dispositivos de la red con Tiempo Universal Coordinado (UTC) en cuestión de milisegundos (50 milisegundos en Internet público y menos de 5 milisegundos en un entorno LAN).
UTC es un estándar global de tiempo que es similar al GMT (Tiempo Medio de Greenwich). UTC no cambia; es el mismo en todo el mundo.
Arquitectura NTP
NTP emplea una arquitectura jerárquica. Cada nivel en la jerarquía se conoce como un estrato.
En la parte superior se encuentran dispositivos de alta precisión para llevar el tiempo, como relojes atómicos, GPS o relojes de radio, conocidos como relojes de hardware de estrato 0.
Los servidores de estrato 1 tienen una conexión directa con un reloj de hardware de estrato 0 y, por lo tanto, proporcionan el tiempo más preciso.
Cada estrato en la jerarquía se sincroniza con el estrato superior y actúa como un servidor para los ordenadores en estratos inferiores.
¿Cómo funciona NTP?
NTP puede operar de varias maneras. La configuración más común es operar en modo cliente-servidor.
El principio de funcionamiento fundamental es el siguiente:
- El dispositivo cliente, como el ESP32, se conecta al servidor NTP a través del Protocolo de Datagrama de Usuario (UDP) en el puerto 123.
- El cliente envía un paquete de solicitud al servidor NTP.
- En respuesta a esta solicitud, el servidor NTP envía un paquete de marca de tiempo. Un paquete de marca de tiempo contiene una variedad de datos, como una marca de tiempo UNIX, precisión, retardo o zona horaria.
- Un cliente puede extraer la fecha y hora actual de él.
Preparando el IDE de Arduino
Debes tener el complemento ESP32 instalado en tu IDE de Arduino antes de proceder con este tutorial. Si aún no lo has instalado, sigue el tutorial a continuación.
Obteniendo la Fecha y Hora del Servidor NTP
El boceto a continuación te mostrará exactamente cómo obtener la fecha y la hora del servidor NTP.
«`c
#include <WiFi.h>
#include «time.h»
const char* ssid = «TU_SSID»;
const char* contraseña = «TU_CONTRASEÑA»;
const char* ntpServer = «pool.ntp.org»;
const long gmtOffset_sec = 3600;
const int offset_sec de verano = 3600;
void imprimirHoraLocal()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println(«Error al obtener la hora»);
return;
}
Serial.println(&timeinfo, «%A, %d de %B del %Y %H:%M:%S»);
}
void configuración()
{
Serial.begin(115200);
//conectar a WiFi
Serial.printf(«Conectando a %s «, ssid);
WiFi.begin(ssid, contraseña);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(«.»);
}
Serial.println(» CONECTADO»);
//inicializar y obtener la hora
configTime(gmtOffset_sec, offset_sec de verano, ntpServer);
imprimirHoraLocal();
//desconectar WiFi ya que no es necesario
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
}
void bucle()
{
delay(1000);
imprimirHoraLocal();
}
«`
Antes de comenzar a cargar el boceto, deberás hacer algunos cambios para asegurarte de que funcione para ti.
- Modifica las siguientes dos variables con tus credenciales de red para que el ESP32 pueda conectarse a una red existente.
«`c
const char* ssid = «TU_SSID»;
const char* contraseña = «TU_CONTRASEÑA»;
«`
- Ajusta el desfase UTC para tu zona horaria (en segundos). Consulta la lista de desfases horarios UTC.
«`c
const long gmtOffset_sec = 3600;
«`
- Cambia el desfase de horario de verano (en segundos). Establécelo en 3600 si tu país observa el horario de verano; de lo contrario, ajústalo a 0.
«`c
const int offset_sec de verano = 3600;
«`
Después de cargar el boceto, presiona el botón EN en tu ESP32. El monitor serial debería mostrar la fecha y hora cada segundo.
Explicación del Código
Echemos un vistazo rápido al código para ver cómo funciona. Primero, incluimos las bibliotecas requeridas para este proyecto.
WiFi.h
es una biblioteca que contiene los métodos WiFi específicos de ESP32 que usaremos para conectarnos a una red.time.h
es la biblioteca de tiempo nativa de ESP32 que maneja la sincronización del servidor NTP de forma elegante.
«`c
#include <WiFi.h>
#include «time.h»
«`
A continuación, se definen algunas constantes, como el SSID, la contraseña de WiFi, el desfase UTC y el desfase de horario de verano.
«`c
const char* ssid = «TU_SSID»;
const char* contraseña = «TU_CONTRASEÑA»;
const long gmtOffset_sec = 3600;
const int offset_sec de verano = 3600;
«`
Además, se especifica la dirección del Servidor NTP. pool.ntp.org
es un gran proyecto NTP abierto para este tipo de cosas.
«`c
const char* ntpServer = «pool.ntp.org»;
«`
pool.ntp.org
selecciona automáticamente servidores de tiempo que están físicamente cerca de ti. Sin embargo, si deseas seleccionar un servidor específico, usa una de las subzonas de pool.ntp.org
.
- Área
- Nombre de Host
- Mundial
- pool.ntp.org
- Asia
- asia.pool.ntp.org
- Europa
- europe.pool.ntp.org
- América del Norte
- north-america.pool.ntp.org
- Oceanía
- oceania.pool.ntp.org
- América del Sur
- south-america.pool.ntp.org
En la sección de configuración, primero establecemos comunicación serial con la PC y luego nos conectamos a la red WiFi llamando a la función WiFi.begin().
«`c
Serial.begin(115200);
//conectar a WiFi
Serial.printf(«Conectando a %s «, ssid);
WiFi.begin(ssid, contraseña);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(«.»);
}
Serial.println(» CONECTADO»);
«`
Una vez que el ESP32 está conectado a la red, utilizamos la función configTime() para inicializar el cliente NTP y obtener la fecha y hora del servidor NTP.
«`c
//inicializar y obtener la hora
configTime(gmtOffset_sec, offset_sec de verano, ntpServer);
«`
Finalmente, utilizamos la función personalizada printLocalTime() para imprimir la fecha y la hora actual.
La función printLocalTime() llama a la función getLocalTime() internamente. La función getLocalTime() envía un paquete de solicitud a un servidor NTP, analiza el paquete de marca de tiempo recibido y almacena la información de fecha y hora en una estructura de tiempo llamada timeinfo.
«`c
void imprimirHoraLocal()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println(«Error al obtener la hora»);
return;
}
Serial.println(&timeinfo, «%A, %d de %B del %Y %H:%M:%S»);
}
«`
En la siguiente tabla, puedes ver cómo cada miembro de esta estructura de tiempo se relaciona con cierta información.
- %A – devuelve el día de la semana
- %B – devuelve el mes del año
- %d – devuelve el día del mes
- %Y – devuelve el año
- %H – devuelve la hora
- %M – devuelve los minutos
- %S – devuelve los segundos
¡Qué interesante! Me encantaría aprender más sobre cómo obtener la fecha y hora del servidor NTP utilizando ESP32. ¡Gracias por compartir este artículo!