ESP32 Horloge à LED
Présentation
On se propose de réaliser une Horloge à LED.
Les besoins sont :
- Récupérer l'heure (avec une connectivité Internet c'est facile) en NTP sur pool.ntp.org par exemple.
- Afficher l'heure sur une matrice de LED basée sur un MAX7219.
- Il faut aussi se localiser car un serveur NTP donne l'heure TU (avant on disait GMT) il nous faut connaitre la "time zone" (le fuseau horaire) et l'état DST (Heure d'été / heure d'Hiver). Des API existent pour cela, Abstract API en est une.
- Comme cette API est implémentée en HTTPS il faudra également utilise la librairie https.
Montage et branchements
On se base sur la page déjà écrite pour brancher une carte "breakout" ESP32 et un module à base de MAX7219.
Code
Code de test
On teste le montage avec le code suivant.
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4 // 4 blocks
#define CS_PIN 21
// create an instance of the MD_Parola class
MD_Parola ledMatrix = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
void setup() {
// Initialize the breakout buildin led
pinMode(2,OUTPUT);
digitalWrite(2,HIGH);
ledMatrix.begin(); // initialize the LED Matrix
ledMatrix.setIntensity(0); // set the brightness of the LED matrix display (from 0 to 15)
ledMatrix.displayClear(); // clear LED matrix display
}
void loop() {
ledMatrix.setTextAlignment(PA_CENTER);
ledMatrix.print("12:30"); // display text
Résultat:
Ca marche on a une horloge à l'heure… deux fois par jours.
Mise à l'heure
En se connectant à un serveur NTP on pourrait afficher l'heure UT.
#include <WiFi.h>
#include <WiFiMulti.h>
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include "SSIDs.h"
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4 // 4 blocks
#define CS_PIN 21
// create an instance of the MD_Parola class
MD_Parola ledMatrix = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Time update
void setClock() {
configTime(0, 0, "pool.ntp.org");
Serial.println("Waiting for NTP time sync: ");
time_t nowSecs = time(nullptr);
while (nowSecs < 8 * 3600 * 2) {
delay(500);
Serial.print(F("."));
yield();
nowSecs = time(nullptr);
}
Serial.println();
struct tm timeinfo;
gmtime_r(&nowSecs, &timeinfo);
Serial.print("Current time: ");
Serial.println(asctime(&timeinfo));
}
// Manage Wifi
WiFiMulti WiFiMulti;
void setup() {
Serial.begin(115200);
// Initialize the breakout buildin led
pinMode(2,OUTPUT);
digitalWrite(2,HIGH);
ledMatrix.begin(); // initialize the LED Matrix
ledMatrix.setIntensity(0); // set the brightness of the LED matrix display (from 0 to 15)
ledMatrix.displayClear(); // clear LED matrix display
WiFi.mode(WIFI_STA);
WiFiMulti.addAP(PRIMARY_SSID);
#ifdef SECONDARY_SSID
WiFiMulti.addAP(SECONDARY_SSID);
#endif
// wait for WiFi connection
Serial.println("Serach WIFI");
ledMatrix.setTextAlignment(PA_CENTER);
ledMatrix.print("WiFi");
Serial.print("Waiting for WiFi to connect...");
while ((WiFiMulti.run() != WL_CONNECTED)) {
delay (100);
}
ledMatrix.setTextAlignment(PA_CENTER);
ledMatrix.print(WiFi.SSID());
delay (1000);
Serial.println(" connected");
ledMatrix.setTextAlignment(PA_CENTER);
ledMatrix.print("Time");
setClock();
}
void loop() {
struct tm timeinfo;
time_t nows = time(nullptr);
gmtime_r(&nows, &timeinfo);
Serial.print(asctime(&timeinfo));
int h = timeinfo.tm_hour;
int m = timeinfo.tm_min;
char timeBuffer[6];
sprintf(timeBuffer,"%d:%02d", h, m);
ledMatrix.setTextAlignment(PA_CENTER);
ledMatrix.print(timeBuffer); // display time
unsigned long old=m;
// Wait for next minute
while (old==m) {
nows = time(nullptr);
gmtime_r(&nows, &timeinfo);
m = timeinfo.tm_min;
}
}
Dans l'ordre l'afficheur nous indique
La connexion wifi s'établit.
Une fois celle-ci établie, comme on utilise WiFiMulti on affiche le SSID qui a été choisit.
Puis on affiche :
Et puis enfin l'heure (mise a jour toutes les secondes)
Gestion des "time zones"
On va utiliser l'API Abstract qui, à partir de notre IP publique va nous donner notre position, notre timezone etc.
