Avec une simple connexion internet, il est possible de calibrer l’horloge interne de l’ESP32 et ainsi avoir l’heure à jour. Plus besoin d’avoir une horloge RTC externe avec une pile pour conserver l’heure à jour, si l’on peut simplement la récupérer depuis Internet. C’est très pratique lorsque l’ESP32 se réveille de temps en temps pour communiquer avec des services WEB, et qu’il veut dater ses paquets avec la bonne date.
Note
Une horloge RTC externe reste cependant intéressante si l’ESP32 n’a pas directement accès à un Internet. On peut aussi utiliser un serveur NTP pour calibrer l’horloge RTC et corriger son décalage avec le temps 😉.
À la base, un serveur NTP (Network Time Protocol) est un serveur qui permet de synchroniser les horloges de différents ordinateurs sur un réseau informatique. Leur but est de s’assurer que tous les ordinateurs sur le réseau ont la même heure, ce qui est important pour de nombreuses applications, comme la gestion de fichiers ou la sécurité informatique. Cela permet également d’éviter les erreurs causées par des horloges qui ne sont pas synchronisées. Le protocole n’est pas si trivial que cela car pour obtenir une horloge précise à la milliseconde près, il faut prendre en compte le temps qui s’écoule pendant l’envoi des requêtes, le temps de traitement par le serveur…
Note
Dans notre cas, on l’utilisera pour synchroniser l’horloge interne de l’ESP32.
Il existe de nombreuses adresses de serveurs NTP que l’on peut utiliser pour synchroniser la date. Le plus connu est "pool.ntp.org"
mais il en existe bien d’autres.
Un timestamp (horodatage en français) est une marque temporelle qui indique la date et l’heure précise d’un événement. Il s’agit d’une série de chiffres qui représentent la date et l’heure de l’événement.
L’epoch time, ou temps Unix, est une référence temporelle communément utilisée dans les systèmes informatiques. Il représente le nombre de secondes écoulées depuis le 1er janvier 1970 à minuit UTC . Cette date de référence est souvent utilisée comme point de départ pour calculer la date et l’heure d’un événement en utilisant un timestamp. Par exemple, si un timestamp est égal à 1601054743, cela signifie qu’il s’agit du nombre de secondes écoulées depuis le 1er janvier 1970 jusqu’à l’événement en question (Soit le Mardi 13 Decembre 2022 à 10h12m25s). Son utilisation permet de faciliter les calculs liés à la date et à l’heure dans les systèmes informatiques.
Pour avoir la bonne heure, il faut prendre en compte le décalage horaire local. Pour ce faire, on utilise comme référence l’heure UTC ou GMT qui correspond au décalage horaire +0. On ajuste ensuite cette valeur en fonction du fuseau horaire local et éventuellement d’un horaire été/hiver additionnel. Pour la France, c’est +1
en hiver et +2
en été.
Avec du code Arduino, cela se fait très simplement, car il y a déjà des fonctions de bases qui s’en chargent. Aucune librairie additionnelle n’est requise, tout est intégré de base dans time.h
.
Voici un script de base qu’il faut a minima compléter avec les identifiants de votre box Wi-Fi 🙂:
#include <WiFi.h>
#include "time.h"
const char* ssid = "upesy-ap"; // Nom de la box Wi-Fi
const char* password = "cupcakes"; // MDP de la box Wi-Fi
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600 * 1;
const int daylightOffset_sec = 3600 * 0;
void setup() {
Serial.begin(115200);
delay(1000);
WiFi.mode(WIFI_STA); // Optional
WiFi.begin(ssid, password);
Serial.println("\nConnecting");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(100);
}
Serial.println("\nConnected to the WiFi network");
Serial.print("Local ESP32 IP: ");
Serial.println(WiFi.localIP());
// On configure le seveur NTP
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
}
void loop() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
delay(1000);
}
On peut le découper en 3 parties :
La configuration et la connexion du Wi-Fi
La configuration du serveur NTP
La récupération de la date toutes les secondes auprès du serveur NTP
Note
Si vous êtes en été, il faudra mettre un daylightOffset_sec = 3600;
pour avoir l’heure d’été.
Dans le moniteur série, on obtient bien la bonne date :
Ce qui est le plus compliqué dans le code, c’est le formatage de la date en texte à partir de la structure timeinfo
(un timestamp). Voici un lien vers la documentation C++ pour connaître les bons paramètres en fonction du format final voulu.
On peut afficher uniquement la donnée voulue, par exemple les minutes :
Serial.println(&timeinfo, "%M");
Pour récupérer cette valeur dans une variable, on peut utiliser le code suivant :
char timeMinutes[3];
strftime(timeMinutes,3, "%H", &timeinfo);
Serial.println(timeMinutes);
Ou récupérer les minutes directement depuis la structure C++
(Les membres de la structure sont listés dans la documentation ):
int minutes = timeinfo.tm_min;
Serial.println(minutes);
Avec les années, des zones ont été établies qui précisent en détail toutes les spécificités horaires locales. Vous avez sûrement dû en rencontrer lors de la configuration d’un appareil électronique, avec une énorme liste de zones possibles:
La liste que l’on va utiliser est disponible sur GitHub : https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv . Ce qui nous intéresse, ce sont les informations à droite. Pour Europe/Paris
c’est CET-1CEST,M3.5.0,M10.5.0/3
. En utilisant cette timezone
, la date sera automatiquement mise à jour lors du changement d’heure été|hiver.