MicroPython pour le NodeMCU (ESP8266) avec Thonny

Jean-Bernard Boichat

Cet article nous montre comment installer le firmware MicroPython sur le NodeMCU ESP8266, comment y développer des applications avec le langage MicroPython, et en accédant à des composants GPIO attachés à ce microcontrôleur, et ceci avec Thonny, un IDE étonnant pour Python.
Merci à f-leb et ClaudeLELOUP pour leur travail de relecture et les commentaires.

Commentez

- Titre : MicroPython pour le NodeMCU (ESP8266) avec Thonny

- Auteur : Jean-Bernard Boichat

- Parution : 22 août 2019

- Public visé :

- Licence : Le contenu de cet article est rédigé par Jean-Bernard Boichat et est mis à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2013 Developpez.com.

Sommaire

- I. Introduction

- II. Préparation de l’installation et utilisation des outils

- III. Installation du firmware

- IV. Vérification de notre NodeMCU avec MicroPython

- IV-A. Installation de PuTTY et REPL

- IV-B. Installation de Thonny

- V. Déposer des composants sur notre NodeMCU

- V-A. Une LED à quatre branches et un LM35

- VI. Test de nos deux composants depuis Thonny

- VII. Un script plus sérieux et déposé dans le NodeMCU

- VII-A. Trois couleurs différentes suivant la température

- VIII. Configuration Wi-Fi

- IX. Notre application main.py

- X. Notre script de démarrage boot.py

- XI. Enfin un peu de Java

- XII. C'est parti pour l'apprentissage de Python

- XIII. Apprendre Java et Python en parallèle

I - Introduction

La définition dans Wikipédia 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 (implanté par défaut dans le firmware des NodeMCU) 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 pyboard qui serait une autre possibilité. Elle 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 PyBoard va bien coûter dix fois plus cher qu’une solution NodeMCU.

Jouant moi-même depuis longtemps avec l'Arduino, aussi pour vérifier certains capteurs ou composants digitaux 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 module ESP8266 avec dix broches GPIO et une seule analogique (A0).

Lorsque nous attachons au NodeMCU des composants comme des LED, 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 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 nombreux 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 sont similaires.

II - Préparation de l’installation et utilisation des outils

Les procédures décrites ici dans cet article 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 installer le firmware associé 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 Moctet 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.

III - 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 bits 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/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 tierce (http://www.pydev.org/. J’ai d’ailleurs écrit un article ici sur ce sujet : PyDev, un IDE pour Python, sous Eclipse et pour le Raspberry Pi 3.)

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 savons rien de son installation, pas de souci, 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, voire en tenant pressé le bouton FLASH sur le NodeMCU :

D :
CD D:\Python37-32\esptool-masterD:\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 indiquent 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 reconnecter 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.

IV - 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.

IV-A - 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 à microcontrô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 solution de remplacement à 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, 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 droit 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.

IV-B - 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 autre possibilité, 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 test 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, en 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 !

V - 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.

V-A - Une LED à quatre branches et un LM35

Une LED à quatre 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 couleur 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.

VI - 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() n'est présente 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 trois 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 une 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élangeront.

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 deux 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 LED bleues sur la carte resteront allumées.

Il est donc possible d’utiliser les deux LED 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’exercices possibles en Python, voire avec la bibliothèque PWM (modulation de largeur d’impulsion) comme ici :

from machine import Pin, PWM
import time

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)

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 (1023 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 avec un thermomètre non calibré, à côté de notre platine de prototypage et en vérifiant le résultat. Un calibrage précis n’était pas important pour moi. 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écimale avec la fonction round(celsius_temp, 1). J’ajouterai encore qu'en 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.

VII - 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.

VII-A - 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. Toutes les 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és 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.

VIII - 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 (entretemps 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.

IX - 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 comment accéder au 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 = """<!DOCTYPE html>
<html>
<head><title>Temperature</title></head>
<body>
%s
</body>
</html>
"""

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 deux 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’à deux 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 valeurs, 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.

X - 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 sera 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 la console permettrait d’interrompre le script main.py, avec ses conséquences, et de retravailler en mode REPL. Le lecteur comprendra vite que notre Thonny est bien agréable à utiliser.

XI - 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 droit de la souris sous Chrome et Firefox) nous retrouverons notre température sur la 5e ligne du code HTML. Nous retirerons les espaces avant une conversion en float.

Nous pourrions par exemple étendre cette miniclasse 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.

XII - 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ésenter 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 faciles à 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 l'implémentation, qui me semble incontournable, d'une classe Python, LedColor, contenant toutes les fonctionnalités sorties de notre imagination.

XIII - 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. Voir l’excellent article de f-leb : La conversion analogique-numérique avec Raspberry Pi.