Introduction aux cartes ESP
Le port ESP (8266 et 32) est un des ports les plus développés pour Micropython (plus grand nombre de librairies, etc. )
La première chose à dire concernant les ESP 32 et 8266, c'est que c'est un "vrai bordel" : il y a plein de versions, de copies, etc... et il y a un peu (beaucoup ?) de quoi s'y perdre avec ces modèles. Ceci étant, ce sont des cartes qui ont un très bon support avec MicroPython, j'ai envie de dire que n'importe quel ESP 32 fera le job sur un projet. Même les modèles les plus "light" ou les plus "anciens" ont 2MB de Flash.
Les versions
Petite vue d'ensemble de cartes ESP :
Note
On appelle :
- module : le composant lui-même sous forme d'un micro-pcb : https://www.espressif.com/en/products/modules
- kit-dev : des cartes avec connecteurs pour exposer les broches du processeur. Plusieurs versions existent aux noms différents : https://www.espressif.com/en/products/devkits
Lequel choisir ?
Le point critique le plus important avec une carte Micropython est la quantité de RAM disponible. Premièrement, entre le 8266 et le ESP32, y'a pas photo : ESP32 (110Ko free RAM contre 40Ko Free RAM sur ESP 8266) !Ensuite, parmi les ESP32, la carte à privilégier est la carte ESP 32 WROVER qui dispose de plusieurs Mo de SPIRAM. Donc, si on n'a pas raison particulière de prendre un WROOM, un WROVER sera le mieux. La seule différence entre les 2 modèles sera quelques broches GPIO de moins, en raison de broches utilisées pour la communication avec la SPIRAM.
ESP 8266
Modèle le plus ancien mais qui est très peu cher et très répandu. Ne dispose que d'une voie analogique et d'une RAM limitée ce qui est vite un problème avec MicroPython, notamment si on veut faire des micro-serveurs embarqués.
ESP 32
La gamme est plutôt large... et décrite ici : https://en.wikipedia.org/wiki/ESP32
Voir également : https://www.espressif.com/en/products/socs/esp32/resources
Voici le brochage de l'ESP 32 WROOM "as is" au format module :
https://randomnerdtutorials.com/esp32-pinout-reference-gpios/
Voici le brochage d'un ESP 32 VROOM sur une carte de développement type (kit-dev) :
Ou bien :
Info
Il y a quelques variations selon le modèle, mais globalement on retrouve le même brochage. Par exemple ici, entre les 2 versions, il y a des différences sur les broches réservées qui ne sont pas forcément exposées.
Dispose de :
- une 15aine de GPIO
- d'autant de broches ADC en 12 bits (18 voies)
- 2 x DAC
- I2C, SPI
Page très bien faite ici : https://projetsdiy.fr/esp32-gpio-broches-fonctions-io-pwm-rtc-i2c-spi-adc-dac/
Comparaison ESP 8266 / ESP 32
Pour la faire simple, ESP 8266 c'est wifi mais pas de bluetoouth, une fréquence processeur moindre (84Mhz), une seule broche ADC en 10 bits. Concrètement, intéressant sur projets simples. On a I2C, SPI, etc.
ESP 32 : c'est wifi, bluetooth, frequence processeur à 240Mhz, plein de broches ADC (8) en 12 bits, DAC, capteur température et effet hall onboard, etc... bref, la totale. Un peu plus cher, mais bien plus polyvalent. On a SPI, I2C, etc en double.
En pratique : ESP8266 sur les projets où on n'a pas de gros besoins de mesure analogique, peu de besoins évolutifs. ESP32 pour tous les autres cas. Et si la différence de prix n'est pas significative, prendre ESP 32
Voici un comparatif entre les 2 modèles :
source : https://community.wia.io/d/53-esp8266-vs-esp32-what-s-the-difference
Autres liens utiles :
- https://www.electronicshub.org/esp32-vs-esp8266/
- https://circuits4you.com/2019/03/02/esp32-vs-esp8266/
Drivers CH3040
Les cartes ESP 32 vont utiliser pour communiquer un driver CH340 qui va fournir un port série au format ttyUSB0
sur Gnu/Linux.
Ces drivers sont directement présents sous Gnu/Linux. Mais doivent à priori être installés sous WIndows et Os X.
Flasher MicroPython
Pour cela on utilise un outil dédié écrit en python, esptool.py
et qui s'installe logiquement avec l'installateur python pip
:
sudo apt-get install python3-pip
sudo pip3 install esptool
Télécharger la version adaptée de MicroPython : https://micropython.org/download/esp32/ La version générique fonctionne que la carte dispose ou non de SRAM externe.
Note
Pour ce qui concerne le WROOVER avec de la SPiRAM, prendre la version avec SPIRAM.
Ensuite, on peut flasher facilement le firmware micropython
dans l'ESP 32. Ouvrir un terminal dans le répertoire où se trouve le binaire puis successivement :
- on efface la mémoire flash de la carte :
esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash
- on flashe micropython :
esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 esp32-20210416-unstable-v1.14-170-ga9bbf7083.bin
Une fois fait, on peut tester que tout est OK en se connectant avec un terminal série sur /dev/ttyUSB0
Avec Thonny par exemple, aller dans Tools > Options > Interpreter > sélectionner la bonne carte
Liens utiles
- Voir ici : https://projetsdiy.fr/reinstaller-firmware-micropython-esp8266-esp32/
- Flasher MicroPython sur une carte NodeMCU : https://icircuit.net/nodemcu-getting-started-micropython/2406 | https://icircuit.net/esp32-micropython-getting-started/1999
Discussion technique
Ici une version de Micropython pour ESP 32 qui est censée améliorer les possibilités : https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo/wiki
Connexion en Wifi
Une des caractéristiques intéressante des modules ESP, c'est de disposer de la connexion Wifi.
On a ici besoin d'un réseau wifi, que l'on peut utiliser sans sécurisation à des fins de tests, la sécurisation pouvant être faîte plus tard (il n'y a aucun danger particulier si de plus le réseau n'est pas connecté à internet). Dans l'exemple ici, on a un réseau wifi local dlink
public.
On commence par importer le module network
:
import network
Ensuite, on fait :
>>> import network
>>> station=network.WLAN(network.STA_IF)
>>> station.active(True)
True
>>> station.connect("dlink","")
>>> station.isconnected()
True
>>> station.ifconfig()
('192.168.0.101', '255.255.255.0', '192.168.0.1', '0.0.0.0')
Bah bah... tout ok en moins de 2 !
Lien : https://projetsdiy.fr/tutoriel-micropython-gerer-connexion-wifi/
Test de la réponse
Ensuite, il faut créer un socket qui va permettre de gérer la connexion (à faire une fois) :
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
Ensuite on gère la réception d'une connexion et la réponse à envoyer (code à boucler) :
s.accept()
#(<socket>, ('192.168.0.100', 51836))
conn,addr=s.accept()
print(conn)
#<socket>
print(addr)
#('192.168.0.100', 51844)
print(conn.recv(1024))
#b'GET / HTTP/1.1\r\nHost: 192.168.0.101\r\nUser-Agent: Mozilla/5.0 (X11; Linux i686; rv:78.0) Gecko/20100101 Firefox/78.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\nAccept-Language: fr,en-US;q=0.7,en;q=0.3\r\nAccept-Encoding: gzip, deflate\r\nDNT: 1\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nSec-GPC: 1\r\n\r\n'
conn.settimeout(None)
response="Hello !"
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()
Bref, on peut gérer assez simplement un petit serveur local et récupérer de la donnée sans fil. Vu que l'on est en wifi, un simple routeur de récup' fera l'affaire et on pourra avoir une portée non négligeable sans trop de problèmes.
Fonctions de base
GPIO
Il existe une LED onboard sur la GPIO 2 :
>>> from machine import Pin
>>> led=Pin(2,Pin.OUT)
>>> led.on()
>>> led.off()
Sur une brohce externe, çà donne :
from machine import Timer, Pin
led=Pin(15, Pin.OUT)
led.on()
led.offf()
PWM
from machine import PWM
pwm=PWM(Pin(15))
pwm.freq(1000)
pwm.duty(1000) # 0-1023
pwm.duty(100)
ADC
https://docs.micropython.org/en/latest/esp32/quickref.html#adc-analog-to-digital-conversion
La mesure analogique est disponible sur les broches 32 à 39 avec MicroPython (noté que l'ESP fournit bien plus de broches ADC que çà...), mais 8 broches ADC, c'est déjà pas mal. Les broches sont en 12 bits (par défaut) configurables. La mesure est renvoyée sur une échelle 0-4095 (=12 bits).
Point particulier : les broches disposent d'un atténuateur / amplificateur de niveau de tension. Par défaut, à 0dB, la mesure se fait sur 0-1V (et pas 3.3V !!). Pour avoir l'échelle en 3.3V, il faut utiliser l'amplification 11dB.
Le constructeur ADC se base sur une broche Pin(xx) où xx est le numéro de la broche GPxx utilisée.
>>> from machine import ADC, Pin
>>> sensor=ADC(Pin(32))
>>> sensor.read() # echelle 0-1v par defaut
0
>>> sensor.read()
3919
>>> sensor.atten(ADC.ATTN_11DB) # pour echelle 0-3.3V
>>> sensor.read()
442
>>> sensor.read()
4095
Note
L'ESP 32 disposent de 2 modules ESP 32, ADC1 et ADC2. Si le wifi est utilisé, alors ADC2 n'est pas utilisable. C'est pourquoi Micropython n'implémente pas ADC2 par défaut. On a donc seulement 4 broches analogiques. Si on a besoin de plus, il est facile d'ajouter un multiplexeur analogique ou bien un module analogique i2C. La limitation est la même en C / Arduino car liée à l'ESP 32 lui-même.
Voir : https://github.com/micropython/micropython/issues/6219
Timer
Timer 0 à 3 disponibles : le constructeur nécessite de fournir un index de timer.
from machine import Timer, Pin
led=Pin(15, Pin.OUT)
timer=Timer(0)
def loop(timer):
if led.value():led.off()
else:led.on()
timer.init(freq=10, callback=loop)
SPI
ESP 8266
Attention, la configuration est un peu spécifique : on ne précise pas les broches et l'indice doit être 1 (0 correspondant à la Flash)
https://docs.micropython.org/en/latest/esp8266/quickref.html?highlight=spi#hardware-spi-bus
>>> sp=SPI(1) # MISO=GPIO12 MOSI=GPIO13 et SCK=GPIO14 - SPI 0 = flash !
ESP 32
https://docs.micropython.org/en/latest/esp32/quickref.html#hardware-spi-bus
RTC
from machine import RTC
rtc.datetime()
rtc=RTC()
rtc.datetime()
(2000, 1, 1, 5, 1, 11, 49, 170430)
RMT
https://docs.micropython.org/en/latest/esp32/quickref.html#rmt
Fonctions spécifiques ESP 32
voir ici : https://docs.micropython.org/en/latest/library/esp32.html
Communication WebREPL
Une chose très intéressante avec les ESP 32 est la possibilité de communiquer en mode interpréteur via le réseau wifi sur lequel il se trouve.
Pour cela, il suffit d'activer le serveur REPL sur l'ESP 32 (intégré par défaut dans la version Micropython des ESP)
>>> import network
>>> wifi=network.WLAN(network.STA_IF)
>>> wifi.isconnected()
False
>>> wifi.active(True)
True
>>> wifi.connect("dlink","")
>>> wifi.isconnected()
True
>>> wifi.ifconfig()
('192.168.0.101', '255.255.255.0', '192.168.0.1', '0.0.0.0')
>>> import webrepl
>>> webrepl.start()
WebREPL daemon started on ws://192.168.0.101:8266
Started webrepl in normal mode
>>>
On peut mettre çà dans une fonction dans le boot.py aussi.
+/- Configuration
>>> import webrepl_setup
WebREPL daemon auto-start status: enabled
Would you like to (E)nable or (D)isable it running on boot?
(Empty line to quit)
> E
Would you like to change WebREPL password? (y/n) n
No further action required
>>> import webrepl
>>> webrepl.start()
Started webrepl in normal mode
*https://www.techcoil.com/blog/how-to-setup-micropython-webrepl-on-your-esp32-development-board/
Le client webrepl
C'est une appli web qui utilise websocket :
Installer localement.
Lancer serveur avec n'importe quel serveur de fichier statique de son choix :
php -S 127.0.0.1:8000
Se connecter sur :
http://127.0.0.1:8000/webrepl.html
Le terminal est inactif dans mon cas bien que la connexion semble se faire correctement.
Projets à base d'ESP 32
- un serveur simple : https://randomnerdtutorials.com/micropython-esp32-esp8266-bme680-web-server/
- contrôler servo : https://icircuit.net/micropython-controlling-servo-esp32-nodemcu/2385
Sources intéressantes
- https://projetsdiy.fr/microcontroleurs-mcu/esp32-iot/page/2/ Les projets MicroPython et Arduino sont mélangés mais il y a quelques bonnes pages MicroPython.
-
Une présentation très complète avec de bonnes explications est disponible ici (bilan des ESP en 2020) : https://projetsdiy.fr/quelle-carte-esp32-choisir-developper-projets-diy-objets-connectes/
Voir également les fonctions spécifiques à l'ESP 32 fournies par Micropython : https://docs.micropython.org/en/latest/library/esp32.html