Dans le dernier épisode, nous avons réalisé, à l'aide du kit ESP32 DevKitC, d'une LED RGB et d'une photorésistance, un petit appareil qui mesure périodiquement la luminosité et l'envoie dans le nuage sur la plateforme AllThingsTalk. Celle-ci permet d'afficher ces données sous forme de page configurable. Pour que cela fonctionne, l'ESP32 doit d'abord se connecter sur le réseau Wi-Fi, puis, via TCP/IP et MQTT, établir la liaison avec le courtier MQTT AllThingsTalk. Si tout va bien, la LED RGB entame ses cycles d'allumage en vert avec extinction progressive. Toutes les deux secondes, un CAN échantillonne la luminosité et publie la valeur via MQTT. Les paramètres de configuration nécessaires (par ex. le SSID du réseau Wi-Fi) peuvent être configurés sur une page Web, que l'ESP32 met à disposition sur un site accessible via son propre réseau Wi-Fi.

Malgré tout, je ne me suis pas encore occupé du fait que la communication s'interrompt de temps en temps. Lors des essais du dernier épisode, j'ai en effet laissé l'appareil fonctionner une demi-journée entière, jusqu'à ce que la batterie d'alimentation soit vide (nous nous occuperons de réduire la consommation dans un épisode à venir). Et il pouvait se produire que la communication Wi-Fi s'interrompe sans que le programme ne le détecte. La LED verte effectuait toujours son cycle, mais évidemment, les mesures ne parvenaient plus chez AllThingsTalk. Piètre enregistreur de données, pourrait mieux faire !

L'ESP32 envoie ses pings

Lors de la publication d'un message MQTT, le courtier n'envoie aucun octet d'accusé de réception. Cela dit, MQTT offre bien un mécanisme de ping, pour déterminer si la communication MQTT est ouverte. J'ai donc d'abord introduit une instruction ping périodique vers le courtier AllThingsTalk dans mon croquis Arduino. Pour éviter un excès de trafic, le ping n'est envoyé que tous les cinq envois de mesure du capteur ; il suffit d'un petit compteur pour y parvenir. J'ai ajouté ce compteur et le ping au tout début, dans la partie de code de la boucle qui réalise la variation périodique de luminosité de la LED et appelle les fonctions MQTT. Si le ping ne reçoit pas de réponse, MQTTClient_Connected repasse de true (vrai) à false (faux), la valeur de cette variable au démarrage du programme. Ensuite, le croquis exécute la partie qui, dans ce cas, relance la communication avec le courtier. En fait, je n'ai pas changé grand chose, j'ai juste ajouté
 
RouterNetworkDeviceState = NETWORKSTATE_NOTLOGGED;

pour enregistrer l'échec de la communication. Je suppose en effet que c'est en réalité le réseau Wi-Fi qui est initialement défaillant si, à la suite du ping, on détecte que la communication MQTT ne fonctionne plus.
Maintenant, dans la boucle parcourue régulièrement, je devais rajouter un test sur
 
RouterNetworkDeviceState != NETWORKSTATE_LOGGED;

suivi d'une (nouvelle) tentative de connexion.

Quelques petites fonctions

Un test de ce genre doit maintenant être intégré dans le code à trois endroits différents : au début du programme dans la fonction Setup, après réception du formulaire de configuration rempli ainsi qu'après un échec du ping et l'échec de la tentative de reconnexion qui le suit. Cela m'a bien sûr poussé à écrire une fonction spécifique que j'ai baptisée LoginRouterNetworkAndSetRGB(). Toutefois, je n'appelle pas cette fonction directement depuis les trois endroits correspondant dans le croquis. À la place, j'ajoute
 
RouterNetworkDeviceState = NETWORKSTATE_NOTLOGGED;

pour changer l'état du réseau. La tentative de connexion ne s'effectue pas immédiatement, mais seulement au moment de la demande correspondante de la boucle. Afin de ne pas paralyser l'application avec d'incessantes tentatives de connexion, j'ai ajouté un autre petit compteur. Entre deux tentatives de connexion, il y a toujours un temps mort d'environ deux secondes. L'appel asynchrone de la fonction  LoginRouterNetworkAndSetRGB() présente maintenant l'avantage qu'après l'envoi du formulaire de configuration au serveur Web de l'ESP32, la tentative de connexion n'est pas immédiate et la nouvelle page Web est livrée plus vite (adresse 192.168.4.1, voir les épisodes précédents). Du même coup, nous traitons ici un petit défaut d'élégance. On obtient la réponse à l'adresse de l'ESP32 du réseau du routeur seulement si la tentative de connexion a réussi, la LED verte diminue d'intensité et ensuite on réappuie sur le bouton de soumission du formulaire.
Pour terminer, j'ai isolé la publication des mesures et la partie de code du serveur Web dans une fonction spécifique. De ce fait, la boucle est parfaitement claire et compacte, comme on peut le voir sur l'extrait d'écran.


 
Dans le croquis, on reconnaît les trois compteurs et l'affectation des deux variables d'état  MQTTClient_Connected et RouterNetworkDeviceState. La fonction Setup a aussi maigri (le nouveau croquis est bien sûr en téléchargement ; voir ci-dessous). Finalement, j'ai transformé ma petite bibliothèque Wi-Fi en bibliothèque de classe – un peu comme je l'ai fait dans le dernier épisode pour les fonctions TCP/IP et MQTT. Les fichiers WiFiNetwork.h/.c sont dans un dossier de même nom qui doit se trouver dans le dossier des bibliothèques Arduino lors de la compilation. J'ai retiré les données série des fonctions et je les ai intégrées dans le programme principal. À cet effet, j'ai créé la fonction  GetOwnIPAddressInRouterNetwork() laquelle retourne l'adresse de l'ESP32 dans le réseau du routeur. L'appel des fonctions du réseau Wi-Fi se fait désormais selon un code orienté objet : par exemple, la ligne
WiFi_SetBothModesNetworkStationAndAccessPoint();
est devenue
myWiFiNetwork.SetBothModesNetworkStationAndAccessPoint();

Ces modifications n'ajoutent aucune fonctionnalité au projet, et pourraient apparaître à certains comme une addiction à la programmation objet – mais nous profiterons de la modularité croissante du logiciel lorsque nous essaierons de nouvelles plateformes.

Compact et bon marché : kit ESP32 Pico

Vous pouvez essayer tout de suite le nouveau logiciel si vous êtes possesseur d'un ESP32DevKit C. On peut cependant le remplacer par un modèle encore plus petit : l'ESP32 Pico Kit, qui, en ce moment, est utilisé pour le concours de projets ESP32 2018 d'Elektor. La plus petite carte a l'avantage de laisser plus de place sur la plaque d'essai.



J'ai pu télécharger le croquis 1:1 sur la nouvelle carte ; je n'ai pas pu mettre de vraie différence en évidence. Seules les broches que j'utilise (barrettes à picots) ont changé de côté, ce qui ne pose aucun problème sur une plaque d'essai. J'ai branché la LED de test rouge sur la br. 15 au lieu de la br. 12 (et modifié le code en conséquence). Ah, j'oubliais : après une coupure temporaire d'alimentation, il faut actionner le bouton EN, sinon le programme ne démarre pas.

En service, on reconnaît le ping régulier à une courte interruption du cycle d'atténuation de la LED. Vous trouverez d'autres informations à la fin du dernier épisode. J'ai laissé le petit appareil fonctionner un jour entier et simulé la défaillance de la connexion Wi-Fi. Sur ma page du site AllThingsTalk, j'ai fait afficher sous forme d'un histogramme l'ensemble des mesures échantillonnées et publiées. Sur la capture d'écran du début de l'article, on voit bien que la luminosité ambiante de mon bureau perso diminue petit à petit. Vers 18 heures, on reconnaît une pointe : je venais d'allumer la lumière :-).

La suite au prochain épisode !