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 :

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 :

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

Discussion technique

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
Lien utile :

*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

Sources intéressantes

Voir également les fonctions spécifiques à l'ESP 32 fournies par Micropython : https://docs.micropython.org/en/latest/library/esp32.html