Découvrez comment utiliser le module d’horloge en temps réel DS1307 avec l’ESP8266. Nous verrons comment régler et lire l’heure. Vous apprendrez à synchroniser l’heure avec l’heure locale de l’ESP8266 et avec un serveur NTP périodiquement. Nous verrons également comment gérer les fuseaux horaires et l’heure d’été. Enfin, nous construirons une horloge numérique ESP8266 en utilisant le module RTC DS1307 et un écran OLED.

Remarque : ce tutoriel est également compatible avec le DS3231 RTC en modifiant simplement une ligne de code dans les exemples.
Table des matières
Dans ce didacticiel, nous aborderons les sujets suivants :
Présentation des modules d’horloge en temps réel (RTC)
Les modules RTC, tels que le DS3231 et le DS1307, possèdent leur propre petite horloge à l’intérieur pour suivre l’heure par eux-mêmes. Habituellement, ils sont livrés avec un support de batterie pour connecter une batterie afin qu’ils continuent de fonctionner même si l’ESP8266 se réinitialise ou perd de l’énergie.
Le DS3231 et le DS1307 font partie des choix les plus populaires à utiliser avec les microcontrôleurs. Les deux sont compatibles avec l’ESP8266 et communiquent via le protocole de communication I2C. Le DS3231 est plus précis car il est livré avec un capteur de température et donne des résultats compensés en température. Néanmoins, le DS1307 est également très précis et adapté à la plupart des applications nécessitant de suivre le temps. Dans ce didacticiel, nous aborderons le module RTC DS1307.
Présentation du module RTC DS1307
Dans ce didacticiel, nous utiliserons le module RTC DS1307, mais si vous possédez un DS3231, la plupart des informations fournies s’appliquent aux deux modules. De plus, tout le code doit être compatible avec les deux modules avec juste un petit changement. (Dans un futur proche, nous créerons un tutoriel pour le module RTC DS3231).

Le module RTC DS1307 est livré avec la puce DS1307 (pour suivre le temps) et l’EEPROM AT24C32 (pour sauvegarder les données en permanence). Il peut également être programmé pour produire des ondes carrées avec différentes fréquences. Nous n’utiliserons que les fonctionnalités de la puce DS1307 pour le chronométrage.
Support de batterie DS1307
Il est livré avec un support de pile pour connecter une pile CR2032 afin de conserver une heure précise. En cas de panne de courant, il peut toujours suivre l’heure avec précision.


Ce module est également livré avec la possibilité de connecter une température DS18B20. Après avoir connecté ce capteur au module, vous pouvez obtenir la température de la broche DS du module.
Adresse I2C du module RTC DS1307
Par défaut, l’adresse du DS1307 RTC est 0x68 et l’EEPROM connectée au module est 0x50. Vous pouvez exécuter un croquis du scanner I2C pour revérifier les adresses.

Brochage du module RTC DS1307
Le tableau suivant décrit rapidement le brochage du module RTC DS1307.
| SQ | Sortie pour ondes carrées : 1 Hz, 4,096 kHz, 8,192 kHz ou 32,768 kHz (nous n’utiliserons pas) |
| DS | Sortie pour les relevés de température si DS18B20 est connecté (nous n’utiliserons pas) |
| SCL | Broche SCL pour I2C |
| SDA | Broche SDA pour I2C |
| VCC | Fournit l’alimentation au module (3,3 V ou 5 V) |
| GND | GND |
| BATTE | Entrée d’alimentation de secours (nous n’utiliserons pas) ou utilisez le support de batterie par défaut |
Voici une liste des pièces requises pour ce tutoriel :
Nous n’utiliserons que les broches I2C et d’alimentation pour interfacer le module RTC avec l’ESP8266. Nous allons connecter SCL à GPIO 5 (D1) ; et SDA vers GPIO 4 (D2). Vous pouvez utiliser n’importe quelle autre broche I2C appropriée, à condition de la modifier dans le code. Vous pouvez utiliser le tableau suivant comme référence ou jeter un œil au diagramme schématique.
| Module RTC | ESP8266 |
| SCL | GPIO5 (D1) |
| SDA | GPIO4 (D2) |
| VCC | 3V3 |
| GND | GND |

Travailler avec le RTC
Utiliser un module RTC dans vos projets nécessite toujours deux étapes importantes.
- Réglage de l’heure actuelle : vous pouvez le faire manuellement en insérant l’heure actuelle (ou une autre heure souhaitée) sur le code ; l’heure locale du système ; ou obtenez l’heure à partir d’un serveur NTP.
- Conservation de l’heure : pour s’assurer que le RTC conserve l’heure correcte, même en cas de panne de courant, il doit être connecté à une batterie. Les modules RTC sont livrés avec un support de batterie, généralement pour une pile bouton.
Installation de la bibliothèque RTClib
Il existe plusieurs bibliothèques pour s’interfacer avec le DS1307 RTC. Nous utiliserons le RTClib d’Adafruit compatible avec les modules RTC DS1307, DS3231 et PCF8523. De plus, cette bibliothèque est également compatible avec les cartes ESP8266.
Dans l’IDE Arduino, accédez à Sketch > Inclure la bibliothèque > Gérer les bibliothèques. Recherchez RTClib et installez la bibliothèque d’Adafruit. Nous utilisons la version 2.1.4.

Réglage et lecture de l’heure

L’exemple suivant définit l’heure sur l’horloge RTC, puis lit l’heure dans la boucle toutes les trois secondes. Ce code montre deux manières différentes de régler l’heure : synchroniser le RTC avec l’heure du système (date et heure de compilation du croquis) et définir manuellement une date et une heure spécifiques en les écrivant vous-même sur le code.
/*
Rui Santos & Sara Santos - Raspberryme.com
Complete project details at https://Raspberryme.com/esp8266-nodemcu-ds1307-real-time-clock-rtc-arduino/
Based on the RTClib Library examples: github.com/adafruit/RTClib/blob/master/examples
*/
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include "RTClib.h"
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
void setup () {
Serial.begin(115200);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running, let's set the time!");
// When time needs to be set on a new device, or after a power loss, the
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
//rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
// When time needs to be re-set on a previously configured device, the
// following line sets the RTC to the date & time this sketch was compiled
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
//rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
void loop () {
// Get the current time from the RTC
DateTime now = rtc.now();
// Getting each time field in individual variables
// And adding a leading zero when needed;
String yearStr = String(now.year(), DEC);
String monthStr = (now.month() < 10 ? "0" : "") + String(now.month(), DEC);
String dayStr = (now.day() < 10 ? "0" : "") + String(now.day(), DEC);
String hourStr = (now.hour() < 10 ? "0" : "") + String(now.hour(), DEC);
String minuteStr = (now.minute() < 10 ? "0" : "") + String(now.minute(), DEC);
String secondStr = (now.second() < 10 ? "0" : "") + String(now.second(), DEC);
String dayOfWeek = daysOfTheWeek[now.dayOfTheWeek()];
// Complete time string
String formattedTime = dayOfWeek + ", " + yearStr + "-" + monthStr + "-" + dayStr + " " + hourStr + ":" + minuteStr + ":" + secondStr;
// Print the complete formatted time
Serial.println(formattedTime);
Serial.println();
delay(3000);
}
Afficher le code brut
Comment fonctionne le code
Commencez par importer la bibliothèque RTCLib.
#include "RTClib.h"
Créez ensuite un objet RTC_DS1307 appelé rtc.
RTC_DS1307 rtc;
Si vous utilisez un module RTC DS3231, utilisez plutôt la ligne suivante.
RTC_DS3231 rtc;
Ensuite, vous créez un tableau de caractères avec les jours de la semaine.
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
Vous pouvez accéder à chaque jour par son index. Par exemple:
- joursDeLaSemaine[0] reviendra « dimanche ».
- joursDeLaSemaine[1] reviendra « lundi ».
Dans setup(), initialisez le Serial Monitor.
Serial.begin(115200);
Initialisez le module RTC comme suit :
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
Vérification de l’état RTC
Ensuite, vérifiez si le RTC garde l’heure avec la fonction isrunning(). S’il ne fonctionne pas, parce qu’il s’agit d’un nouveau périphérique ou parce que la batterie de secours a échoué, nous imprimerons un message sur le moniteur série et réglerons l’heure.
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running, let's set the time!");
Régler l’heure
Pour régler l’heure sur RTC, nous pouvons utiliser la méthode ajuster() sur notre objet rtc. La ligne suivante définit la date et l’heure du RTC sur la date et l’heure actuelles de la dernière compilation de ce croquis.
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
__DATE__ et __TIME__ sont des macros qui fournissent la date et l’heure actuelles lors de la compilation.
Vous pouvez également régler la date et l’heure manuellement. Passez les champs horaires dans cet ordre : année, mois, jour, heure, minute, seconde. Cette ligne est commentée sur le code.
// January 21, 2014 at 3am you would call:
rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
Si vous avez besoin de réinitialiser l’heure sur un appareil préalablement configuré, vous pouvez appeler l’une des deux lignes précédentes pour régler l’heure sans vérifier s’il fonctionne ou non (ceci est commenté sur le code).
// When time needs to be re-set on a previously configured device, the
// following line sets the RTC to the date & time this sketch was compiled
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
//rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
Obtenir la date et l’heure
Dans la boucle(), nous obtenons la date et l’heure toutes les trois secondes, et nous les imprimons dans le Serial Monitor.
Nous appelons rtc.now() pour obtenir la date et l’heure actuelles du module RTC.
DateTime now = rtc.now();
Il renvoie un objet DateTime contenant les valeurs de l’année, du mois, du jour, de l’heure, des minutes et des secondes en cours.
Pour accéder à chaque champ de la date et de l’heure, nous pouvons utiliser les méthodes suivantes :
| maintenant.année() | Obtient l’année en cours (par exemple, 2024) |
| maintenant.mois() | Obtient le mois en cours (1-12) |
| maintenant.jour() | Obtient le jour actuel du mois (1–31) |
| maintenant.dayOfTheWeek() | Obtient le jour de la semaine (0-6), où 0 correspond au dimanche et 6 au samedi |
| maintenant.heure() | Obtient l’heure actuelle (0-23) |
| maintenant.minute() | Obtient la minute actuelle (0-59) |
| maintenant.seconde() | Obtient la seconde actuelle (0-59) |
Pour convertir le résultat en chaîne, nous pouvons utiliser la méthode String(). Nous passons également DEC comme deuxième argument à la méthode string() pour obtenir un nombre décimal.
String yearStr = String(now.year(), DEC);
Dans le cas du mois, du jour, de l’heure, des minutes et des secondes, on ajoute un zéro non significatif lorsque le nombre est inférieur à 10. Ainsi, au lieu d’avoir, par exemple : 3:5:6 (ce qui est bizarre pour un format d’heure ), vous obtiendrez 03:05:06.
String monthStr = (now.month() < 10 ? "0" : "") + String(now.month(), DEC);
String dayStr = (now.day() < 10 ? "0" : "") + String(now.day(), DEC);
String hourStr = (now.hour() < 10 ? "0" : "") + String(now.hour(), DEC);
String minuteStr = (now.minute() < 10 ? "0" : "") + String(now.minute(), DEC);
String secondStr = (now.second() < 10 ? "0" : "") + String(now.second(), DEC);
Pour obtenir le nom du jour de la semaine, nous utilisons le tableau joursOfTheWeek que nous avons créé au début du code.
String dayOfWeek = daysOfTheWeek[now.dayOfTheWeek()];
En fin de compte, nous concaténons tous les champs temporels dans une variable et l’affichons dans le Serial Monitor.
// Complete time string
String formattedTime = dayOfWeek + ", " + yearStr + "-" + monthStr + "-" + dayStr + " " + hourStr + ":" + minuteStr + ":" + secondStr;
// Print the complete formatted time
Serial.println(formattedTime);
Tester l’exemple
Avec le RTC connecté à l’ESP8266, téléchargez le code sur votre carte.
Ouvrez le moniteur série à un débit en bauds de 115 200. L’ESP8266 définira l’heure RTC et affichera l’heure actuelle toutes les trois secondes.

Synchronisation du RTC avec un serveur NTP
L’exemple suivant est similaire au précédent, mais il synchronise l’heure RTC avec un serveur NTP après avoir connecté l’ESP8266 à Internet. Cette méthode est utile s’il est nécessaire de réinitialiser ou d’ajuster l’heure sans saisie manuelle, par exemple après avoir changé la pile bouton du RTC, ou si, pour une raison quelconque, le module RTC tombe en panne. Dans cet exemple particulier, nous ajoutons également la possibilité de synchroniser l’heure avec le serveur NTP toutes les heures pour éviter les dérives dans le temps (la synchronisation périodique doit être ajustée en fonction des exigences de votre projet).
/*
Rui Santos & Sara Santos - Raspberryme.com
Complete project details at https://Raspberryme.com/esp8266-nodemcu-ds1307-real-time-clock-rtc-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include
#include
#include
// Enter your Wi-Fi credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// NTP server details
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 0; // Offset for GMT in seconds
const int daylightOffset_sec = 3600; // Daylight savings time in seconds
// RTC object (for DS1307 or DS3231)
RTC_DS1307 rtc; // Change to RTC_DS1307 for DS1307 module
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
// Global timeinfo struct and last sync timestamp
struct tm timeinfo;
unsigned long lastSyncMillis = 0; // Last sync time in milliseconds
void setup() {
Serial.begin(115200);
initWiFi();
// Initialize RTC
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
// Sync the RTC at startup
syncTime();
}
void loop() {
checkTimeAndSync(); // Check if 1 hour has passed and sync if necessary
// Get current time from RTC
DateTime now = rtc.now();
// Getting each time field in individual variables
String yearStr = String(now.year(), DEC);
String monthStr = (now.month() < 10 ? "0" : "") + String(now.month(), DEC);
String dayStr = (now.day() < 10 ? "0" : "") + String(now.day(), DEC);
String hourStr = (now.hour() < 10 ? "0" : "") + String(now.hour(), DEC);
String minuteStr = (now.minute() < 10 ? "0" : "") + String(now.minute(), DEC);
String secondStr = (now.second() < 10 ? "0" : "") + String(now.second(), DEC);
String dayOfWeek = daysOfTheWeek[now.dayOfTheWeek()];
// Complete time string
String formattedTime = dayOfWeek + ", " + yearStr + "-" + monthStr + "-" + dayStr + " " + hourStr + ":" + minuteStr + ":" + secondStr;
// Print the complete formatted time
Serial.println(formattedTime);
Serial.println();
delay(10000);
}
void initWiFi() {
WiFi.begin(ssid, password); // Connect to WiFi
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected.");
}
void syncTime() {
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); // Configure time with NTP server
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
Serial.println("\nESP8266 Time synchronized with NTP server.");
// Format the current time as a string
char timeStr[64];
strftime(timeStr, sizeof(timeStr), "%A, %B %d %Y %H:%M:%S", &timeinfo);
Serial.print("Current time: ");
Serial.println(timeStr);
// Sync the RTC with the NTP time
rtc.adjust(DateTime(timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday,
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec));
lastSyncMillis = millis(); // Record the last sync time in milliseconds
}
void checkTimeAndSync() {
// Check if 1 hour has passed since the last sync (1 hour = 3600000 milliseconds)
if (millis() - lastSyncMillis >= 3600000) {
Serial.println("Synchronizing time with NTP...");
syncTime();
}
}
Afficher le code brut
Comment fonctionne le code ?
Ce code est similaire au précédent, mais utilise un serveur NTP pour synchroniser l’heure. Pour obtenir l’heure d’un serveur NTP, l’ESP8266 doit être connecté à Internet.
Tout d’abord, vous devez inclure les bibliothèques suivantes.
#include
#include
#include
Ensuite, vous devez insérer vos connexions réseau dans les lignes suivantes.
// WiFi credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Ensuite, nous avons les détails du serveur NTP. Le serveur NTP renvoie l’heure en GMT. Si vous vous trouvez sur un fuseau horaire différent, vous pouvez ajouter le décalage de fuseau horaire sur la variable gmtOffset_sec en secondes. Ajoutez également l’heure d’été en secondes dans la variable daylightOffset_sec si nécessaire.
// NTP server details
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 0; // Offset for GMT in seconds
const int daylightOffset_sec = 3600; // Daylight savings time in seconds
Nous créons une structure tm appelée timeinfo pour enregistrer l’heure du serveur NTP.
struct tm timeinfo;
La structure tm contient une date et une heure de calendrier décomposées en ses composants :
- tm_sec : secondes après la minute ;
- tm_min : minutes après l’heure ;
- tm_hour : heures depuis minuit ;
- tm_mday : jour du mois ;
- tm_year : années depuis 1900 ;
- tm_wday : jours depuis dimanche ;
- tm_yday : jours depuis le 1er janvier ;
- tm_isdst : indicateur d’heure d’été ;
- documentation sur la structure tm.
Pour en savoir plus sur l’obtention de l’heure d’un serveur NTP avec l’ESP8266, consultez ce didacticiel : Obtenir la date et l’heure avec le client-serveur NTP NodeMCU ESP8266.
Nous créons une variable pour enregistrer le temps qui s’est écoulé depuis la synchronisation de l’heure.
unsigned long lastSyncMillis = 0; // Last sync time in milliseconds
Dans le setup(), nous initialisons le moniteur série et connectons l’ESP8266 au Wi-Fi.
void setup() {
Serial.begin(115200);
initWiFi();
Nous initialisons le module RTC.
// Initialize RTC
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
Et enfin, nous appelons la fonction syncTime(), déclarée à la fin du code, pour synchroniser l’heure.
// Sync the RTC at startup
syncTime();
La fonction syncTime()
Sur la fonction syncTime(), nous récupérons l’heure du serveur NTP et la sauvegardons sur la variable timeinfo.
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); // Configure time with NTP server
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
Ensuite, nous appelons la méthode rtc.adjust() et passons en arguments les champs horaires de la variable timeinfo. Cela synchronisera l’heure RTC avec l’heure du serveur NTP.
// Sync the RTC with the NTP time
rtc.adjust(DateTime(timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday,
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec));
Remarque : timeinfo.tm_year contient le nombre d’années depuis 1900. Nous devons donc ajouter 1900 pour obtenir l’année en cours.
Enfin, nous mettons à jour lastSyncMillis() avec l’heure actuelle.
// Sync the RTC at startup
syncTime();
boucle()
Dans la boucle(), nous commençons par appeler la fonction checkTimeAndSync().
checkTimeAndSync(); // Check if 1 hour has passed and sync if necessary
Cette fonction vérifiera si une heure s’est écoulée depuis la dernière synchronisation et synchronisera l’heure si nécessaire.
void checkTimeAndSync() {
// Check if 1 hour has passed since the last sync (1 hour = 3600000 milliseconds)
if (millis() - lastSyncMillis >= 3600000) {
Serial.println("Synchronizing time with NTP...");
syncTime();
}
}
Toujours dans la boucle(), après avoir synchronisé l’heure, nous récupérons l’heure du module RTC et imprimons l’heure dans le Serial Monitor toutes les 10 secondes.
// Get current time from RTC
DateTime now = rtc.now();
// Getting each time field in individual variables
String yearStr = String(now.year(), DEC);
String monthStr = (now.month() < 10 ? "0" : "") + String(now.month(), DEC);
String dayStr = (now.day() < 10 ? "0" : "") + String(now.day(), DEC);
String hourStr = (now.hour() < 10 ? "0" : "") + String(now.hour(), DEC);
String minuteStr = (now.minute() < 10 ? "0" : "") + String(now.minute(), DEC);
String secondStr = (now.second() < 10 ? "0" : "") + String(now.second(), DEC);
String dayOfWeek = daysOfTheWeek[now.dayOfTheWeek()];
// Complete time string
String formattedTime = dayOfWeek + ", " + yearStr + "-" + monthStr + "-" + dayStr + " " + hourStr + ":" + minuteStr + ":" + secondStr;
// Print the complete formatted time
Serial.println(formattedTime);
Serial.println();
delay(10000);
Tester le code
Téléchargez le code précédent sur l’ESP8266. Il se connectera à Internet, obtiendra l’heure du serveur NTP et synchronisera l’heure du module RTC.
Après cela, il affichera la date et l’heure toutes les 10 secondes.

Toutes les heures, il resynchronisera l’heure.
Ajustements de l’heure d’été et du fuseau horaire
Même si vous ajustez le décalage pour obtenir l’heure de votre fuseau horaire, il ne prendra pas en compte le moment où l’heure d’été est active ou non (lorsque l’heure change). Il existe un moyen d’obtenir l’heure de votre fuseau horaire spécifique et de l’ajuster à l’heure d’été en définissant la variable d’environnement TZ sur la valeur correcte.
L’exemple suivant est similaire au précédent, mais vous obtiendrez toujours l’heure correcte en tenant compte de votre fuseau horaire (et de l’heure d’été).
/*
Rui Santos & Sara Santos - Raspberryme.com
Complete project details at https://Raspberryme.com/esp8266-nodemcu-ds1307-real-time-clock-rtc-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include
#include
#include // For DS3231 or DS1307 RTC module
// Enter your Wi-Fi credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// NTP server and timezone details
const char* ntpServer = "pool.ntp.org";
const char* timezone = "WET0WEST,M3.5.0/1,M10.5.0";
// Check list of timezones here: https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
// RTC object (change to RTC_DS3231 for DS3231 module)
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
// Track last sync time
struct tm timeinfo;
unsigned long lastSyncMillis = 0; // Last sync time in milliseconds
void setup() {
Serial.begin(115200);
initWiFi();
// Initialize RTC
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1); // Stop if RTC is not found
}
// Sync the RTC at startup
syncTime();
}
void loop() {
checkTimeAndSync(); // Check if 1 hour has passed and sync if necessary
// Get current time from RTC
DateTime now = rtc.now();
// Format the time as strings
String yearStr = String(now.year());
String monthStr = (now.month() < 10 ? "0" : "") + String(now.month());
String dayStr = (now.day() < 10 ? "0" : "") + String(now.day());
String hourStr = (now.hour() < 10 ? "0" : "") + String(now.hour());
String minuteStr = (now.minute() < 10 ? "0" : "") + String(now.minute());
String secondStr = (now.second() < 10 ? "0" : "") + String(now.second());
String dayOfWeek = daysOfTheWeek[now.dayOfTheWeek()];
// Print the formatted time
String formattedTime = dayOfWeek + ", " + yearStr + "-" + monthStr + "-" + dayStr + " " + hourStr + ":" + minuteStr + ":" + secondStr;
Serial.println(formattedTime);
delay(10000);
}
void initWiFi() {
Serial.print("Connecting to WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected.");
}
void syncTime() {
// Configure time with NTP server and get time info
configTime(0, 0, ntpServer);
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
// Configure timezone for DST using POSIX rule
Serial.println("Configuring timezone and daylight saving time");
setenv("TZ", timezone, 1);
tzset();
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain adjusted time");
return;
}
Serial.println("\nTime synchronized with NTP server with timezone and DST.");
char timeStr[64];
strftime(timeStr, sizeof(timeStr), "%A, %B %d %Y %H:%M:%S", &timeinfo);
Serial.print("Current time: ");
Serial.println(timeStr);
// Update the RTC time
rtc.adjust(DateTime(timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday,
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec));
lastSyncMillis = millis(); // Update last sync time
}
void checkTimeAndSync() {
// Sync with NTP server every 1 hour (3600000 ms)
if (millis() - lastSyncMillis >= 3600000) {
Serial.println("Synchronizing time with NTP...");
syncTime();
}
}
Afficher le code brut
Fondamentalement, nous obtenons l’heure du serveur NTP, la convertissons dans votre fuseau horaire en définissant la variable d’environnement TZ, puis nous définissons le module RTC avec cette heure. Toutes les heures, le module RTC resynchronise son heure (vous pouvez la modifier pour une période plus longue).
Comment fonctionne le code ?
Ce code est assez similaire à l’exemple précédent, jetons juste un œil aux parties pertinentes pour ajuster le fuseau horaire.
Définissez votre chaîne de fuseau horaire sur la variable suivante. Une liste des chaînes de fuseau horaire peut être trouvée ici. La nôtre est Europe/Lisbonne.
const char* timezone = "WET0WEST,M3.5.0/1,M10.5.0";
Dans la fonction syncTime(), nous récupérons d’abord l’heure du serveur NTP.
void syncTime() {
// Configure time with NTP server and get time info
configTime(0, 0, ntpServer);
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
Pour convertir l’heure en un fuseau horaire spécifique, utilisez la fonction setenv() pour définir la variable d’environnement TZ (fuseau horaire) comme suit, dans lequel fuseau horaire est votre chaîne de fuseau horaire.
setenv("TZ", timezone, 1);
Après cela, appelez la fonction tzset() pour que les modifications prennent effet.
tzset();
Après cela, appelez à nouveau la fonction getLocalTime() pour obtenir l’heure ajustée à votre fuseau horaire.
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain adjusted time");
return;
}
Maintenant que vous avez ajusté l’heure, vous pouvez synchroniser l’heure du module RTC en utilisant rtc.adjust().
rtc.adjust(DateTime(timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday,
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec));
Le reste du code fonctionne exactement comme l’exemple précédent.
Tester l’exemple
Maintenant, après avoir téléchargé le code, vous devriez obtenir l’heure correcte pour votre fuseau horaire et l’ajuster à l’heure d’été.

Horloge NodeMCU ESP8266 avec module RTC et écran OLED (avec fuseau horaire et heure d’été)
Désormais, nous pouvons facilement créer une horloge numérique ESP8266 qui affiche toujours l’heure correcte, synchronisée avec votre fuseau horaire et prenant en compte l’heure d’été.

Câblage du circuit
Ajoutez un écran OLED à votre circuit. Câblez-le comme indiqué dans le tableau ci-dessous.
| Écran OLED | ESP8266 |
| SDA | GPIO4 (D2) |
| SCL | GPIO5 (D1) |
| GND | GND |
| VCC | 3V3 |
Horloge ESP8266 NodeMCU avec module RTC et écran OLED – Code
Téléchargez le code suivant sur votre tableau. Ajustez la variable de fuseau horaire avec votre chaîne de fuseau horaire et insérez vos informations d’identification réseau.
/*
Rui Santos & Sara Santos - Raspberryme.com
Complete project details at https://Raspberryme.com/esp8266-nodemcu-ds1307-real-time-clock-rtc-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include
#include
#include // For DS3231 or DS1307 RTC module
#include
// Enter your Wi-Fi credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// NTP server and timezone details
const char* ntpServer = "pool.ntp.org";
const char* timezone = "WET0WEST,M3.5.0/1,M10.5.0";
// Check list of timezones here: https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
// RTC object (change to RTC_DS3231 for DS3231 module)
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
// OLED display setup
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Track last sync time
struct tm timeinfo;
unsigned long lastSyncMillis = 0;
void setup() {
Serial.begin(115200);
initWiFi();
// Initialize the OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
while (1); // Stop if display initialization fails
}
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.display();
// Initialize RTC
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
// Sync the RTC at startup
syncTime();
}
void loop() {
checkTimeAndSync(); // Check if 1 hour has passed and sync if necessary
// Get current time from RTC
DateTime now = rtc.now();
// Format the time as strings
String yearStr = String(now.year());
String monthStr = (now.month() < 10 ? "0" : "") + String(now.month());
String dayStr = (now.day() < 10 ? "0" : "") + String(now.day());
String hourStr = (now.hour() < 10 ? "0" : "") + String(now.hour());
String minuteStr = (now.minute() < 10 ? "0" : "") + String(now.minute());
String secondStr = (now.second() < 10 ? "0" : "") + String(now.second());
String dayOfWeek = daysOfTheWeek[now.dayOfTheWeek()];
// Construct the formatted time
String formattedTime = dayOfWeek + "\n" + yearStr + "-" + monthStr + "-" + dayStr +
"\n" + hourStr + ":" + minuteStr + ":" + secondStr;
// Display the formatted time on the OLED
display.clearDisplay();
display.setCursor(0, 0);
display.println(formattedTime);
display.display();
delay(1000); // Update every second
}
void initWiFi() {
Serial.print("Connecting to WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected.");
}
void syncTime() {
// Configure time with NTP server and get time info
configTime(0, 0, ntpServer);
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
// Configure timezone for DST using POSIX rule
Serial.println("Configuring timezone and daylight saving time");
setenv("TZ", timezone, 1);
tzset();
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain adjusted time");
return;
}
Serial.println("\nTime synchronized with NTP server with timezone and DST.");
char timeStr[64];
strftime(timeStr, sizeof(timeStr), "%A, %B %d %Y %H:%M:%S", &timeinfo);
Serial.print("Current time: ");
Serial.println(timeStr);
// Update the RTC with NTP time
rtc.adjust(DateTime(timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday,
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec));
lastSyncMillis = millis(); // Update last sync time
}
void checkTimeAndSync() {
// Sync with NTP server every 1 hour (3600000 ms)
if (millis() - lastSyncMillis >= 3600000) {
Serial.println("Synchronizing time with NTP...");
syncTime();
}
}
Afficher le code brut
Nous n’expliquerons pas comment fonctionne ce code. La majeure partie a été expliquée dans les exemples précédents. Pour apprendre à interfacer l’écran OLED avec l’ESP8266, vous pouvez utiliser le didacticiel suivant comme référence.
Démonstration
Après avoir téléchargé le code, l’horloge numérique est prête. Maintenant, vous pouvez créer une jolie coque pour un look plus fini.

Conclusion
Dans ce didacticiel, vous avez appris à utiliser le module RTC DS1307 avec l’ESP8266. Vous avez appris à régler et à lire l’heure. Vous avez également appris à synchroniser périodiquement l’heure avec un serveur NTP, afin que le RTC soit toujours à l’heure. De plus, nous avons également examiné comment ajuster l’heure à votre fuseau horaire et prendre en compte l’heure d’été.
Enfin, nous avons créé une horloge numérique utilisant un écran OLED. Alternativement, vous pouvez également utiliser un écran LCD, par exemple. Vous souhaiterez peut-être également combiner ce projet avec les éléments suivants :
Nous avons des tutoriels et des guides pour plus de 20 modules avec l’ESP8266 qui pourraient vous être utiles :
Si vous souhaitez en savoir plus sur l’ESP8266, consultez nos ressources :
Merci d’avoir lu.
Apprenez l’histoire de Raspberry Pi à travers cette vidéo :

-
DollaTek 5Pcs Minuscule RTC I2C DS1307 AT24C32 Horloge en Temps réel Module pour Arduino AVR PIC 51 Arm
-
DollaTek 10Pcs Minuscule RTC I2C DS1307 AT24C32 Horloge en Temps réel Module pour Arduino AVR PIC 51 Arm
