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ègle 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:

  • Abbré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 minute 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à votre programme est fini. Voici le code complet:

// Déclaration des librairies utilisées
#include <ESP8266WiFi.h>
#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
    
    Afficheur_G.init(5,4); // Initialisation de l'afficheur, SDA=5, SCL=4
    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);
}

Une compilation, un transfert dans l’ESP8285 et voilà le résultat:

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

Ce contenu a été publié dans Arduino, ESP8285. Vous pouvez le mettre en favoris avec ce permalien.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *