Sistema NTP per orologio interno ESP32

Introduzione

Molto spesso nei nostri sistemi abbiamo necessità di tenere traccia del tempo, per esempio  la temporizzazione di una uscita, oppure  tracciare  l’istante di un evento o semplicemente avere anche un orologio che segnali il tempo sul sistema. In tutte queste situazioni  possiamo adottare soluzioni diverse:

Timer RTC: Usa la sorgente di clock RTC con una risoluzione 6.6667 us,  il clock può rimanere attivo anche quando il sistema  è posto nello stato di   “Sleep”, per ridurre il consumo di energia. Ovviamente,  con l’utilizzo del  timer RTC, nel caso in cui dovesse mancare l’alimentazione il riferimento sarà perduto e il contatore inizia di nuovo il  conteggio da capo.

High-resolution timer: Questotimer ha un’alta risoluzione perché usa il clock del sistema, tipicamente 80 MHz. A differenza del timer RTC, in questo caso il conteggio  non sara’ attivo quando il sistema  si trova nello stato di “sleep”.

Network Time Protocol (NTP): E’ uno standard del protocollo IP per sincronizzare l’orologio di un sistema da un computer di riferimento,  in rete ad un determinato indirizzo è connesso un computer con un dispositivo  di misurazione del tempo estremamente preciso,  se un sistema ha necessità di sincronizzare il proprio orologio può connettersi a questo computer.  

Figura 1

Come connettere ESP32 ad un sistema NTP

In questo articolo realizzeremo un progetto per connettere il microcontrollore ESP32 ad un sistema NTP, per aggiornare il clock interno, ovviamente, affinché questo sistema possa funzionare è necessario avere una connessione ad Internet.

Per connettere il  microcontrollore ESP32 ad un server NTP, bisogna eseguire i seguenti passi:

  • Il client (ESP32)  si connette al server con il protocollo UDP (User Datagram Protocol)
  • Il client invia una richiesta di pacchetto al server NTP
  • Il server NTP risponde  e invia  il pacchetto “time stamp”.
  • Il pacchetto “time stamp” contiene l’informazione sull’ora corrente , e il time zone.
  • Il cliente  può elaborare le informazioni.

Codice

#include <WiFi.h>
#include "time.h"

const char* ssid       = "ID wifi";
const char* password   = "Password";

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;

void stampa_ora_locale()
{
  struct tm ora_locale;
  if(!getLocalTime(&ora_locale)){
    Serial.println("non riesco a connettermi al server");
    return;
  }
  Serial.println(&ora_locale, "%A, %B %d %Y %H:%M:%S");
}

void setup()
{
  Serial.begin(115200);
  
  //connect to WiFi
  Serial.printf("mi sto connettendo a %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println(" CONNESSO");
  
  //init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  stampa_ora_locale();

 
}

void loop()
{
  delay(1000);
  stampa_ora_locale();
}

Includiamo le librerie per la connessione al Wi-Fi e per la lettura dell’ora locale e della data.

tra le virgolette devono essere inserite le credenziali del Wi-Fi

indichiamo l’indirizzo del server dove caricare l’ora locale e l’area di riferimento, che nel nostro caso e’ Italia, come indicato dalla pagina di wikipedia UTC ( Coordinated Universal Time).

Dichiariamo la funzione per connettersi al sever e che poi verra’ chiamata nel loop della funzione.

All’avvio il microcontrollore ESP32 si connette al rete WI-FI.

Configuriamo l’ora locale che deve essere richiesta la server per poi chiamare al funzione che stampa l’ora locale sulla terminale della seriale

Nel loop si chiama la funzione di stampa dell’ora ogni secondo.

4 commenti

  1. Grazie per l articolo, ti chiedo però: come posso inserire giorno, mese, anno in delle variabili INT? In sostanza se volessi costruire una sveglia o un timer ad esempio, dovrei usare degli IF… e gg-mm-aaa, hh-mm in variabili INT da confrontare. Come le estrapolo? Grazie

    • Ciao e benvenuto sul mio sito. Se vuoi convertire l’ora in un intero puoi procedere nel seguente modo:
      strftime(timeHour,3, “%H”, &ora_locale); Con questa trasformi l’ora in un char
      int i=atoi(timeHour); con questa funzione trasformi il char in un int.
      In questo esempio ho eseguito la conversione con l’ora, lo stesso ragionamento lo puoi fare con i minuti.
      Mi hai dato una buona idea, magari in un prossimo progetto realizzero’ una sveglia.
      Spero di averti risposto chiaramente alla tua domanda, altrimenti non esitare a scrivere di nuovo.
      Buon divertimento.
      Gennaro.

      • Scusa il ritardo ma non mi ero accorto della risposta, ancora non ho testato lo sketch per mancanza di tempo. Un’altra domanda: se non ho capito male, questo script prende l ora ntp all inizio e poi avanza ore e minuti in seguito da solo senza più interrogare il server ntp, o sbaglio? A me serve che mantenga l ora anche in caso di assenza di internet dopo l accensione del dispositivo, quindi qualcosa che interroghi ntp all inizio e poi possa lavorare anche offline.. Grazie ancora, gentilissimo.

        • Ciao, se osservi nella parte di codice che si ripete a loop, chiama la funzione “stampa_ora_locale();” ogni secondo, quindi il software come e’ stato scritto si connette continuamente al server per leggere l’ora. Ovviamente questo e’ un codice d’esempio, nessuno ti vieta di modificarlo in funzione delle tue esigenze. Potresti eliminare dal loop la chiamata alla funzione, indicata sopra, e potresti gestire la misura del tempo con il timer interno del microcontrollore, in questo caso la scheda ESP32 si connettera’ al server solo all’accensione. Comunque, per avere la certezza che l’orologio misuri sempre il tempo con la massima precisione, farei connettere almeno ogni ora l’ESP32 al server per aggiornare l’orologio.
          Spero di essere stato chiaro, altrimenti non esitare a scrivermi.
          Buon lavoro,
          Gennaro.

Lascia una risposta

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Ti sei iscritto alla newsletter

There was an error while trying to send your request. Please try again.

Quattrodispositivi utilizzerà le informazioni fornite in questo modulo per restare in contatto con te e fornire aggiornamenti del sito