You are currently viewing Horloge connectée avec Arduino
Horloge connectée avec Arduino

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.
Horloge connectée à l'aide d'un ESP8285 et d'Arduino

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:

Affichage de la date et de l’heure local sur une carte de développement ESP8285

Test d’affichage de l’heure locale avec l’ESP32

Pour l’ ESP32-DevKitC, voici la vidéo :

Affichage de la date et de l’heure local sur une carte de développement ESP32-DevKitC

Votre horloge connectée est terminée. Si ce projet Arduino vous a plu, n’hésitez pas à ajouter vos commentaires !

S’abonner
Notification pour
guest
17 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires
HOHM
3 années il y a

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 .

Harlock73
Harlock73
3 années il y a

Bonjour est-ce compatible avec une carte ESP8266 ?
merci d’avance

Lalou hu096
Lalou hu096
3 années il y a

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.

Vincent
Vincent
2 années il y a

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.

TUO HERVE
TUO HERVE
1 année il y a

merci bien pour ce tuto

Jacques
Jacques
1 année il y a

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!

Jacques
Jacques
Répondre à  Nikko
1 année il y a

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.

Elchardus
Elchardus
11 mois il y a

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.

Elchardus
Elchardus
Répondre à  Nikko
11 mois il y a

Super !
Merci beaucoup !

Elchardus
Elchardus
Répondre à  Nikko
11 mois il y a

Incroyable, je vous remercie !!