Ajouter une horloge à vos montages grâce à internet et NTP :)

Introduction :

Nous avons vu il y a environ deux ans comment donner l’accès à l’heure à vos montages électroniques grâce une horloge temps réel RTC (Real Time Clock) DS1302 dans un article disponible ICI.
Nous allons voir ici comment accéder l’heure sans utiliser une horloge RTC tout simplement en accédant à un serveur NTP (Network Time Protocol) via internet.
Nous utiliserons pour cela dans cet article un Wemos D1 mini qui permet l’accès à internet grâce à son ESP8266 qui dispose du WIFI malgré sa taille très réduite. Celui-ci est par ailleurs programmable avec l’IDE Arduino ce qui simplifie pas mal le travail. Vous trouverez sans difficulté sur internet des Wemos D1 mini pour environ un euro 🙂
Vous trouverez ci-dessous une photo du Wemos D1 mini ainsi que le détail des broches :
 
Le jour de la semaine ainsi que l’heure seront affichés dans la console série et sur un afficheur OLED de type SSD 1331 (pour plus de précisions sur l’utilisation de cet afficheur vous pouvez vous reporter à l’article disponible ICI).

Montage

Le montage est très simple puisqu’il suffit de raccorder le Wemos D1 mini pour l’alimenter grâce à sa prise USB.

Code

Dans le programme nous allons nous appuyer sur une bibliothèque qui permet d’instancier un client NTP qui se connectera à un serveur NTP pour récupérer la date et l’heure.

Il existe sur le WEB plusieurs bibliothèques NTP. Ici j’ai choisi d’utiliser celle de Fabrice Weinberg NTPClient qui peut être installée facilement dans votre IDE Arduino via les menus inclure une bibliothèque / gérer les bibliothèques en saisissant NTP dans le champ sujet, puis en cliquant sur installer.

La librairie NTPCLient utilise le protocole de transport  UDP pour se connecter au serveur NTP. Il faut donc inclure la librairie WiFiUdp.h dans l’entête de votre programme.

Dans le setup de votre programme, il faut initialiser l’objet NTPClient avec la configuration suivante :

  • Serveur NTP : par exemple europe.pool.ntp.org, fr.pool.ntp.org, etc.
  • Intervalle de mise à jour : 6 000 (60 secondes)
  • Décalage horaire (en secondes) : 3 600 secondes soit GMT+1
Cela donne l’instruction : NTPClient timeClient(ntpUDP, « europe.pool.ntp.org », 0, 60000);
Ensuite toujours dans le setup, il faut démarrer le service avec la méthode timeClient.begin().
Puis dans la boucle loop,  la récupération des mises à jour de l’heure sont effectuées à l’aide de la méthode timeClient.update();
Les autres méthodes suivantes peuvent ensuite être utilisées :
  • getDay() : jour de la semaine avec 0 pour dimanche
  • getHours() : l’heure
  • getMinutes() : les minutes
  • getSeconds() : les secondes
  • getFormattedTime() : heure au format hh:mm:ss
  • getEpochTime() : date au format epoch, c’est à dire le temps UNIX en secondes qui a débuté le 1er janvier 1970 à minuit.
Vous trouverez ci-dessous le programme complet utilisé  :
/*
  Skecth : pm_wemos_53_ntp.ino
  Description : Recuperation date et heure sur internet via un serveur NTP
                en utilisant la bibliotheque de NTPClient Fabrice Weinberg
                et affichage heure et jour sur OLED SSD 1331
  WEB : https://phmarduino.wordpress.com
  GIT :                 
  Auteur : PHMARDUINO
  Création : 22 11 2018
  Mise a jour : 26 11 2018 - affichage heure et jour sur OLED SSD 1331
*/

// Appel des bibs
#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>

// Declarations WIFI
const char* ssid = "MON WIFI";
const char* password = "MON MOT DE PASSE WIFI";

// Variables de travail
unsigned long epoch = 0;
int nujour = 0; //numero jour de la semaine avec 0 pour dimanche
String jour = "mon jour"; // dimanche, lundi, etc.
String heure = "mon heure ..";

// Declaration OLED SSD1331
#define sclk D5
#define mosi D7
#define cs   D8
#define rst  D3
#define dc   D1

// Declaration des couleurs
#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0
#define WHITE           0xFFFF

//Creation objet Adafruit_SSD1331 display 
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);

//Creation objet WIFI UDP puis du client NTP
WiFiUDP ntpUDP;
// Avec intervalle de mise à jour de 60 sec ...
// ... et offset en secondes cad decalage horaire, pour GMT+1 mettre 3600, GMT +8 mettre 28800, etc.
// ... et le serveur NTP utilise est : europe.pool.ntp.org
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);

void setup(){
  // Demarrage liaison serie
  Serial.begin(115200);
  // Demarrage ecanr oled ssd1331
  display.begin();
  // Connection au reseau WIFI
  WiFi.begin(ssid, password);
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }
  // Demarrage client NTP
  timeClient.begin();
}

void loop() {
  // Recup heure puis affichage
  timeClient.update();
  epoch = timeClient.getEpochTime(); // Heure Unix
  nujour = timeClient.getDay();    // jour de la semaine
  heure = timeClient.getFormattedTime(); // heure

  switch (nujour) { // on determine le jour
      case 0: 
        jour = "dimanche";
        break;
      case 1:
        jour = "lundi";
        break;
      case 2: 
        jour = "mardi";
        break;
      case 3: 
        jour = "mercredi";
        break;
      case 4: 
        jour = "jeudi";
        break;
      case 5: 
        jour = "vendredi";
        break;
       case 6: 
        jour = "samedi";
        break;
    }
  
  // Envoi des donnees recuperees sur la liaison serie
  Serial.print("Temps UNIX : ");
  Serial.print(epoch);
  Serial.print(" - jour : ");
  Serial.print(jour);
  Serial.print(" - heure : ");
  Serial.println(timeClient.getFormattedTime());

  // Affichage sur oled ssd1331
  display.fillScreen(BLACK);
  display.setTextSize(2);
  
  display.setCursor(0, 0);
  display.setTextColor(YELLOW);
  display.print(jour);

  display.drawFastHLine(0, 21, display.width() - 1, RED);

  display.setCursor(0, 25);
  display.setTextColor(WHITE);
  display.print(heure);

  display.drawFastHLine(0, 45, display.width() - 1, RED);
  
  display.setTextSize(1);
  display.setCursor(15, 52);
  display.setTextColor(BLUE);
  display.print("PHMARDUINO");
  
  delay(2000); // tempo de 2 sec
}



Le code est disponible sous GITHUB ICI.

 Résultats

Les résultats obtenus dans la console série de l’IDE Arduino sont les suivants :
Les résultats obtenus sur l’écran OLED sont les suivants :

 Ajout de la date

Nous allons voir maintenant comment compléter le code pour ajouter l’affichage de la date complète et non pas seulement du jour de la semaine.

Pour cela nous allons simplement utiliser la bibliothèque standard time.h.

Le nouveau programme complet est le suivant :
/*
  Skecth : pm_wemos_53_ntp_avec_date.ino
  Description : Recuperation date et heure sur internet via un serveur NTP
                en utilisant la bibliotheque de NTPClient Fabrice Weinberg
                et affichage heure et jour sur OLED SSD 1331
  WEB : https://phmarduino.wordpress.com
  GIT :                 
  Auteur : PHMARDUINO
  Création : 27 11 2018
  Mise a jour : 28 11 2018 - ajout affichage de la date
*/

// Appel des bibs
#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>
#include <time.h>

// Declarations WIFI
const char* ssid = "MONWIFI";
const char* password = "MON MOT DE PASSE WIFI";

// Variables de travail
unsigned long epoch = 0;
int nujour = 0; //numero jour de la semaine avec 0 pour dimanche
String jour = "mon jour"; // dimanche, lundi, etc.
String heure = "mon heure ..";
char buffer[80]; // Stockage de la date complete

// Declaration OLED SSD1331
#define sclk D5
#define mosi D7
#define cs   D8
#define rst  D3
#define dc   D1

// Declaration des couleurs
#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0
#define WHITE           0xFFFF

//Creation objet Adafruit_SSD1331 display 
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);

//Creation objet WIFI UDP
WiFiUDP ntpUDP;

//Creation objet client NTP avec les parametres suivants :
// - pool de serveurs NTP
// - en option le décalage horaire en secondes, ici 3600 pour GMT+1, pour GMT+8 mettre 28800, etc.
// - en option l intervalle de mise à jour en millisecondes par défaut à 60 secondes
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);

void setup(){
  // Demarrage liaison serie
  Serial.begin(115200);
  // Demarrage ecanr oled ssd1331
  display.begin();
  // Connection au reseau WIFI
  WiFi.begin(ssid, password);
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }
  // Demarrage client NTP
  timeClient.begin();
}

void loop() {
  // Recup heure puis affichage
  timeClient.update();
  epoch = timeClient.getEpochTime(); // Heure Unix
  nujour = timeClient.getDay();    // jour de la semaine
  heure = timeClient.getFormattedTime(); // heure

  // Calcul de la date en convertissant le temps UNIX epoch
  time_t timestamp = epoch;
  struct tm * pTime = localtime( & timestamp );
  strftime( buffer,80, "%d/%m/%Y", pTime );
  Serial.println(buffer);

  switch (nujour) { // on determine le jour
      case 0: 
        jour = "dimanche";
        break;
      case 1:
        jour = "lundi";
        break;
      case 2: 
        jour = "mardi";
        break;
      case 3: 
        jour = "mercredi";
        break;
      case 4: 
        jour = "jeudi";
        break;
      case 5: 
        jour = "vendredi";
        break;
       case 6: 
        jour = "samedi";
        break;
    }
  
  // Envoi des donnees recuperees sur la liaison serie
  Serial.print("Temps UNIX : ");
  Serial.print(epoch);
  Serial.print(" sec - jour : ");
  Serial.print(jour);
  Serial.print(" - heure : ");
  Serial.println(timeClient.getFormattedTime());

  // Affichage sur oled ssd1331
  display.fillScreen(BLACK);
  display.setTextSize(1);
  
  display.setCursor(0, 0);
  display.setTextColor(YELLOW);
  display.print(jour);

   display.setCursor(0, 10);
  display.setTextColor(YELLOW);
  display.print(buffer);

  display.drawFastHLine(0, 25, display.width() - 1, RED);

  display.setCursor(0, 30);
  display.setTextColor(WHITE);
  display.print(heure);

  display.drawFastHLine(0, 45, display.width() - 1, RED);
  
  display.setCursor(15, 52);
  display.setTextColor(BLUE);
  display.print("PHMARDUINO");
  
  delay(2000); // tempo de 2 sec
}



Le code est disponible sous GITHUB ICI.
Les résultats dans la console série de l’IDE Arduino sont les suivants :
Vous trouverez ci-dessous une photo du montage après modification :
Publicités

Répondre

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l'aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s