bclose

El servicio NTP

Sincronizando los relojes del M5STack / ESP32

El servicio NTP en Internet

 

 

    • Hablaremos del NTP.
    • Veremos como cceder a sincronizar la hora con NTP.
    • Lo usareos en nuestro reloj interno.

 

 

Material requerido.

MOdelo basicoUn M5Stack

 

 Detalle de conectoresUn cable USB C

 

M5STACK y NTP

 

Cada vez que alguien me desenchufa el reloj de mi mesilla y me pierde la hora yo pierdo los nervios. Si, vale, es un reloj chino barato de esos que marcan los dígitos con un display LED de poco pelo y entiendo que por lo que cuesta, no podemos pedir virguerías, pero ¿En serio es tan complicado hacer un reloj WIFI, que se ponga en hora automáticamente cada vez que arranca usando NTP? ¿Por qué los relojes, aún los digitales siguen en la tecnología del siglo XIX?

Además dos veces al año, la dichosa comisión europea nos hace cambiar la hora por razones bastante absurdas, que nadie comprende y que resulta muy dudoso que sirva para nada que no sea garantizar la vida de los varios cientos de funcionarios que viven del cuento este.

Dicho de otro modo ¿Podemos usar el M5Stack que trae WIFI de serie para hacer un reloj que se ponga en hora solo cada vez que arranca?  Y ya que estamos, que compruebe la hora periódicamente para que cuando llega el momento de cambiar la hora lo haga solo como los Pcs o los teléfonos móviles.

Si alguien ha pensado que no, que se ponga de cara a la pared un par de minutos como castigo por memo. ¡Claro que se puede! y dado que en el M5stack tenemos pantalla + Wifi + Batería tiene que estar chupado. Y de eso va esta sesión, veamos cómo hacer ese dichoso reloj desatendido.

 

 

El servicio NTP en Internet

 

Ya hemos hablado antes del servicio NTP (Network Time Protocol) al que podemos acceder desde Internet. Básicamente es un sistema que sincroniza la hora interna de nuestro sistema con un reloj maestro de referencia a través de internet.

A la gente que hemos nacido en los últimos años, la idea de un tiempo universal es inherente a nuestra concepción del mundo y por eso mis amigos (Los pocos que me aguantan)  se suelen sorprender cuando les digo que ese tiempo universal es un invento del siglo 19. Piénsalo. Antes de que los ingleses inventaran el tren no había necesidad de que dos ciudades más o menos distantes tuvieran la misma. ¿Quién iba a comprobarlo, cuando los viajes se hacían en carruaje y el transporte de máxima velocidad eran los caballos?

Cuando un señorito (Los pobres no viajaban y punto) iba en carruaje de caballos a otra ciudad, al llegar, simplemente ponía en hora su reloj con el de la torre del ayuntamiento y listo. Que este estuviera sincronizado con el de su pueblo era una idea bastante absurda ¿Para qué? ¿Qué sentido tendría?

Pero al inventar los ferrocarriles, un tren podría cruzar el país por la noche y varios husos horarios, y era imprescindible saber a qué hora iba a salir o a llegar, porque había gente y mercancías esperando y a partir de esto, sincronizar los relojes, entre ciudades distantes, se convirtió en una necesidad, al menos entre las ciudades a las que llegaba el tren.

Como fueron los ingleses los primeros en tener esta necesidad, Crearon una hora propia y un lugar arbitrario a partir del cual se medía la distancia en horas, el meridiano 0 de Greenwich (Un pueblo Inglés) y un tiempo medido en este punto o GMT (Greenwich Mean Time)

Y a partir de este tema también surge la diferencia horaria entre distintos puntos del país o continente, ya hay una diferencia horaria que se basa en el tiempo en que la tierra tarda en girar desde el punto 0, Greenwich, hasta el meridiano que pasa por otra ciudad o punto dado. A este tiempo se le llama diferencia horaria y por eso cuando saltas en avión de un país a otro, te puedes encontrar con una diferencia de varias horas, lo que descoloca bastante hasta que te aclimatas.

 
  • Algunas personas se sorprenden de que se mida la distancia entre puntos distantes en horas. Pero tienes que tener en cuenta que el mundo hace una revolución completa cada 24 horas, lo que permite medir la distancia por el tiempo que la tierra cambia en girar de un punto a otro.
  • Este tiempo es precisamente el desfase horario entre los dos puntos, que debemos corregir ajustando los relojes  si vamos de uno a otro (Y suponiendo que no hay funcionarios de por medio decidiendo jugar con los relojes públicos)  

Por eso en la era de los aviones, necesitábamos un tiempo mundial, ya que si antes poner en hora relojes de las estaciones de tren era un lío, Hoy poner en hora los relojes de los aeropuertos de todo el mundo era una pesadilla (Si es que hay gente que no deja de inventar tonterías) y por eso era necesario el concepto de tiempo universal común o coordinado a nivel planetario y a esa hora mundial se le llama UTC (Coordinated Universal Time )

El UTC es el tiempo universal común (Que se cuenta desde Greenwich) y cada punto del globo calcula su propia hora local como una desviación respecto al UTC. España por ejemplo (Donde estoy escribiendo esto) va una hora adelantado al UTC.

¿Y qué servidores tenemos disponibles por ahí para sincronizar la hora?  Bueno, aunque te parezca increíble no eres el único buscando la hora en internet. Por ello, el servicio NTP está organizado jerárquicamente para poder dar respuesta a una demanda global, de forma que en el primer estrato tenemos relojes atómicos muy precisos, que pasan la hora a los del segundo nivel y estos a su vez a los verdaderos servidores NTP que son los que nos hacen caso a los pringaos como tú y yo de clase turista.

Jerarquia de servidores NTP

Bien, una vez que os he metido el rollo teórico de la hora, podemos ya pasar a ver cómo podemos usar el Servicio NTP de internet, que nos proporciona acceso a un reloj UTC, y al que después podemos sumar o restar nuestro desfase horario para obtener nuestro tiempo local.

 

Acceder al NTP con M5Stack

 

Veamos como programar acceso al servicio NTP desde nuestro M5stack. Necesitamos descargar la   librería NTPClient-master.zip desde  en instalarla según el procedimiento habitual, y empezamos declarando los includes necesarios:

#include <M5Stack.h>
#include <NTPClient.h>
#include <WiFi.h>
#include <WiFiUdp.h>

const char *ssid     = "XXXXXX";
const char *password = "YYYYYYY";

Necesitamos incluir las Librería NTPClient.h y WIFIUdp.h porque la comunicación con NTP se realiza a través de UDP y no de TCP/IP. Asegúrate de poner el nombre tu Wifi y contraseña para poder conectar. Como desde España hay una hora de diferencia respecto UTC que son 3600 segundos:

const long utcOffsetInSeconds = 3600;

Ahora ya podemos empezar con el programa:

WiFiUDP ntpUDP;     // Define NTP Client to get time
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

La primera línea crea una instancia de cliente UDP con WIFI y con la segunda creamos un cliente del servicio NTP a partir de la instancia UDP anterior, un pool de servidores NTP:  “pool.ntp.org” y una diferencia horaria en segundos.

¿Qué es esa película del pool de servidores NTP? Del mismo modo que tu PC encuentra la dirección de cualquier servidor en Internet, como Google.com o mucho más importante Prometec.net mediante un servicio DNS global, en cualquier servicio publico, como el NTP,  es que hay diferentes niveles de atención a los demandantes y para nosotros (La clase turista) es buena idea entrar por un servidor NTP genérico “pool.ntp.org” que nos asignara otro servidor NTP disponible de modo transparente  a toda velocidad (Y además gratis así que no protestes)

 
  • Es un poco como llamar a una servicio de atención telefónica. EL sistema te pasa con el primer operador disponible.
  • Hay jerarquías de servidores a nivel global, continental, Estatal y hasta de universidades y sitios así, pero no vale la pena complicarnos mas. 
void setup()
{  WiFi.begin(ssid, password);
   while ( WiFi.status() != WL_CONNECTED )
        {  delay ( 500 );
        }

    timeClient.begin();
    M5.begin();
}

Iniciamos el WIFI con el nombre de tu red y password y esperamos hasta que el status del WIFI sea conectado y al conectar iniciamos timeCLient, la instancia del cliente NTP y claro esta iniciamos las librerías del M5.

Voy a crear una función printClock() que dibuje en la pantalla LCD del M5 la hora. Para ello podríamos hacer algo como esto:

Void printClock()
{    int H = timeClient.getHours();
     int M = timeClient.getMinutes();
     int S = timeClient.getSeconds();

     M5.Lcd.fillScreen(BLACK);   // Borra la pantalla
     M5.Lcd.setCursor(20, 110);
     M5.Lcd.setTextColor(RED);
     M5.Lcd.setTextSize(6);

     M5.Lcd.printf("%02d:%02d:%02d", H, M, S );
}

Podemos acceder a timeClient para sacar las horas minutos y segundos  e imprimirlos con un printf con formato de 2 dígitos, pero como sé que los amigos de Arduino suelen alucinar con estas instrucciones y además es una lata escribir tanto, sería más fácil usar otra función disponible que nos devuelve la hora ya formateada:

Void printClock()
{   M5.Lcd.fillScreen(BLACK);   // Limpia la pantalla
    M5.Lcd.setCursor(20, 110);
    M5.Lcd.setTextColor(RED);
    M5.Lcd.setTextSize(6);

    M5.Lcd.print(timeClient.getFormattedTime());
}

¿Que porque no he empezado por aquí? Pues básicamente  porque getFormattedTime() devuelve un string con el formato de lo más mono pero puede pasar que queráis sacar las horas y minutos pero no los segundos (Al final es un reloj)y os conviene saber cómo hacerlo. Y ya solo faltaría llamar a la función desde el loop:

void loop()
{   timeClient.update();
    printClock();
    delay(999;
}

Si cargas el programita veréis como ya tienes el reloj en hora.

 

Refinando el programa

 

El programa anterior es válido pero tiene el inconveniente que llama al servidor NTP cada segundo y si todo el mundo hiciese eso podría causar problemas.

En realidad nuestro ESP32 dispone de un reloj interno que funciona bastante potablemente y lo único que necesitamos es ponerlo en hora con NTP y después se apaña él solo. Simplemente basta con volver de tarde en tarde a sincronizar de nuevo el reloj interno para asegurarnos que sigue preciso mediante NTP, especialmente en esos días en que la hora cambia.

Por tanto podemos modificarlo un poco para que llame, cada hora por ejemplo al saltar los minutos a cero. Bastaría con cambiar un poco el loop tal que  así:

Contenido solo disponible para suscriptores. ¡Accede al contenido!

           

Aquí os dejo una foto con el resultado:

Imagen del reloj digital con M5stack