Récupérer l'heure sur un serveur de temps NTP, code Arduino ESP8266, librairie NTPClient

mini-tuto

#1

La librairie NTPClient développée par Fabrice Weinberg permet très facilement de récupérer l’heure depuis un serveur de temps NTP. Elle utilise une connexion WiFi UDP pour se connecter à un serveur NTP. Par défaut, la librairie synchronise l’heure toutes les 60 secondes secondes.
Il est possible d’indiquer manuellement le serveur NTP, le décalage horaire et l’intervalle de synchronisation.

NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);

Exemple de code Arduino

Ce programme permet de récupérer le temps toutes les 10 secondes. L’heure au format HH:MM:SS est affichée sur le moniteur série

#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>

#define NB_TRYWIFI        10    // Nbr de tentatives de connexion au réseau WiFi - Number of try to connect to WiFi network

const char* ssid = "xxxx";
const char* password = "xxxx";

WiFiClient espClient;
WiFiUDP ntpUDP;

NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);

void setup() {
  Serial.begin(115200);
  Serial.println("");
  Serial.print("Startup reason:");Serial.println(ESP.getResetReason());

  WiFi.begin(ssid, password);

  Serial.println("Connecting to WiFi.");
  int _try = 0;
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print("..");
    delay(500);
    _try++;
    if ( _try >= NB_TRYWIFI ) {
        Serial.println("Impossible to connect WiFi network, go to deep sleep");
        ESP.deepSleep(10e6);
    }
  }
  Serial.println("Connected to the WiFi network");
  
  // Démarrage du client NTP - Start NTP client
  timeClient.begin();
}

void loop() {
    // Met à jour l'heure toutes les 10 secondes - update time every 10 secondes
    timeClient.update();
    Serial.println(timeClient.getFormattedTime());
}

Stocker le temps dans la zone SPIFFS et estimer le temps écoulé depuis le dernier redémarrage ou Reset

L’ESP8266 ne dispose pas d’horloge RTC. Il est très simple de stocker régulièrement le temps NTP dans un simple fichier texte dans la zone mémoire SPIFFS. On pourra en calculer le temps écoulé depuis le dernier démarrage avec une simple soustraction. Le temps écoulé est en secondes.

La code suivant ajoute plusieurs fonctions

  • saveLastEvent(), enregistre dans un fichier nommé lastEvent.txt l’heure NTP au format EPOCH Unix
  • loadLastEvent(), recharge le dernier temps NTP sauvegardé
  • timeSpent(), calcul le temps écoulé en secondes depuis le dernier démarrage
  • runEvent(), exécute un événement si le temps écoulé est supérieur au temps spécifié dans la variable DELAY_NEXT_EVENT

Vous pouvez également tester en activant le mode Deep-Sleep (passer la clé DEEP_SLEEP à true) du module ESP8266.

#include <ESP8266WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include "FS.h"

#define NB_TRYWIFI        10    // Nbr de tentatives de connexion au réseau WiFi - Number of try to connect to WiFi network
#define DELAY_NEXT_EVENT  60    // délai entre deux événements en secondes - delay before new event in second 
#define DEEP_SLEEP        false
const char* ssid = "xxxx";
const char* password = "xxxx";

WiFiClient espClient;
WiFiUDP ntpUDP;

NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);

int lastEvent;
int start = millis();
long int _now = 0;

bool loadLastEvent(){
  File f = SPIFFS.open("/lastEvent.txt", "r");
  if (!f) {
    Serial.println("Failed to open file");
    return false;
  }
  lastEvent = f.readStringUntil('\n').toInt();
  return true;
}

bool saveLastEvent(){
  File f = SPIFFS.open("/lastEvent.txt", "w");
  if (!f) {
      Serial.println("file open failed");
      return false;
  }
  f.println(_now);
  f.close();
  return true;
}

long int timeSpent(){
  loadLastEvent();
  timeClient.forceUpdate();
  _now = timeClient.getEpochTime();
  int timeSpent = _now - lastEvent;
  Serial.println("Time spent since last alarm (s): ");Serial.print(timeSpent);
  return timeSpent;
}
void runEvent(){
    
  if ( timeSpent() >= DELAY_NEXT_EVENT ) {
    Serial.println("RUN EVENT");
    saveLastEvent();
  } 
}

void setup() {
  Serial.begin(115200);
  Serial.println("");
  Serial.print("Startup reason:");Serial.println(ESP.getResetReason());

  SPIFFS.begin();

  WiFi.begin(ssid, password);

  Serial.println("Connecting to WiFi.");
  int _try = 0;
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print("..");
    delay(500);
    _try++;
    if ( _try >= NB_TRYWIFI ) {
        Serial.println("Impossible to connect WiFi network, go to deep sleep");
        ESP.deepSleep(10e6);
    }
  }
  Serial.println("Connected to the WiFi network");
  
  // Démarrage du client NTP - Start NTP client
  timeClient.begin();
   
  
  if ( DEEP_SLEEP){ 
    runEvent();
    Serial.println("Go to deep sleep");
    ESP.deepSleep(10e6);
  }  
}

void loop() {
  if ( !DEEP_SLEEP ){
    timeClient.update();
    Serial.println(timeClient.getFormattedTime());
    delay(10000); 
  }
}