Ignorer et passer au contenu

Livraison offerte à partir de 50€

Contents Menu Expand Light mode Dark mode Auto light/dark mode

Récupérer la date et l’heure exacte avec un ESP32 depuis un serveur NTP avec du code Arduino

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 😉.

Serveur NTP : A quoi ça sert ?

À 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…

Si vous voulez en apprendre davantage sur le fonctionnement du protocole NTP et de son architecture, je vous conseille cette excellente vidéo en anglais de Computerphile .

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.

Quelle est la différence entre timestamp, temps epoch et Unix ?

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.

Prendre en compte le décalage horaire (UTC, GMT)

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é.

Récupérer la date depuis un Internet (Serveur NTP) avec un ESP32

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 :

date récupérée depuis un serveur ntp

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);

Fonctionnement avancé

Changer automatiquement l’horaire été/hiver avec un timezone

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:

liste timezone

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.

Cette section est réservée aux abonnés. Il vous reste 86% à découvrir.

Devenir membre premium

Déjà abonné ? Connectez-vous

Nous utilisons des cookies pour que votre visite sur la boutique soit la plus agréable possible. Politique de confidentialité