Cet article est terminé. Nous le trouvons dans le numéro d'été 2019 du magazine Programmer.
Il a aussi été publié un peu plus tard sur https://www.developpez.net/ et légèrement modifié après relectures et corrections.
Si vous avez des questions, des remarques ou du code source, vous pouvez me contacter:
Résumé
C'est un des gros articles que j'ai écrit après la sortie de mon dernier livre sur Java, Python et le Raspberry Pi 3, paru chez Eyrolles en Janvier 2019, mais le style est similaire avec beaucoup d'outils, de petits exemples et de schémas Fritzing.
Le NodeMCU ESP8266 a été choisi à cause de son prix modique. L'idée ensuite sera de passer sur l'ESP32, aussi en MicroPython.
Un Arduino standard n'a pas de Wi-Fi, au contraire des ESP8266 et ESP32, et le MicroPython est la solution idéale pour les makers désirant se familiariser avec le langage Python qui semble devenir, pour l'éducation, le langage officiel de programmation en France.
Nous y trouverons:
- l'installation du firmware MicroPython pour remplacer la version originale avec laquelle nous pouvons développer des applications avec l'IDE de l'Arduino;
- installation des outils comme PuTTY et Thonny;
- utilisation de l'IDE Thonny pour programmer en Python sur un PC ou en MicroPython sur l'ESP8266;
- schéma Fritzing pour une LED couleur à 4 branches et un LM35, un capteur de température;
- test de ces deux composants en MicroPython depuis le PC en mode REPL;
- installation des scripts Python sur le NodeMCU avec le réseau Wifi et un serveur Web pour recevoir la température;
- de nombreux trucs et astuces comme un application Java (PC ou Raspberry Pi) pour lire cette température ou encore comment remettre le firmware original de l'ESP8266.
----------------------------------------------------
Article complet: MicroPython pour le NodeMCU (ESP8266) avec Thonny
C'est l'article complet paru dans Programmez, numéro 231, Juillet - Août 2019, mais un peu remanié.
Introduction
La définition dans Wikipedia est parfaite : MicroPython est une implémentation écrite en C du langage Python, adapté au monde des microcontrôleurs. Son site Web officiel se trouve à l'adresse http://micropython.org/, mais https://docs.micropython.org/en/latest/ est plus complet. Thonny est un IDE pour débutant en Python et disponible sous Windows, Mac et Linux. C’est l’outil idéal pour les microcontrôleurs du type ESP8266 ou ESP32 avec un firmware MicroPython que nous allons installer ici pour le premier. Moi-même, sur mes Arduino, ESP8266 et ESP32, je n'ai jamais utilisé le langage de script LUA et toujours développé le logiciel avec l’IDE de l’Arduino.
Étant moi-même un fan et un inséparable de programmation Java, donc de programmation objet, je me suis aussi, avec le temps, familiarisé avec Python, le langage que j'ai utilisé pour vérifier mes composants attachés au GPIO du Raspberry Pi 3. Je cherchais aussi quelque chose de ludique simple, orienté éducation pour les débutants, pour mon NodeMCU, un ESP8266. C'est alors que j''ai découvert le MicroPython.
Je ne mentionnerai pas ici la carte piboard (http://micropython.fr/cartes_micropython/pyboard) déjà rencontrée en novembre 2018 dans Programmez. La piboard possède plus de broches GPIO et analogiques, vient préinstallée avec MicroPython, mais est nettement plus coûteuse. Pour les makers débutants, je recommanderais le NodeMCU avec lequel il est possible de le programmer à la manière Arduino, avec l’IDE de ce dernier, où il y a pléthore d’exemples sur le Web, et avant de passer à l'installation manuelle du firmware MicroPython. Le principe de développement et les outils sont similaires, cependant l'approche ludique de l'apprentissage de Python sur le PC me semble intéressante. De plus une carte PiBoard va bien coûter 10 fois plus cher qu’une solution NodeMCU.
Jouant moi-même depuis longtemps avec l'Arduino, aussi pour vérifier certains capteurs ou composants digitales que je déposais sur mes Raspberry Pi, il était naturel de passer au NodeMCU :
Le modèle présenté et utilisé ici vient du vendeur Ai-Thinker. Si un autre modèle était utilisé, il faudrait consulter le vendeur pour vérifier les différences voire le firmware version en cas de réinstallation.
C'est un Arduino simplifié, aussi meilleur marché, possédant une interface Wi-Fi et utilisant le même outil de développement IDE que celui de l'Arduino donc avec une connexion via un câble USB. Le NodeMCU, en bref, est une carte basée sur le microcontrôleur 8266 avec 10 broches GPIO et une seule analogique (A0).
Lorsqu'on attache au NodeMCU des composants comme des LEDs, des capteurs, voire des relais, l'outil pour les contrôler par logiciel est l'IDE de l'Arduino avec les langages C et C++ (fonctionnalités limitées). Pour les les débutants ou enseignants désirant apprendre les rudiments de la programmation, le langage Python est certainement plus approprié.
Un programmeur expérimenté devra aussi avoir des bases du langage C, évidemment, pour ensuite passer à du plus sérieux comme le C++ et améliorer son CV. Personnellement, je pencherais plus pour Java comme premier langage, mais ce dernier est simplement inapplicable sur un Arduino ou un ESP8266. Le langage Python, avec de nombreuses alternatives d'outils, étant disponible sur des plates-formes comme Windows, Linux ou encore le Raspberry Pi, ce sera un choix judicieux de remplacer le firmware d'un NodeMCU, donc d'un ESP8266, pour supporter et développer du logiciel en MicroPython, c'est à dire en Python 3. J’indiquerai encore que l’installation et l’utilisation du MicroPython sur un ESP32 est similaire.
Préparation de l’installation et utilisation des outils
Les procédures décrites ici sont pour Windows, mais c'est assez équivalent sous Linux puisque l'IDE de l’Arduino, le langage Python et d’autres outils comme Thonny existent aussi sous Linux et MacOS.
Pour pouvoir jouer avec le MicroPython, il faut commencer par remplacer le firmware installé d'usine sur le NodeMCU ESP8266, avant d'utiliser un IDE comme Thonny sur PC.
Le lecteur aura sans doute déjà pianoté avec l'Arduino IDE pour télécharger et tester des sketches. Nous y aurons découvert le COM utilisé ainsi que la dimension de la flash de 4 Moctets (le minimum est de 1 Moctets pour MicroPython, à surveiller, si on utilise d'autres types d’ESP8266).
Lors du branchement du câble USB sur le NodeMCU, il faudra utiliser Gérer dans l'explorateur de fichiers de Windows sous « Ce PC » pour découvrir quelque chose comme :
indiquant que le port COM4 est ici utilisé.
Si le port COM n'est pas identifiable, il faudrait envisager d'installer le driver USB depuis Silicon Lab à l'adresse https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers.
Installation du firmware
Avant de passer à l’installation de MicroPython, il faudra se rendre compte que le firmware original du NodeMCU sera écrasé. Nous ne pourrons donc plus utiliser l’IDE de l’Arduino pour développer des applications avec le firmware original qui sera remplacé par la version MicroPython. Si nous désirons revenir au NodeMCU d’usine, il faudra utiliser par exemple ESP8266Flasher.exe pour Windows 64-bit qui se trouve à l’adresse https://github.com/nodemcu/nodemcu-flasher/tree/master/Win64/Release. C’est un exécutable qui ne nécessite aucune modification dans les options : il suffira d’indiquer le COM qui est facilement identifiable après la connexion avec le câble USB. J’ai fait moi‑même la vérification et ensuite un test à partir de l’IDE de l’Arduino avec un sketch rudimentaire contenant juste un print() et un delay() dans la boucle loop traditionnelle. Pour ceux qui veulent faire cet exercice, ils prendront la dernière version binaire de l’IDE sur https://www.arduino.cc/en/Main/Software et il faudra spécifier l’URL de téléchargement https://github.com/esp8266/Arduino/releases/download/2.3.0/package_esp8266com_index.json dans les préférences et ajouter le bon gestionnaire de carte, NodeMCU 1.0 (ESP-12E Module), sous Outils, Type de carte. Pour un autre vendeur d’ESP8266 (ici c’est Ai‑Thinker), il faudrait considérer l’outil esptool.py avec read_flash pour reprendre le firmware d’origine: il faudra donner les bons paramètres.
Pour les makers utilisant Linux ou un autre type d’ESP8266, il faudra se retourner sur l’outil esptool.py et consulter le site https://nodemcu.readthedocs.io/en/master/flash/. Nous y trouverons la description de la commande avec write_flash.
Le téléchargement du firmware se faisant avec un script Python, ainsi que les outils qui suivront, nous aurons besoin d'installer préalablement le langage Python sur le PC. Moi‑même j'ai eu quelques difficultés avec mes versions de Python 2 et 3, c'est pourquoi je donnerai ici, à chaque fois, le chemin complet de l'installation lors de l'exécution de scripts.
Pour cette installation, je n'ai pas considéré la version de Python qui vient installée avec Thonny, mais la version standard que j’utilisais déjà avec d'autres outils, comme Eclipse sous PyDev, une extension tiers (http://www.pydev.org/ et pour mon article dans Programmez de février 2019 (no.226)) où j'avais besoin d'une installation traditionnelle.
Nous trouverons sur https://www.python.org/downloads/ le fichier d'installation de Python, la version 3, nommé « Windows x86 executable installer » et nous choisirons l'option « Customize installation » avec tous les « Features » pour le positionner par exemple dans le répertoire D:\Python37-32. Il m’est aussi arrivé de devoir faire une réparation (Repair), dans le même répertoire, après avoir remarqué que python.exe ne voulait plus s’exécuter.
Dans un nouveau répertoire D:\Python37-32\esptool-master, nous irons télécharger les outils et les dézipper depuis https://github.com/espressif/esptool (avec le bouton « Clone or Download » suivi de « Download zip ») ainsi que le firmware de MicroPython, esp8266-20190125-v1.10.bin, depuis le site http://micropython.org/download, qui est la version disponible au moment de l’écriture de cet article. Le fichier esptool-master.zip n’a pas de date et attention de bien prendre la version 8266 du firmware et non celle du 32, c’est à dire de la puce ESP-32.
Pour pouvoir communiquer en Python avec le port série de l’USB, il faudra installer le module pySerial. Si nous ne le savons pas, pas de soucis, en se positionnant sur le disque D:, dans mon cas, et dans une console CMD de Windows :
D:
D:\>cd Python37-32
D:\Python37-32>python.exe -m pip install pyserial
qui nous indiquera par exemple :
D:\Python37-32>python.exe -m pip install pyserial
Requirement already satisfied: pyserial in d:\python37-32\lib\site-packages (3.4)
que c’est déjà installé.
Sur certains sites Web, nous pourrions trouver une référence à l’effacement de la flash voir même en tenant pressé le bouton FLASH sur le NodeMCU :
D :
CD D:\Python37-32\esptool-master
D:\Python37-32\python.exe esptool.py --chip esp8266 erase_flash
Cette procédure n’a pas été nécessaire sur mon modèle.
Pour l’écriture du firmware, c’est à dire du fichier esp8266-20190125-v1.10.bin, certains sites indique cette commande :
esptool.py --port COM5 write_flash 0x00000 esp8266-20190125-v1.10.bin
Dans mon cas, pour ma variante de NodeMCU, j’ai utilisé :
esptool.py --port COM5 --baud 115000 write_flash --flash_size=detect -fm dio 0 esp8266-20190125-v1.10.bin
Si notre NodeMCU connecté vient d’être utilisé, il faudra reconnecté le câble USB. J’ai eu un cas, après avoir laissé mes platines de démonstration branchées, de devoir reflasher le firmware en tenant le bouton FLASH pressé durant le transfert.
Donc après avoir identifié le COM4 depuis Windows, utiliser une vitesse raisonnable (115000) voire créer une commande flash.cmd avec une PAUSE en dernier :
D :
CD D:\Python37-32\esptool-master
D:\Python37-32\esptool-master>D:\Python37-32\python.exe esptool.py --port COM4 --baud 115000 write_flash --flash_size=detect -fm dio 0 esp8266-20190125-v1.10.bin
esptool.py v2.7-dev
Serial port COM4
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: Wi-Fi
MAC: 5c:cf:7f:00:d6:51
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0240
Compressed 615388 bytes to 399928...
Wrote 615388 bytes (399928 compressed) at 0x00000000 in 35.4 seconds (effective 139.0 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
Nous allons à présent indiquer comment vérifier l’installation du firmware.
Vérification de notre NodeMCU avec MicroPython
La première vérification se fera avec PuTTY avant d’utiliser Thonny l’outil IDE pour Python et MicroPython.
Installation de PuTTY et REPL
Il n'est pas essentiel d'utiliser PuTTY pour tester nos premiers scripts. Nous pourrions passer directement à Thonny, l'IDE parfait pour le MicroPython. Pour les bricoleurs comme moi, jouant par exemple avec des Raspberry Pi, un robot Lego EV3 ou d'autres plates-formes à micro-contrôleur, PuTTY devrait déjà être installé sous Windows. PuTTY est une application client SSH et telnet que l'on peut aussi utiliser sur un port série COM.
Une alternative à PuTTY c’est par exemple Tera Term (https://osdn.net/projects/ttssh2/releases/). Si le lecteur le connaît déjà, il peut l’utiliser et sans passer par l’installation de PuTTY. Il ne devra pas oublier de spécifier la vitesse avec le menu Setup / Serial port… et ceci après la connexion sur le COM du NodeMCU ESP8266 déjà branché avec le câble USB.
Nous pourrons télécharger PuTTY depuis le site http://www.putty.org/ et nous choisirons la version 64 bits installable avec l’extension .msi.
La fenêtre de l'application PuTTY nous permettra d'entrer le port série (bouton à cocher « Serial ») et la vitesse de 115200 définie par le firmware :
Il est important d’ajuster le Flow Control à None. Dans cette fenêtre, nous irons sous Category, Connection et Serial pour le modifier.
Pour une prochaine utilisation, et c'est vraiment pratique, nous sauverons la session avec un nom prédéfini, comme par exemple NodeMCU COM4.
Avec le bouton « Open » nous devrions voir cette fenêtre avec l'invite du MicroPython en ligne de commande REPL, c'est à dire >>>.
Elle apparaîtra après l'envoi de la touche Retour sur le clavier et positionné dans la fenêtre de PuTTY :
REPL signifie Read Evaluate Print Loop. Il s'agit du nom donné à l'invite interactive du MicroPython. Utiliser le REPL est de loin le moyen le plus simple de tester du code simple et d’exécuter des commandes.
Nous allons commencer par entrer les deux commandes Python suivantes (un Ctrl-C sur une sélection suivi d'un clic du bouton droite de la souris, permet un copier/coller une sélection d’ailleurs dans la fenêtre de PuTTY) :
import sys
print(sys.platform+ " " + sys.version)
qui seront ainsi interprétés en mode REPL :
>>> import sys
>>> print(sys.platform+ " " + sys.version)
esp8266 3.4.0
La version est bien 3.4.0, celle de notre MicroPython, qui vient d'une réécriture complète de la version 3.4 du langage Python. Pour l’installation et l’utilisation de Thonny qui va suivre, il faudra préalablement fermer la session PuTTY, et ensuite sortir et rebrancher le câble USB.
Installation de Thonny
J'ai choisi l'IDE Thonny sous Windows qui permet le développement d'applications en Python et MicroPython depuis le PC et avec un câble USB connecté à notre NodeMCU.
Une alternative à Thonny, c'est uPyCraft: https://randomnerdtutorials.com/install-upycraft-ide-windows-pc-instructions/. Nous noterons le site https://randomnerdtutorials.com que je conseille au lecteur de suivre régulièrement ou de s'abonner. Rui Santos fait un travail extraordinaire pour de nombreux projets Arduino, ESP8266 ou ESP32. Il a aussi été pour moi une source d'information pour écrire cet article et certains sujets de mon dernier livre dédié au Raspberry Pi 3 avec Python et Java.
Sur le site Web de Thonny, https://thonny.org/, au moment de l'écriture de cet article, j'y ai trouvé la version 3.1.2 (thonny-3.1.2.exe). Comme j'avais déjà installé Thonny, il me demande juste de mettre mon ancienne version à jour sur D:\Thonny (j'utilise le disque D : pour ne pas surcharger mon disque SSD C:).
Nous commencerons par créer un fichier test1.py avec les deux instructions que nous connaissons déjà :
Je l'ai mis ici volontairement dans Notepad++ (https://notepad-plus-plus.org/fr/), car j'adore sa colorisation syntaxique et je l'utilise souvent avant de déposer mes scripts Python sur mes Raspberry Pi, scripts qui ne nécessitent souvent pas de tests sur le PC au travers d’un interpréteur Python à installer.
Ayant créé ce premier script Python, nous pouvons à présent l'ouvrir dans Thonny et l'exécuter avec le bouton fléché circulaire Run, coloré vert (ou F5) :
Le premier message indique que l’interpréteur est celui empaqueté avec Thonny. Nous pourrons l'identifier avec le menu Tools, Options et Interpreter :
Nous passerons rapidement à notre NodeMCU ESP8266, qui est déjà connecté avec un câble USB, un changeant le mode en « generic device » avec le même menu Tools, Options et Interpreter :
Nous remarquons que le COM4 a été assigné par Windows. Comme ci-dessus, nous utiliserons à nouveau le bouton Run coloré vert (ou F5) :
Nous sommes cette fois-ci sur notre NodeMCU ESP8366. Nous avons la même réponse que précédemment en mode REPL sous PuTTY. Magnifique !
Déposer des composants sur notre NodeMCU
Avant de pouvoir programmer nos premiers scripts Python, il nous faut préparer nos plaques de prototypage avec quelques capteurs et composants.
Une LED à 4 branches et un LM35
Une LED à 4 branches, c'est une LED couleur où les trois couleurs RVB peuvent être activées séparément.
Ce sera un excellent sujet pour de premiers exercices en Python.
Nous devons tout d'abord présenter la disposition des pins sur le NodeMCU :
ainsi que le diagramme Fritzing (http://fritzing.org/home/) de notre LED où chaque broche, correspondant à une couleur RGB différente, doit être protégée, pour limiter le courant, par une résistance de 220 Ohm, valeur que nous trouvons dans les kits et correcte pour cette tension de 3.3Volt et ce composant LED :
Nous y avons aussi ajouté un capteur de température LM35 sur l'unique broche analogique du NodeMCU. En plaçant le NodeMCU juste entre deux petites plaques de prototypage, il tiendra bien, et nous aurons d'un côté la partie analogique et de l'autre la digitale. Pour la couleurs des fils de la LED RGB, nous avons utilisé ici sur ce schéma la couleur qui sera activée sur la LED. La broche D0, en haut à droite, va correspondre au GPIO16, c'est à dire à la couleur rouge. J’ai ajouté ces descriptions de couleurs dans les scripts Python qui suivront. Nous mettrons en série trois résistances de 220 Ohm avant chaque broche correspondante à une couleur. La broche la plus longue est celle associée à la terre.
Test de nos deux composants depuis Thonny
Nous commencerons par tester les deux composants depuis Thonny avec deux scripts des plus dépouillés, mais aussi lisibles que possible.
Le plus facile et direct ici est de démarrer Thonny avec le NodeMCU déjà connecté et avec le mode en « generic device » (Menu : Tools, Option, Interpreter) sur le COM déjà détecté.
Dans le fichier test2.py nous déposerons le script Python suivant :
from machine import Pin
from time import sleep
ledblue = Pin(16, Pin.OUT) #bleu
ledgreen = Pin(5, Pin.OUT) #vert
ledred = Pin(4, Pin.OUT) #rouge
ledred.value(0)
ledgreen.value(0)
ledblue.value(0)
while True:
ledgreen.value(not ledgreen.value())
sleep(1.0)
Nous montrons à nouveau l’exécution dans Thonny avec le bouton Run coloré vert (ou F5) :
Ici, il n’y a pas de message dans la partie Shell de Thonny, car aucune instruction print() ne sont présentes dans le script.
Après l’assignation des broches (voir le diagramme ci-dessus, où par exemple la broche D0 correspond au GPIO16 et la couleur bleu) nous déposons 3 valeurs 0 sur chacune. Aucune couleur ne sera donc activée.
Dans la boucle while le not de l’instruction value() est particulier et génial. Chaque seconde, la valeur de la couleur rouge sera inversée. Donc, au premier passage, la LED sera allumée en rouge pour 1 seconde. Avant la boucle while nous pourrions activer la partie bleue et la laisser ainsi, donc avec ledblue.value(1). Lorsque la broche rouge sera inactive, chaque seconde après une seconde, la LED sera bleue, sinon le bleu et le rouge se mélangerons.
En ajoutant le code qui suit qui contient quelques pauses en secondes (sleep(sec)), et avant les trois value(0), et comme ceci :
sleep(1.0)
ledblue.value(0)
sleep(2.0)
ledboard = Pin(2, Pin.OUT)
ledboard.value(0)
sleep(3.0)
nous comprendrons que (nous retirerons et remettrons le câble USB pour s’assurer du bon état des broches au démarrage) :
• la LED couleur sera bleue, car le GPIO16 sera 1 au démarrage par défaut ;
• après une seconde la LED s’éteint, mais une LED bleue sur le NodeMCU s’allume (près du câble USB) (elle est mise en circuit inversé par rapport à D0, le GPIO 16) ;
• après 2 autres secondes, une autre LED bleue sur l’ESP8266, à côté du D0, associée au GPIO02 (D4) s’allume (ledboard.value(0) : valeur inversée comme D0. Par défaut au démarrage le D4 (pas utilisé ici) est à 1 ;
• lorsque le code initial est actif avec la LED clignotant en rouge, les deux LEDs bleues sur la carte resteront allumée.
Il est donc possible d’utiliser les deux LEDS de la carte pour indiquer à l’utilisateur des états d’activité du logiciel. Ce dernier devrait donc éviter d’utiliser D0 et D4 pour des composants intégrés sur les platines de développement.
La manipulation du bouton STOP dans Thonny, pour arrêter l’exécution n’est pas évidente, comme d’ailleurs le Save (Ctrl-S) dans le menu qu’il faut parfois cliquer deux fois pour fonctionner après des corrections de code. Suivant les situations, il faudra parfois retirer le câble et le remettre, voire relancer Thonny. Par contre charger un autre script et l’exécuter sans stopper l’actuel semble bien fonctionner.
Nous pouvons facilement nous imaginer le nombre d’exercice possible en Python, voir avec la librairie PWM (modulation de largeur d’impulsion) comme ici :
from machine import Pin, PWM
import timefrom machine
import Pin from time import sleep
ledblue = Pin(16, Pin.OUT) #bleu
ledgreen = Pin(5, Pin.OUT) #vert
ledred = Pin(4, Pin.OUT) #rouge
ledred.value(0)
ledgreen.value(0)
ledblue.value(0)
pwm = PWM(Pin(4))
for level in range(0, 1023):
time.sleep(.01)
pwm.duty(level)
Le PWM n’est pas disponible sur la broche D0 (GPIO 16) : il faudrait alors faire passer le bleu de la broche D0 à la broche D3 (GPIO 0) par exemple. Cet exemple nous montre notre LED couleur mise au rouge (1013 pour le maximum) qui se fane rapidement jusqu’à s’éteindre (pwm.duty(0)).
Comme pour le script test1.py et les suivants, tous ces scripts ne sont pas téléchargés dans le NodeMCU et il faudra les exécuter à chaque fois. Mais cela permet de les vérifier, d’y ajouter plus de code, d’autres fonctions ou modules, avant une installation pour un démarrage automatique au boot de l’ESP8266, c’est à dire dans le fichier main.py. Nous y viendrons rapidement !
Le script ci-dessus sera vraisemblablement déposé dans un fichier et chargé dans Thonny. Mais un copier/coller dans la fenêtre Shell de ce dernier est tout à fait possible : le code devrait cependant rester simple et une exécution ligne par ligne est recommandée.
Le prochain composant à vérifier, c’est le capteur de température, un LM35.
from machine import ADC
adc = ADC(0) #assigne la broche analogique
def temperature():
value = adc.read()
return value/3.95
celsius_temp = temperature()
print(celsius_temp)
Le def n’est pas vraiment nécessaire, peut-être juste pour montrer au lecteur que l’auteur de cet article sait un petit peu comment écrire une fonction en Python !
Le 3.95 a été défini, après calibration, en déposant un thermomètre à côté de notre platine de prototypage et en vérifiant le résultat. Avec deux doigts sur le LM35, nous pouvons rapidement vérifier que le température augmente ou diminue, mais évidemment pas déterminer si nous sommes fiévreux !
Le 22 degrés est une température juste confortable pour travailler et les chiffres après la virgule pourraient être ignorés, ou mieux, arrondis à une décimal avec la fonction round(celsius_temp, 1). J’ajouterai encore quand déconnectant la platine de démonstration contenant le LM35, j’ai noté une valeur de 2 à la lecture. Un LM35 mal branché pourra aussi être vérifié en le pinçant de deux doigts pour y faire monter la température.
Un script plus sérieux et déposé dans le NodeMCU
Nous allons à présent considérer les aspects suivants :
• intégrer le code des scripts précédents, test2.py et lm35.py pour y faire quelque chose de plus intelligent ;
• ajouter le code nécessaire pour attribuer une adresse IP à notre NodeMCU ;
• y ajouter un serveur Web pour obtenir la température de l’extérieur.
Les trois composants seront vérifiés comme précédemment, et toujours sans télécharger les scripts pour qu’ils soient disponibles au prochain démarrage du NodeMCU.
Trois couleurs différentes suivant la température
Nous présentons le script ControlTemperature.py, que nous préparerons sous Thonny, suivi de quelques explications :
from machine import Pin
from machine import ADC
from time import sleep
ledblue = Pin(16, Pin.OUT) #bleu
ledgreen = Pin(5, Pin.OUT) #vert
ledred = Pin(4, Pin.OUT) #rouge
adc = ADC(0) #LM35 sur l'analogique 0
ledgreen.value(0)
ledblue.value(0)
ledblue.value(1)
sleep(.3)
ledblue.value(0)
ledgreen.value(1)
sleep(.3)
ledgreen.value(0)
ledred.value(1)
sleep(.3)
ledred.value(0)
sleep(1)
while True:
reading = adc.read()
celsius_temp = round(reading/3.95, 1)
print(celsius_temp)
ledgreen.value(0)
ledblue.value(0)
ledred.value(0)
if (celsius_temp) > 24.0:
ledred.value(1)
else:
if (celsius_temp) < 22.0:
ledblue.value(1)
else:
ledgreen.value(1)
sleep(2.0)
Rien de bien sorcier. C’est une composition des scripts précédents avec la lecture de la température. Chaque deux secondes nous coupons la tension GPIO de toutes les broches, pour ne pas mélanger les couleurs, et nous attribuons une couleur dépendante de la température :
• bleu si en dessous 22 degrés ;
• rouge si supérieure à 24 degrés ;
• vert, entre les deux, c’est confortable.
Comme il n’y a ici qu’un seul print(), c’est la seule chose que nous verrons dans le shell de Thonny en l’exécutant, c’est à dire la température en degré Celsius avec une décimale. Nous verrons la LED avec la couleur correcte, couleur qu’il nous est facile de faire passer au rouge avec deux doigts sur le LM35. La mise à jour se fera chaque seconde, c’est suffisant.
Avant de passer au transfert de fichiers MicroPython sur le NodeMCU et en particulier aux boot.py et main.py qui seront exécutés à chaque démarrage, il nous faut revenir un peu au mode REPL et à la configuration Wi-Fi.
Configuration Wi-Fi
Notre application finale, qui aura besoin d’un accès réseau pour transmettre en particulier la température récupérée par un LM35, va nécessiter préalablement la mise en place de sa configuration réseau.
Cette configuration et sa vérification peut très bien être faite du Shell de Thonny voire aussi de PuTTY. Nous noterons ici que le Shell de Thonny permet de copier/coller (Ctrl-C/Ctrl-V) depuis une autre fenêtre Windows et aussi de naviguer sur d’anciennes commandes avec les touches curseur.
import network
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
print('network config:', sta_if.ifconfig())
Il faudra un peu patienter avant de voir la réponse avec l’adresse IP activée (entre temps un 0.0.0.0 serait retourné) :
>>> print('network config:', sta_if.ifconfig())
network config: ('192.168.1.138', '255.255.255.0', '192.168.1.1', '192.168.1.1')
Dans mon cas, j’ai attribué, dans mon routeur Wi-Fi, 192.168.1.138 comme adresse IP statique.
Il serait ensuite possible avec sta_if.active(False) de désactiver l’adresse IP et de, par exemple, nous déplacer dans un autre réseau Wi-Fi ou routeur, en refaisant la même procédure.
Notre application main.py
Thonny nous permet de télécharger des fichiers et des scripts Python sur notre NodeMCU installé avec MicroPython. Ceci se fait avec le menu Device et un des trois sous-menus Upload. Nous commencerons par le premier script décrit ici, le fichier test1.py et ensuite avec main.py et boot.py.
Le main.py est le fichier qui contiendra le code de notre application et qui sera lancé lors de la mise sous tension, s'il existe, et après le script boot.py. Nous déposerons dans ce dernier le code pour initialiser le réseau Wi-Fi.
Nous allons à présent examiner comme accéder le système de fichiers du NodeMCU voire de le modifier. Ayant déposé, avec le menu correspondant de Thonny, le fichier test1.py sur notre NodeMCU, nous pourrons avec le Shell de Python, exécuter les commandes suivantes:
import os
os.listdir()
print(open('test1.py').read())
os.remove('test1.py')
os.listdir()
Typiquement nous devrions retrouver pour la dernière instruction, et plus tard après l'installation des main.py et boot.py qui vont suivre, le résultat de la dernière commande :
>>> os.listdir()
['boot.py', 'main.py']
Précédemment, le read() nous aura montré le contenu de test1.py. La commande remove() effacera le test1.py.
Notre application main.py présentée maintenant est composée des fonctions discutées précédemment:
• test de notre LED ;
• lecture de la température ;
• couleur de la LED en fonction de cette dernière
et nous y ajoutons un serveur Web pour obtenir cette température de l'extérieur.
from machine import Pin
from machine import ADC
from time import sleep
import socket
#import machine
html = """
Temperature
%s
"""
celsius_temp = 10.0
ledblue = Pin(16, Pin.OUT) #bleu
ledgreen = Pin(5, Pin.OUT) #vert
ledred = Pin(4, Pin.OUT) #rouge
adc = ADC(0) #LM35 sur l'analogique 0
ledgreen.value(0)
ledblue.value(0)
ledblue.value(1)
sleep(.3)
ledblue.value(0)
ledgreen.value(1)
sleep(.3)
ledgreen.value(0)
ledred.value(1)
sleep(.3)
ledred.value(0)
sleep(1)
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
while True:
#print('Boucle ')
s.settimeout(2)
try:
conn, addr = s.accept()
except OSError as er:
pass
#print(er.args[0] in (110, 'timed out'))
# 110 is ETIMEDOUT
else:
#print('Client connecté de ', addr)
conn_file = conn.makefile('rwb', 0)
while True:
line = conn_file.readline()
#print('Line ', line)
if not line or line == b'\r\n':
break
response = html % celsius_temp + '\n'
#print('Client receives ', response)
conn.send('HTTP/1.1 200 OK\n')
conn.send('Content-Type: text/html\n')
conn.send('Connection: close\n\n')
conn.sendall(response)
conn.close()
conn.close()
reading = adc.read()
celsius_temp = round(reading/3.95, 1)
#print(celsius_temp)
ledgreen.value(0)
ledblue.value(0)
ledred.value(0)
if (celsius_temp) > 24.0:
ledred.value(1)
else:
if (celsius_temp) < 22.0:
ledblue.value(1)
else:
ledgreen.value(1)
Comme pour les scripts précédents, nous vérifierons le script de la même manière, depuis Thonny, et avant de le télécharger. Un certain nombre de print(), ici en commentaire, nous permettraient de vérifier le bon fonctionnement du script.
La variable html est typique d’une page Web vraiment simple, juste pour nous retourner la température où le %s sera remplacé par la valeur de celsius_temp qui sera de 10.0 degrés au démarrage et immédiatement corrigée après 2 secondes dans la boucle while True. Les deux secondes viennent du s.settimeout(2) sur le socket du port 80 (Web).
Le MicroPython de l’ESP8266 n’ayant pas de support Thread, c’est une manière de faire un peu simpliste, mais suffisante, pour cette application. Une requête http://192.168.1.138/ devra patienter jusqu’à 2 secondes avant de recevoir la dernière température. Au timeout la température sera mise à jour comme la couleur de la LED.
L’adresse IP 0.0.0.0 est une adresse réservée indiquant ce site et ce réseau. Avec 0.0.0.0 nous écouterons sur tous les réseaux d’interface configurés.
L’instruction s.accept() est assez particulière pour les débutants en Python, car elle nous retourne une paire de valeur, conn et adress, un tuple : le premier est la référence d'un nouvel objet de la classe socket(), qui sera la véritable interface de communication entre le client et le serveur, et le second un autre tuple contenant les coordonnées de ce client (son adresse IP et son numéro de port utilisé).
Dès qu’un client sur le port 80 demande un accès, nous lisons toute la requête en ignorant ici les paramètres. Si nous jouons, avec par exemple http://192.168.1.138/temperature, nous recevrons toujours la même réponse envoyée avec les différents conn.send() qui spécifient le protocole et la réponse. Le conn.sendall() est identique à conn.send() mais attend que tout soit envoyé. La send('Connection: close\n\n') est intéressante : elle indiquera que la connexion n’est pas persistante après l’envoi de la réponse : notre température « emballée » dans des balises HTML.
Il y aurait du travail pour implémenter le passage dans une requête Web pour nos deux limites de température, ici fixées à 22 et 24 degrés, pour les intégrer dans le script main.py voire stockées dans un fichier de configuration de l’ESP8266.
Notre script de démarrage boot.py
Nous déposerons le code réseau pour le Wi-Fi dans le fichier Python boot.py :
def do_connect():
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
print('connecting to network...')
sta_if.active(True)
sta_if.connect('routeur', 'mot_de_passe')
while not sta_if.isconnected():
pass
print('network config:', sta_if.ifconfig())
do_connect()
Nous le vérifierons tout d’abord avec le shell :
>>> %Run boot.py
network config: ('192.168.1.138', '255.255.255.0', '192.168.1.1', '192.168.1.1')
La fonction do_connect() devra être modifiée en y mettant le nom et le mot de passe du routeur. Comme je le fais pour mes composants IOT, après l’attribution de l’adresse IP, ici ce 192.168.1.138, j’utilise l’accès Web du routeur pour y attribuer le mode statique. Ce sera plus facile pour retrouver ce NodeMCU parmi une pléthore d’objets connectés.
La variable sta_if est utilisée avec la classe WLAN pour obtenir une connexion au routeur et en passant à la fonction connect() le SSID (le nom du réseau, le routeur) et son mot de passe.
Ensuite nous utiliserons le menu Device avec « Upload current script as boot script ». Le menu Device possède deux sous-menus pour visionner nos deux boot.py et main.py. Nous débrancherons et reconnecterons le câble USB pour vérifier l’installation, que la LED change de couleur en la touchant de deux doigts, et que la requête http://192.168.1.138/ nous retourne des valeurs différentes.
En cas de difficultés, nous pourrions toujours remettre quelques print() dans le code, voire utiliser PuTTY. Pour utiliser ce dernier, il faudra rebrancher le câble pour avoir une session correcte dans PuTTY. Un Ctrl-C dans sa console permettrait d’interrompre le script main.py, avec ces conséquences, et de retravailler en mode REPL. Le lecteur comprendra vite que notre Thonny est bien agréable à utiliser.
Enfin un peu de Java
Ma passion et mon attachement restant toujours la programmation Java, je n’ai pas hésité à écrire une petite classe Java pour récupérer la température de cet objet connecté qu’est notre NodeMCU :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
public class NodeMcuWebRead {
public static void main(String[] args) throws IOException {
URL url = new URL("http://192.168.1.138");
BufferedReader in = new BufferedReader(
new InputStreamReader(url.openStream()));
String inputLine;
float temperature = (float)0.0;
int lineNb = 0;
while ((inputLine = in.readLine()) != null) {
if (lineNb == 4) {
inputLine = inputLine.replaceAll("\\s+","");
temperature = Float.parseFloat(inputLine);
System.out.println(temperature);
break;
}
lineNb++;
}
in.close();
}
}
Ce code pourra être compilé et déposé sur n’importe quel PC ou système embarqué, comme un Raspberry Pi (avec Java 8), voire un NAS et là où une machine virtuelle Java est disponible et installée.
En utilisant un explorateur Internet à l’adresse http://192.168.1.138/ et en examinant le code source (bouton droite de la souris sous Chrome et Firefox) nous retrouverons notre température sur la 5-ième ligne du code HTML. Nous retirerons les espaces avant une conversion en float.
Nous pourrions par exemple étendre cette mini-classe en une classe lisant régulièrement la température pour :
• enregistrer la température chaque minute dans une table de base de données SQLite, aussi créée avec sa table dans cette même classe ;
• calculer les moyennes horaires et journalières et les déposer dans deux autres tables SQLite ;
• y ajouter d’autres NodeMCU pour des statistiques de températures mesurées à différents endroits de la maison, voire de l’extérieur ;
• développer un Web serveur en Java pour montrer ces informations sous différentes formes ;
• envoyer chaque jour ou semaine un courriel avec ces informations de statistique ;
• créer un système d’alarme pour indiquer un problème de température lié aux limites de température précédemment discutée et en permettant au NodeMCU d’accepter de nouvelles valeurs limites.
C'est parti pour l'apprentissage de Python
Ce n'est pas le but de cet article, mais nous voyons bien que nous avons ici une infrastructure idéale pour l'apprentissage du langage Python.
Nous pourrions commencer par des variables, qui pourraient par exemple représentées l'intensité d'une ou de plusieurs couleurs de la LED. Des tests de conditions suivant la valeur de la température, ou de petits jeux de variations d'intensité ou de couleurs, sont facile à imaginer et à développer sous Thonny.
En fonction des thèmes de l'apprentissage de Python, il serait alors facile de mettre en place une série d'exercices évolutifs, comme par exemple, l'implémentation, qui me semble incontournable, d'une classe Python, LedColor, contenant toutes les fonctionnalités sorties de notre imagination.
Apprendre Java et Python en parallèle
Dès que nous parlons de classe, ici de LedColor, il nous viendrait vite à l’esprit d’écrire aussi une jolie classe en Java, sous Eclipse, pour un Raspberry Pi, avec la même LED, mais un Dallas DS18B20 digital pour remplacer notre LM35 analogique, car le Pi n’a pas d’interface analogique.