Afficheur de couleur Tempo EdF sur ESP8266 et ESP32

Affichage de couleur Tempo sur ESP8266 et ESP32
1- Présentation générale

Amis bidouilleurs,
bonjour,

Il y a déjà quelques temps, dans un autre fil sur le même sujet, l'idée de publier un afficheur de couleur Tempo pour ESP8266 avait été évoquée. Le temps de cette publication est arrivé.

Le projet de base ne comportait que l'extracteur qui récupérait les couleurs sur un site EdF. Il est en service dans une de mes bidouilles depuis des mois. Je l'ai enrichi d'un afficheur sur trois LEDs multicolores WS2812B et de diverses fonctions d'aide à la mise au point, à visée pédagogique, pour montrer ce qu'il est possible de faire dans ce domaine.

Le projet de base était sur ESP8266. Ce dernier arrivant en fin de vie, j'ai porté le code sur un ESP32, et je publie ici les deux versions, qui sont d'ailleurs quasiment identiques.

Enfin, j'en ai dérivé une version complétée enrichie de fonctions bien pratiques (OTA et serveur Telnet) pour montrer que l'on peut bidouiller sur un ESP (8266 ou 32) avec tout le confort moderne, sans être relié à son PC par un fil à la patte.

Bien entendu, je n'ai pas tout inventé et je rends dès ici hommage à J-M-L et à Bricoleau pour ce qui leur revient.

La publication est organisée de la manière suivante :

  • le matériel est décrit dans la suite de cette introduction,
  • ensuite, la mise en oeuvre pour les impatients,
  • la description des modules de la version de base (2 parties),
  • celle de la version complétée.

Pour le matériel, le plus simple est de se reporter au schéma ci-joint, qui comporte plusieurs points importants :

  • les ESP fonctionnent en 3V3 avec leur régulateur intégré qui abaisse la tension d'alimentation de 5V à 3V3. Les diodes LEDs WS2812B fonctionnent elles en 5V. Entre les deux, il faut prévoir un adaptateur de niveau, par ex. le montage classique à MOSFET que l'on trouve partout et que j'utilise avec succès,
  • par sécurité et respect des règles de l'art qui assurent fiabilité et tranquilité, il faut découpler l'alimentation des LEDs avec le dispositif classique : un condensateur chimique (lent) de moyenne capacité (220 µF) doublé d'un condensateur à film plastique (rapide) de 100 nF. Ca peut marcher sans, mais on est plus tranquille avec,
  • dans le même registre, l'ESP32, plus rapide, consomme aussi beaucoup plus que le 8266. Après avoir constaté quelques instabilités lors des transmissions WiFi, j'ai rajouté des condensateurs (respectivement 1000 µF et 220 µF) sur le 5V et le 3V3 et tout est rentré dans l'ordre,
  • enfin, cerise sur le gâteau, vous pouvez essayer le code sans les LEDs, vous alors pourrez suivre son fonctionnement sur le moniteur série.

En PJ :

La suite au prochain numéro...

2- Mise en oeuvre des versions de base (V03x)

Les zips contiennent le code, un par version et respectivement pour ESP8266 et ESP32.

ColTpo_P03h.zip (16.5 KB)
ColTpo32_P03h.zip (16.4 KB)

Il vous suffit de les décompresser dans votre arborescence Arduino et de veiller à ce que chaque programme principal (.ino) soit bien dans un répertoire portant le même nom que lui (sans le ".ino").

Les programmes utilisent les bibliothèques externes suivantes :

  • ArduinoJson,
  • Streaming,
  • Adafruit_NeoPixel,
    qui doivent être installées avec le gestionnaire de bibliothèque de l'IDE.

Ensuite, il vous faut paramétrer le programme pour votre environnement. Cela se passe dans le programme principal (.ino) :

const char* ssid       = "SSID_de_votre_réseau";   //Replace with your own SSID
const char* password   = "Mot_de_passe_réseau";    //Replace with your own WiFi password

Après avoir paramétré cela, il vous reste à compiler, à télécharger et à essayer avec le terminal série à 9600 Bds. Le programme va s'initialiser, se connecter au WiFi, se mettre à l'heure sur un serveur NTP, récupérer les couleurs Tempo et les afficher.
Il vous tiendra au courant de tout ce qu'il fait sur la console. Si vous lui envoyez "-h" ou "%h", il vous indiquera la liste des commandes disponibles, que je vous invite à essayer.

Dans les commandes disponibles, il y a le %w qui donne les paramètres WiFi. Dans le lot d'informations retourné par la commande, il y a le nom de machine et les adresses MAC et IP. Notez tout cela quelque part, cela vous servira si vous décidez de passer à la version complétée (V04).

Si vous avez l'afficheur avec les 3 LEDs WS2812B, débranchez tout et raccordez le comme indiqué. Si le test précédent a fonctionné, les couleurs s'afficheront sur les trois LEDs :

  • première LED à gauche, qui reçoit le signal de l'ESP : couleur du jour,
  • deuxième LED (milieu) : couleur du lendemain,
  • troisième LED, la plus à droite : heures pleines.

Si la broche de commande ne vous convient pas, ou n'existe pas sur votre version d'ESP, vous pouvez en changer en modifiant la ligne suivante du programme principal :

  • sur ESP8266 :
const uint8_t C_LedPin = 12;   /* Pin D6 (GPIO12) on ESP8266 Wemos    */

-sur ESP32 :

 const uint8_t C_LedPin = 13;   /* GPIO pin 13 for WS2812B strip of 3 LEDs */

Une fois que vous aurez raccordé l'afficheur et démarré le système, il reste un petit test à faire : envoyez lui la commande "%T" avec le moniteur série. Il doit normalement vous allumer les trois LEDs en rouge, vert, bleu dans cet ordre en partant de la gauche (première LED raccordée).
Si ce n'est pas le cas, vous êtes tombés sur un fabricant de LED WS2812B facétieux qui a mis les couleurs des LEDs dans un ordre différent. Rien de grave, le cas est prévu dans la bibliothèque Adafruit_NeoPixel qui explique dans son .h quel paramètre il faut modifier pour y remédier.
Le test s'arrête automatiquement au bout de 30s. Vous pouvez y mettre fin manuellement avec un "%R".

Pour info, les versions que j'utilise :

  • IDE : 1.8.16,
  • ESP8266 : 2.7.4,
  • ESP32 : 3.1.0.
    Oui, je sais, ce sont loin d'être les plus récentes... ce qui ne veut pas dire que cela ne marchera pas avec des versions plus récentes.

La suite au prochain numéro...

3- Modules communs aux deux versions : KALED et LEDDisp

Outre son programme principal, chaque version contient trois modules de classe :

  • KALED qui gère le clignotement de la LED des ESP,
  • LEDDisp qui gère l'affichage sur les trois WS2812B,
  • et ColTpo qui gère l'acquisition des couleurs Tempo sur le site EdF.
    Voyons ce que contient et fait chaque module :

1- Le module KALED
Ce module gère le clignotement de la LED intégrée sur les ESP.
Pur gadget ?

Pas vraiment, surtout à la mise au point du programme. En effet, en fonctionnement normal, le système ne "travaille" que très peu de temps par 24h :

  • à 7h30 pour l'acquisition des couleurs,
  • à 22h00 pour l'extinction de la LED période pleine,
  • à 6h00 pour le basculement de la couleur du lendemain sur celle du jour, l'extinction de la couleur du lendemain et l'allumage des heures pleines.

Le reste du temps, il ne fait RIEN (ce n'est pas tout à fait vrai, voir plus loin...).

Le clignotement de la LED des l'ESP sert à vérifier qu'il n'est pas planté ou en reset continuel :

  • dans le init() la LED clignote plus ou moins rapidement,
  • une fois dans le loop(), elle doit clignoter bien régulièrement avec un petit flash de 50ms, suivi d'une extinction de 950ms et ainsi de suite.

Les fabricants de cartes ESP étant eux aussi facétieux, 50% raccordent la dite LED sur le GND et l'autre moitié sur le 3V3. Dans mon cas, la LED de l'ESP8266 est raccordée au GND et s'allume donc sur le niveau haut tandis que celle de mon ESP32 est raccordée au +3V3 et s'allume donc sur le niveau bas...
Si vous constatez une inversion du clignotement commentez ou décommentez suivant le cas, dans KALED.cpp, la ligne :

#define LEDONLOW true    /* Use when LED is active on low level */

Enfin, si vous ne voulez pas de cette LED clignotante, commentez la ligne suivante dans le programme principal et elle ne clignotera plus :

#define KALED 2           /* Keep alive LED on pin GPIO2 */

2- le module LEDDisp

Ce module gère l'affichage des LEDs. Il est construit sur l'excellente bibliothèque Adafruit_NeoPixel. J'avais fait un premier essai avec une autre bibliothèque, dont je tairai le nom par charité envers ses auteurs... une honte, elle ne compilait même pas !

Seule particularité à signaler : dans le .h de sa bibliothèque, Adafruit mentionne qu'elle utilise micros() et donc que son compteur 32 bits déborde toutes les 2^32 µs, c-à-d environ toutes les 70 minutes.
D'après les concepteurs de la bibliothèque, un problème peut se manifester quand il y a eu de multiples débordements du compteur 32 bits, ce qui est précisément le cas ici où le programme ne fait rien pendant des heures.
Pour éviter tout problème, j'ai mis en place un rafraichissement de l'affichage toutes les 20 minutes (ou plus souvent s'il y a du changement, bien sûr !).

Ces deux modules sont identiques sur ESP8266 et ESP32, au paramètrage du la KALED près (suivant nécessité).

La suite au prochain numéro...

4- Module d'extraction des couleurs ColTpo

C'est le module qui fait tout le travail d'extraction des couleurs... mais il ne travaille que quelques centaines de ms toutes les 24h ! Il existe en deux versions légèrement différentes pour ESP8266 et ESP32.

Dans les deux cas, c'est un module de classe qui comprend deux méthodes essentielles :

  • update() qui est un séquenceur qui déclenche les actions en fonction du timing décrit plus haut. Il doit être appelé à chaque tour de loop(). Le timing se fait en comptant les minutes par jour. La mise à jour se fait quotidiennement à 7h30. Vous pouvez modifier les heures de déclenchement en jouant sur les paramètres en début de module.
  • getColor() qui est le module qui fait l'acquisition des couleurs sur le site.

Voyons getColor() plus en détail. Il comporte quatre étapes :
1- la récupération des informations sur le site EdF ("www.services-rte.com") en https,
2- l'extraction du json,
3- la désérialisation du json,
4- le formatage des informations.

1- Récupération des informations sur le site EdF. C'est le seul endroit où les programmes pour ESP8266 et ESP32 sont différents.

a- Récupération des informations sur ESP32
L'ESP32 sait faire du https sans autre forme de procès. C'est donc ce que l'on fait. C'est tout simple et ça marche parfaitement, merci J-M-L.

b- Récupération des informations sur ESP8266
L'ESP8266 ne sait pas faire de https en une fois. Il faut gérer manuellement l'empreinte et sa comparaison avec les empreintes déposées sur la cascade de sites de référence, avec les certificats et tout le toutim... Pas vraiment simple, alors comme le but de la manip est de LIRE une information par ailleurs PUBLIQUE et sans criticité, j'ai opté pour le https "simplifié", c-à-d sans la vérification d'authenticité du site.
C'est sans risque ici (sauf de récupérer une couleur Tempo fausse ?), mais surtout, ne faites pas cela pour communiquer des informations à un site !

2- Extraction du json
Le site retourne une chaîne avec 2 json imbriqués. La doc indique que la bibliothèque ArduinoJson sait faire. Je dois avouer n'y être point arrivé.
J'ai donc opté pour une extraction "à-la-papa" avec les bonnes vieilles C-strings, simples et très efficaces :

  • récupération de l'adresse de la C-string interne à l'objet String,
  • copie dans une zone de mémoire dynamique où on pourra la modifier, car il ne faut surtout pas modifier la C-string interne d'un objet String, sauf à vouloir tout planter,
  • positionnement du pointeur de début sur le début de la 2ième chaîne json,
  • effacement du dernier caractère.
    Le tour est joué en moins de temps qu'il ne faut pour l'écrire, mais il ne faut surtout pas oublier de libérer la copie en mémoire dynamique avant de quitter la routine, sous peine de provoquer une magnifique "fuite de mémoire" avec au bout du compte un plantage vicieux difficile à trouver...

3- Désérialisation du json avec la bibliothèque ArduinoJson
La bibliothèque fonctionne parfaitement et décortique le json pour retourner les couleurs Tempo du jour et du lendemain sous forme de texte.

4- dernière opération : le formatage des informations.
ArduinoJson retourne du texte que l'on convertit tranquilou en valeur numérique en le comparant, encore ici "à-la-papa", avec les valeurs possibles stockées en mémoire programme (PMEM), et le tour est joué.

Notes :
1- la date textuelle dont on a besoin pour décortiquer le json est fournie facilement par les routines de la bibliothèque standard time.h.

2- j'ai truffé le module de yield(). Les ESP intègrent un mini système d'exploitation temps réel, qui gère entre autres le WiFi et toutes les communications, entre les tours de la loop(). Le yield() rend la main au "background", pour que celui-ci puisse effectuer les tâches en attente. C'est utile quand on a des opérations qui peuvent prendre du temps, comme le contact à des sites ou la désérialisation json. Cela ne peut de toutes façons pas nuire...

La suite au prochain épisode...

5- Description des versions complétées (V04)

La version de base est parfaitement fonctionnelle, mais je n'ai pu résister à présenter également une version complétée qui comporte deux fonctionnalités fort pratiques, lorsque le produit de votre bidouille est dans un endroit pas trop facilement accessible...

1- La mise à jour OTA
Je ne présente plus cette fonctionnalité qui permet de téléverser un programme dans un ESP8266 ou ESP32 sans contact physique. Il faut simplement que PC et ESP soient chacun connectés au même réseau WiFi. C'est le module OTA qui s'en charge.
A noter qu'il n'est pas activé par défaut, mais doit être activé en appelant OTAActivate().
L'activation se fait explicitement pour ne pas charger inutilement le processeur et aussi par souci de sécurité pour ne pas laisser une faille béante...
Ici, l'OTA s'active par la commande "%o". A noter qu'une fois activé, il le reste...
Quand l'OTA est activé, votre machine apparaît dans le menu "Outils", rubrique "Port".
Pour télécharger, le mot de passe OTA vous sera demandé.
En revanche, le terminal série de l'IDE ne fonctionne pas... ce qui nous amène directement à la rubrique suivante.

2- Le serveur Telnet
Telnet ques acco ?
C'est un ancien protocole de communication Internet, parfaitement fonctionnel, mais non sécurisé. Cela signifie que vous pouvez l'utiliser sans crainte sur votre réseau privé (vous êtes protégé par le pare-feu de votre box) mais qu'il serait imprudent de l'utiliser sur Internet.
J'ai déjà publié cette approche ici

et je l'utilise depuis régulièrement dans mes bidouilles car elle permet d'accéder en lecture et en écriture au "terminal" de votre ESP sans avoir de contact physique avec lui.
Son coeur est une habile substitution de "Serial" par une instance d'une classe dérivée de "Stream". Tout cela est inspiré du projet WifiTerm de Bricoleau à qui je rends ici... ce qui lui revient.
Pour utiliser ce serveur, il vous faut un client Telnet sur votre PC.

Le client Telnet

Pour accéder à la "liaison série" de votre ESP, il vous faudra vous connecter en Telnet sur votre ESP. Pour cela, il vous faut un client Telnet, qui dépend de la machine que vous utilisez.

1- Sur machine L Sur ces machines, le client Telnet est natif, il s'appelle "telnet" et il suffit de l'appeler depuis le terminal...

2- sur machine W
Sur machine W11 et probablement sur les dernières versions de W10, le client Telnet est aussi natif, mais il faut faire une manip très simple pour l'activer (une case à cocher). Pour la manip, posez la question à votre moteur de recherche préféré.
Alternativement, vous pouvez aussi utiliser l'excellent puTTY, qui lui va fonctionner sur toutes les versions de W, au moins jusqu'à l'ancestral XP inclus.

3- Sur machine A
N'en ayant pas, je ne peux être affirmatif, mais ces machines étant construites sur un Unix, je serais étonné qu'un client Telnet n'y figure pas. Je laisse aux afficionados de ces machines le soin de répondre.
</zone de prudence>

La suite au prochain épisode...

6- Mise en oeuvre des versions complétées (V04)

ColTpo_P04e.zip (24.5 KB)
ColTpo32_P04e.zip (24.5 KB)

Installation
Les versions V04 pour ESP8266 et ESP32 s'installent comme celles de la V03 après décompression dans un répertoire de votre arborescence Arduino portant le même nom que le programme principal.
Le programme principal (.ino) doit être configuré de manière similaire à la V03 avec le mot de passe protégeant l'activation de l'OTA en supplément :

const char* ssid       = "SSID_de_votre_réseau";   //Replace with your own SSID
const char* password   = "Mot_de_passe_réseau";    //Replace with your own WiFi password

const char* OTAPwd     = "Mot_de_passe_OTA";      //Replace with your own password

Après avoir paramétré cela, il vous reste à compiler, à télécharger classiquement en reliant l'ESP au PC.
Au lancement, le programme va s'initialiser, se connecter au WiFi, se mettre à l'heure sur un serveur NTP, récupérer les couleurs Tempo et les afficher si vous avez connecté les LEDs.
Par contre, vous ne verrez rien sur le terminal série, car tout est redirigé vers un serveur Telnet.

Pour vous connecter à votre ESP depuis votre PC, il suffit d'indiquer son adresse IP à votre client Telnet, par ex.

telnet aa.bb.cc.dd

aa.bb.cc.dd est l'adresse IP de votre ESP que vous avez noté un peu plus haut...
Normalement, l'ESP doit vous raconter tout ce qu'il a fait récemment. Vous pouvez aussi lui envoyer des commandes, exactement comme vous l'auriez fait avec le moniteur série de l'IDE.
Sympa, non ?

Si cela ne marche pas, vérifiez par un

ping aa.bb.cc.dd

que votre ESP est bien là avec la bonne adresse.
Si ce n'est pas le cas, passez directement à la suite...

Il reste encore une petite chose à faire : donner à votre ESP une adresse IP fixe pour que vous puissiez le retrouver à coup sûr. Pour cela, il vous faut ouvrir le mode administrateur de votre box. Ensuite cela dépend des boxes... mais ça y est à coup sûr.
Il vous faut d'abord repérer l'ESP dans la liste des clients de la box. L'adresse MAC que vous avez noté précédemment vous aidera car elle identifie l'ESP à coup sûr.
Ensuite, ce que vous cherchez c'est à donner un bail à IP fixe à durée indéterminée à la machine dont l'adresse MAC est celle que vous avez relevé plus haut. Les menus sont différents selon les boxes, mais elles ont toutes cette fonction. Vous pouvez vous aider par un tuto spécifique de votre box.
Choisissez une adresse IP libre sur votre sous-réseau, dans la zone DHCP. Validez. La box vous indiquera alors que le changement sera pris en compte au redémarrage de l'ESP, ce que vous ferez.
Vous pourrez alors vérifier par un ping sur la nouvelle adresse de l'ESP que le changement a été pris en compte.

Si vous ne voulez pas, ou ne pouvez pas donner une adresse IP fixe à l'ESP en demandant à la box de le faire, il y a aussi moyen de forcer l'ESP à prendre toujours la même adresse IP. Pour cela, il faut rajouter la ligne suivante dans le programme principal :

WiFi.config(OwnIP, Gateway, SubNetM, DNS1, DNS2);

avant

WiFi.begin(ssid, password);

Le prototype de la méthode config est :

bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000);

retourne TRUE si OK.
Bien entendu, il faut choisir une IP en dehors de la zone DHCP de la box...

Vous accéderez désormais toujours à votre ESP en Telnet sur sa nouvelle adresse, ce qu'il vous confirmera si vous lui envoyez un "%w".

Utilisation sans Telnet

Vous pouvez également configurer cette version sans le Telnet en commentant la ligne

#define TELNET_DEBUG_ACTIVATE "TelnetTerm.h"

dans le fichier Config.h.

La suite au prochain épisode...

7- Et maintenant...

Et maintenant, à vous de jouer, pour utiliser, mais surtout pour expérimenter et étendre, par exemple en rajoutant des délesteurs et tout ce que vous pourrez imaginer...

Bien entendu, j'essaierai de répondre à toute demande (raisonnable) d'explication...

Maintenant, je n'aurais plus qu'un mot : bonne bidouille à toutes et tous !