Ajout de code logiciel pour afficher la date et l’heure locale
Nous allons maintenant modifier notre code logiciel Arduino pour réaliser une horloge connectée affichant:
- L’heure à la seconde près en première ligne.
- La date du jour en deuxième ligne.
Bibliothèque nécessaire
Pour gérer la conversion d’une date depuis le format « Unix Time » vers une date au format calendaire et une heure locale, nous allons utiliser la bibliothèque Arduino Timezone nommée « TimeZone by Jack Christensen » . Cette bibliothèque prend également en compte les changements d’heure été/hivers du pays concerné.
Pour fonctionner, cette bibliothèque nécessite que la bibliothèque Time nommée « Time by Michael Margolis » soit également installée.
Installez ces 2 bibliothèques, puis complétez le code logiciel pour indiquer au compilateur l’utilisation de Timezone:
#include <Timezone.h>
En France comme en Europe, le passage:
- à l’heure d’été s’effectue le dernier dimanche de mars et
- à l’heure d’hiver s’effectue le dernier dimanche d’octobre.
Nous allons traduire en langage informatique ces règles de changement d’heure en utilisant des structures du type « TimeChangeRule » défini dans la bibliothèque Timezone.
Vous allez ajouter la déclaration de deux structures globales de type « TimeChangeRule » « RegleHeureEteEurope_G » et « RegleHeureHiverEurope_G« . Ces structures se composent des champs suivants:
- Abréviation: Chaîne de maximum 5 caractères permettant d’identifier de façon unique cette règle. Dans ce programme, vous choisirez les majuscules des noms de structures.
- Semaine: Semaine du mois pour laquelle la règle s’applique. Pour les 2 changements d’heure en Europe, il s’agit des 2 dernières semaines du mois. Vous utiliserez donc le mot clef « Last« .
- Jour de la semaine: Jour de la semaine pour lequel la règle s’applique. Pour les 2 changements d’heure en Europe, il s’agit du dimanche. Vous utiliserez donc le mot clef « Sun« .
- Heure: Heure de déclenchement de la règle. Le passage à l’heure d’été se déclenche à 2 heures et le passage à l’heure d’hiver à 3 heures.
- Décalage: Décalage du fuseau horaire en nombre de minutes par rapport à l’heure UTC (Temps universel coordonné). Ce décalage est de 2 heures l’été et 1 heure l’hiver.
Vous en déduisez la règle suivante pour le passage à l’heure d’été:
TimeChangeRule RegleHeureEteFrance_G = {"RHEE", Last, Sun, Mar, 2, 120}; // Règle de passage à l'heure d'été pour la France
et la règle suivante pour le passage à l’heure d’hiver:
TimeChangeRule RegleHeureHiverFrance_G = {"RHHE", Last, Sun, Oct, 3, 60}; // Règle de passage à l'heure d'hiver la France
Vous pouvez maintenant déclarer l’objet de conversion à l’heure française prenant en compte ces 2 règles de changement d’heure:
Timezone ConvertirHeureFrance_G(RegleHeureEteFrance_G, RegleHeureHiverFrance_G); // Objet de conversion d'heure avec les caractéristiques de la métropole française
Conversion du « Unix Time » en heure locale
Tout d’abord, je vous invite à nettoyer votre fonction loop de ce tout ce qui concerne l’affichage du « Unix Time », ce qui vous permet de conserver l’ossature suivante:
// Fonction principale du programme, s'exécute en boucle: void loop() { // Variables de la fonction time_t HeureLocale_L; if(WiFi.status()==WL_CONNECTED) { // Internet est disponible HeureLocale_L = ConvertirHeureFrance_G.toLocal(ClientNtp_G.getUnixTime()); AfficherHeureLocale(HeureLocale_L); } else { // Pas de connexion internet Afficheur_G.setCursor(0,0); Afficheur_G.print("Erreur de "); Afficheur_G.setCursor(0,1); Afficheur_G.print(" Connexion"); } delay(300); }
Sous Arduino et plus généralement en langage C embarqué, le type dédié à la mémorisation d’une date/heure locale est le type « time_t« . Vous commencez donc par déclarer la variable destinée à recevoir cette donnée:
// Variables de la fonction time_t HeureLocale_L;
Concernant la conversion en elle-même, la méthode « toLocal » de notre objet ConvertirHeureFrance_G permet d’effectuer cette conversion de l' »Unix Time » en heure locale:
// Internet est disponible HeureLocale_L = ConvertirHeureFrance_G.toLocal(ClientNtp_G.getUnixTime());
Afin de rendre le code plus lisible, je vous propose de séparer l’affichage de l’heure locale du reste du code en créant une fonction dédiée appelée « AfficherHeureLocale« . Nous lui passerons l’heure locale en paramètre en utilisant le type C standard « time_t » :
AfficherHeureLocale(HeureLocale_L);
Fonction d’affichage de l’heure locale
Il ne nous reste plus qu’à écrire la fonction Arduino d’affichage de l’heure locale de notre horloge connectée. Vous commencez par écrire son ossature:
void AfficherHeureLocale(time_t Heure_P) { }
Afin de pouvoir afficher
- l’abréviation du jour de la semaine en utilisant l’expression « AbreviationJour_L[…] »
- et du mois en utilisant l’expression « AbreviationMois_L[…] »
vous déclarez les tableaux suivants:
char AbreviationMois_L[12][4]={"Jan","Fev","Mar","Avr","Mai","Jun","Jul","Aou","Sep","Oct","Nov","Dec"}; char AbreviationJour_L[7][4]={"Dim","Lun","Mar","Mer","Jeu","Ven","Sam"};
Pour le reste de la fonction d’affichage de l’heure local, vous utilisez les fonctions de la bibliothèque « Time« :
- « hour« , « minute« , « second » pour extraire heure, minute et seconde.
- « weekday » pour le jour de la semaine.
- « day« , « month » et « year » pour la date complète.
Vous obtenez alors une fonction d’affichage de la date et l’heure réutilisable dans d’autres programmes, quelque soit votre source de temps:
void AfficherHeureLocale(time_t Heure_P) { char Buffer_L[50]; char AbreviationMois_L[12][4]={"Jan","Fev","Mar","Avr","Mai","Jun","Jul","Aou","Sep","Oct","Nov","Dec"}; char AbreviationJour_L[7][4]={"Dim","Lun","Mar","Mer","Jeu","Ven","Sam"}; Afficheur_G.setCursor(0,0); sprintf(Buffer_L, " %.2d:%.2d:%.2d", hour(Heure_P), minute(Heure_P), second(Heure_P)); Afficheur_G.print(Buffer_L); Afficheur_G.setCursor(0,1); sprintf(Buffer_L, "%s %.2d %s %d", AbreviationJour_L[weekday(Heure_P)-1], day(Heure_P), AbreviationMois_L[month(Heure_P)-1], year(Heure_P)); Afficheur_G.print(Buffer_L); }
Et voilà le programme est fini. Voici le code complet:
// Déclaration des librairies utilisées #if defined(ESP8266) #include <ESP8266WiFi.h> #elif defined(ESP32) #include <WiFi.h> #endif #include <LiquidCrystal_I2C.h> #include <EasyNTPClient.h> #include <WiFiUdp.h> #include <Timezone.h> // Déclaration globales LiquidCrystal_I2C Afficheur_G(0x27, 16, 2); // Afficheur LCD1206 d'addresse 0x27 avec écran de 2 lignes de 16 caractères WiFiUDP Udp_G; // Objet UDP permettant d'envoyer et recevoir des trames Wi-Fi selon le protocole UDP EasyNTPClient ClientNtp_G(Udp_G, "pool.ntp.org"); // Objet NTP synchronisé avec "pool.ntp.org" TimeChangeRule RegleHeureEteFrance_G = {"RHEE", Last, Sun, Mar, 2, 120}; // Règle de passage à l'heure d'été pour la France TimeChangeRule RegleHeureHiverFrance_G = {"RHHE", Last, Sun, Oct, 3, 60}; // Règle de passage à l'heure d'hiver la France Timezone ConvertirHeureFrance_G(RegleHeureEteFrance_G, RegleHeureHiverFrance_G); // Objet de conversion d'heure avec les caractéristique de la métropole française // Fonction de démarrage, s'exécute une seule fois: void setup() { // Constantes de la fonction const char* SSID_L = "LiveBox_1324"; // Nom du réseau Wi-Fi const char* MOT_DE_PASSE_L = "12345?ABCDE"; // Mot De Passe du réseau // Variables de la fonction wl_status_t StatutConnexion_L; // Pour mémoriser l'état de la connexion #if defined(ESP8266) Afficheur_G.init(4,5); // Initialisation de l'afficheur, SDA=4, SCL=5 #elif defined(ESP32) Afficheur_G.init(32,33); // Initialisation de l'afficheur, SDA=32, SCL=33 #endif Afficheur_G.backlight(); // Allumage du rétroéclairage WiFi.begin(SSID_L, MOT_DE_PASSE_L); // Tentative de connexion au point d'accès Wi-Fi StatutConnexion_L = WiFi.status(); // Lecture de l'état de la connexion et mémorisation dans la variable "StatutConnexion_L" while ((StatutConnexion_L != WL_NO_SSID_AVAIL)&&(StatutConnexion_L != WL_CONNECTED)&&(StatutConnexion_L != WL_CONNECT_FAILED)) { delay(500); Afficheur_G.print("."); // Pour visualiser la tentative de connexion et faire patienter StatutConnexion_L = WiFi.status(); // Lecture de l'état de la connexion et mémorisation dans la variable "StatutConnexion_L" } Afficheur_G.clear(); // On efface l'écran avant l'affichage de l'heure } // Fonction principale du programme, s'exécute en boucle: void loop() { // Variables de la fonction time_t HeureLocale_L; if(WiFi.status()==WL_CONNECTED) { // Internet est disponible HeureLocale_L = ConvertirHeureFrance_G.toLocal(ClientNtp_G.getUnixTime()); AfficherHeureLocale(HeureLocale_L); } else { // Pas de connexion internet Afficheur_G.setCursor(0,0); Afficheur_G.print("Erreur de "); Afficheur_G.setCursor(0,1); Afficheur_G.print(" Connexion"); } delay(300); } void AfficherHeureLocale(time_t Heure_P) { char Buffer_L[50]; char AbreviationMois_L[12][4]={"Jan","Fev","Mar","Avr","Mai","Jun","Jul","Aou","Sep","Oct","Nov","Dec"}; char AbreviationJour_L[7][4]={"Dim","Lun","Mar","Mer","Jeu","Ven","Sam"}; Afficheur_G.setCursor(0,0); sprintf(Buffer_L, " %.2d:%.2d:%.2d", hour(Heure_P), minute(Heure_P), second(Heure_P)); Afficheur_G.print(Buffer_L); Afficheur_G.setCursor(0,1); sprintf(Buffer_L, "%s %.2d %s %d", AbreviationJour_L[weekday(Heure_P)-1], day(Heure_P), AbreviationMois_L[month(Heure_P)-1], year(Heure_P)); Afficheur_G.print(Buffer_L); }
Test d’affichage de l’heure locale avec l’ESP8285
Une compilation, un transfert dans le microcontrôleur et voilà le résultat pour l’ESP8285:
Test d’affichage de l’heure locale avec l’ESP32
Pour l’ ESP32-DevKitC, voici la vidéo :
Votre horloge connectée est terminée. Si ce projet Arduino vous a plu, n’hésitez pas à ajouter vos commentaires !
bonjour ,
à partir de ce programme il serais possible de mettre à jour une rtc du type DS3231 pour la remettre a l’heure .
d’avance merci .
Bonjour Hohm,
Oui tout à fait. Il est possible d’utiliser ce programme pour mettre à jour l’heure d’un RTC (DS3231, DS1307 ou autre). Cela a un intérêt pour un projet nécessitant une horloge précise avec une couverture Wi-Fi intermittente.
Bonjour est-ce compatible avec une carte ESP8266 ?
merci d’avance
Bonjour Harlock73,
Oui ce programme est compatible avec une carte ESP8266. La différence entre les deux cartes est la mémoire de stockage qui est plus faible sur l’ESP8266. Je n’ai pas de carte sous la main pour tester mais il devrait y avoir assez de place dans l’ESP8266.
Je vous laisse me confirmer 😉
Bonjour et merci pour ce tuto. Peut on adapter ce projet avec un ESP32 à la place d’un ESP8285 SVP.
Par avance merci de votre réponse.
Lalouhu096.
Bonjour Lalou,
l’ESP32 étant également équipé d’une interface Wi-Fi, ce projet ESP8285 peut facilement être adapté à cet autre microcontrôleur du même fabricant.
Bonjour et un grand merci pour ce tuto clair et précis, notamment sur la gestion du passage en heure été/hiver. Tout fonctionne correctement sur la carte ESP-01 qui contient une puce ESP8266. Bravo à vous, beau travail.
merci bien pour ce tuto
Bonjour, je sais que ce tuto date de quelques années déjà. Je désire m’initier au monde Arduino et ce projet est justement ce qu’il me faut. D’abord très bien expliqué en partant de zéro, et en y allant pas à pas. En fait j’ai besoin d’une horloge qui ne dérive pas dans le temps (donc du type WiFi via NTP, ou DCF77), capable de générer une impulsion d’1 min à chaque heure pleine. Donc ma question est (avant de me lancer dans l’achat de tous les composants): est-il possible de sortir une commande du ESP8285 (il me semble qu’il y a des GPIO)? Par exemple lorsque la valeur « minute » = 00. Pour la modification du programme, je pense que je pourrai me débrouiller lorsque je serai un peu familiarisé. D’avance merci et encore bravo pour ce tuto!
Merci Jacques,
pour ce retour.
Oui il reste des broches de disponibles sur la carte ESP8285.
Je compléterai la description du produit en y précisant l’affectation des broches (pinout) à mon retour de vacance dans 1 semaine afin de vous aider dans les développements.
Il est également à noter que les achats sur la boutique seront réouvert à ce moment.
J’espère que cela repond à votre question.
Bonjour Nikko, un tout grand merci pour avoir pris le temps de me répondre.
Oui je patiente jusqu’à la réouverture de la boutique. Et j’ai déjà réponse à ma question, mais j’en aurai surement d’autres d’ici là 😉 .
Bonne fin de vacances et encore merci.
Bonjour Jacques,
la fiche produit de l’ESP8285 a été complétée avec le brochage détaillé (Pinout).
Bonjour,
Je souhaite réaliser ce projet avec un autre module wifi : l’ESP-32. Cela est possible puisqu’il est aussi compatible avec le wifi.
Ma question serait de savoir si le programme final que vous avez fourni peut s’adapter à l’ESP-32 ? Et est-ce que vous avez fait un tuto pour ce module ?
Merci d’avance, je vous souhaite une agréable journée.
Cordialement,
L.E.
Bonjour Elchardus,
Oui le programme est facilement adaptable à l’ESP32.
Je vais mettre à jour ce tuto dans les prochains jours pour couvrir les microcontrôleurs EPS8285 et ESP32.
Super !
Merci beaucoup !
Le tutoriel d’horloge connectée a été mis à jour pour être utilisable sur plateforme ESP32.
Incroyable, je vous remercie !!