Se connecter à un réseau Wi-Fi avec l’ESP32 en MicroPython
(Mis à jour le 06/04/2023)
L’ESP32 est une carte électronique capable de se connecter à un réseau Wi-Fi. Grâce au module network
inclus de base dans MicroPython, il est possible d’utiliser facilement les fonctionnalités Wi-Fi de cette carte. Dans cet article, nous allons explorer le premier mode Wi-Fi possibles sur la carte ESP32 : le mode Station (STA) .
Mode Station : Accéder à Internet depuis l’ESP32
Le mode Station (STA) est utilisé pour connecter l’ESP32 à un point d’accès Wi-Fi. En mode STA
, la carte ESP32 agit comme un ordinateur connecté à notre box. Si la box est connectée à Internet, alors l’ESP32 peut y accéder. L’ESP32 est intégré dans votre réseau local : on peut aussi avoir un microserveur dessus et y accéder depuis d’autres appareils connectés à votre réseau (Ordinateur, tablette…) voir depuis Internet.
Script minimal pour se connecter à un réseau WiFi
Voici un script Python simple qui permet de se connecter à votre box :
Astuce
Un moyen simple d’avoir une “box de test” est de faire un partage de connexion Wi-Fi depuis son smartphone et de se connecter sur cette box virtuelle.
import network
import time
ssid = 'upesy-ap'
password = 'cupcakes'
if __name__=="__main__":
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print(f"Try connect to SSID : {ssid}")
wlan.connect(ssid, password)
while not wlan.isconnected():
print('.', end = " ")
time.sleep_ms(500)
print("\nWi-Fi Config: ", wlan.ifconfig())
Important
N’oubliez pas de mettre les identifiants de votre box dans les variables ssid
et password
. ssid
correspond au nom de votre box.
Explications
On configure l’interface réseau de MicroPython pour se mettre en mode station avec network.WLAN(network.STA_IF)
. Ensuite on active l’interface, puis si on n’est pas déjà connecté au réseau on essaye en boucle de se connecter à la box. La connexion n’est pas instantanée et peut prendre plusieurs secondes. C’est pour cela qu’on rajoute un petit délai de 500ms entre deux tentatives.
Au début, on ajoute une étape de vérification sur le statut de la connexion actuelle car entre 2 lancements de scripts, MicroPython conserve l’état de connexion. Elle n’est pas réinitialisée comme cela pourrait être le cas avec du code Arduino. Si on essaye de se reconnecter alors que l’on est déjà connecté, MicroPyton va planter en renvoyant cette erreur.
Le gros avantage c’est que l’on a pas à se reconnecter à chaque lancement d’un script : c’est plusieurs secondes d’économisées à chaque fois 🙂.
Vous remarquez d’ailleurs que les prochaines fois, le script affiche directement les informations sur le réseau dont on est déjà connecté.
D’ailleurs voici une explication des informations renvoyées par wlan.ifconfig()
:
192.168.158.175
correspond à l’adresse IP locale de l’ESP32 sur votre réseau255.255.255.0
correspond au masque de sous-réseau.192.168.158.177
correspond à l’adresse IP locale de votre box192.168.158.177
correspond à l’adresse IP du serveur DNS
On peut aussi utiliser cette fonction pour imposer les numéros d’IP choisis.
Note
Le nom de cette fonction fait allusion à la commande ifconfig
sur Linux et ipconfig
sur Windows qui permet d’obtenir des informations sur son interface réseau.
Des fonctions utiles
La fonction wlan.config()
permet de récupérer des informations utiles sur le réseau . On les utilisera dans le script du scan Wi-Fi des box aux alentours.
On peut récupérer la force du signal via la commande wlan.status('rssi')
.
import network
import time
def connect_to_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
if not wlan.active():
wlan.active(True)
if not wlan.isconnected():
print(f"Try connect to SSID : {ssid}")
wlan.connect(ssid, password)
while not wlan.isconnected():
print('.', end = " ")
time.sleep_ms(500)
return wlan
def display_wifi_info(wlan):
print("\nLocal IP: {}\nSubnet mask: {}\nIP Gateway: {}\nDNS:{}".format(*wlan.ifconfig()))
print("BSSID: {:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}".format(*wlan.config("mac")))
print(f"RSSI: {wlan.status('rssi')} dB")
if __name__=="__main__":
my_wlan = connect_to_wifi(ssid="upesy-ap", password="cupcakes")
display_wifi_info(my_wlan)
Sans paramètres on peut connaître le statut de la connexion. Cela peut être pratique pour debugger un problème de connexion :
STAT_IDLE
: Pas de connexion ni d’activité,STAT_CONNECTING
: Connexion en coursSTAT_WRONG_PASSWORD
: Connexion échouée à cause d’un mauvais mot de passeSTAT_NO_AP_FOUND
: Connexion échouée car le point d’accès est introuvableSTAT_CONNECT_FAIL
: Connexion échouée à cause d’un autre problèmeSTAT_GOT_IP
: Connexion réussie
Débogages
Vous pouvez utiliser le statut de la connexion pour plus facilement debugger les problèmes de connexion. Voici un exemple de script qui affiche régulièrement l’état :
import network
import time
def print_wlan_status(wlan_status):
stat = "UNKNOWN"
if wlan_status == network.STAT_IDLE:
stat = "STAT_IDLE"
elif wlan_status == network.STAT_CONNECTING:
stat = "STAT_CONNECTING"
elif wlan_status == network.STAT_WRONG_PASSWORD :
stat = "STAT_WRONG_PASSWORD "
elif wlan_status == network.STAT_NO_AP_FOUND :
stat = "STAT_NO_AP_FOUND "
elif wlan_status == network.STAT_CONNECT_FAIL :
stat = "STAT_CONNECT_FAIL "
elif wlan_status == network.STAT_GOT_IP :
stat = "STAT_GOT_IP "
print(stat)
def connect_to_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print(f"Try connect to SSID : {ssid}")
print_wlan_status(wlan.status())
wlan.connect(ssid, password)
print_wlan_status(wlan.status())
while not wlan.isconnected():
print_wlan_status(wlan.status())
time.sleep_ms(500)
return wlan
def display_wifi_info(wlan):
print("\nWi-Fi Config: ", wlan.ifconfig())
print(f"RSSI {wlan.status('rssi')} dB")
if __name__=="__main__":
my_wlan = connect_to_wifi(ssid="upesy-ap", password="cupcakes")
display_wifi_info(my_wlan)
De temps en temps, pour une raison inconnue, l’ESP32 peut ne pas arriver temporairement à se connecter au réseau WiFi. La meilleure solution est de dire qu’au bout de n tentatives si l’ESP32 ne s’est toujours pas connecté au WiFi, on redémarre l’ESP32 avec la fonction machine.reset()
.
Voici un exemple qui permet de redémarrer l’ESP32 au bout de 5 tentatives :
import network
import time
import machine
def connect_to_wifi(ssid, password, max_try=-1):
connexion_try = 0
wlan = network.WLAN(network.STA_IF)
if not wlan.active():
wlan.active(True)
if not wlan.isconnected():
print(f"Try connect to SSID : {ssid}")
wlan.connect(ssid, password)
while not wlan.isconnected():
if max_try>0 and connexion_try >= max_try:
print(f"\nStill not connected after {connexion_try} tries -> Restart ESP32")
machine.reset()
connexion_try+=1
print('.', end = " ")
time.sleep_ms(500)
return wlan
if __name__=="__main__":
my_wlan = connect_to_wifi(ssid="upesy-ap", password="cupcakes", max_try=5)
display_wifi_info(my_wlan)
À noter que le script ne se relancera pas automatiquement. Cette solution est intéressante quand le script est sauvegardé dans le fichier boot.py
ou main.py
qui s’exécute dès que l’ESP32 est allumé.
Scan Wi-Fi : Détecter les box Wi-Fi aux alentours
En utilisant la fonction wlan.scan()
, on peut très facilement implémenter un scanneur des box Wi-Fi aux alentours.
import network
import time
if __name__=="__main__":
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if wlan.isconnected():
wlan.disconnect()
print("[*] Start Wi-Fi Scan ...")
authmodes = ['Open', 'WEP', 'WPA-PSK','WPA2-PSK4', 'WPA/WPA2-PSK', 'Other']
for (ssid, bssid, channel, RSSI, authmode, hidden) in wlan.scan():
print("* {:s}".format(ssid))
print(authmodes[authmode])
print(" - Auth: {} {}".format(authmodes[authmode], '(hidden)' if hidden else ''))
print(" - Channel: {}".format(channel))
print(" - RSSI: {}".format(RSSI))
print(" - BSSID: {:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}".format(*bssid))
print()
On vérifie au début que MicroPython n’est pas déjà connecté à un réseau. Si c’est le cas, on le déconnecte. Ensuite on peut commencer le scan. La fonction renvoie un tableau avec dans chacune des cases, un tuple
(une liste spécifique à Python pour faire simple) qui contient des informations sur un réseau Wi-Fi. Le reste n’est que du formatage pour afficher ces informations dans la console.
Sauvegarder ses clés d’accès
C’est une bonne pratique de ne jamais “hardcoder“ des identifiants dans un code, surtout si l’on compte le partager sur des sites comme Github, Gitlab…
En général, on centralise toutes les clés d’accès dans un fichier externe ou dans des variables d’environnements. Si on utilise un fichier texte, on veillera bien à ne pas l’inclure dans git via le fichier .gitignore
.
Une solution serait d’inclure les identifiants de votre box dans un fichier JSON (un ensemble de clé valeurs) et de le charger depuis votre script MicroPython. Ce fichier JSON sera stocké dans la mémoire flash de l’ESP32 et sera visible comme un fichier texte pour MicroPython.
Cette section est réservée aux abonnés. Il vous reste 79% à découvrir.
Devenir membre premiumDéjà abonné ? Connectez-vous
Avoir une connexion automatique
Cela peut être intéressant de se connecter à la box Wi-Fi dès que MicroPython se lance, c’est-à-dire dès que la carte ESP32 est allumée. En mettant le code dans le fichier boot.py
, il sera exécuté automatiquement à chaque démarrage de l’ESP32 même si aucun script Python est lancé par la suite.
Une autre solution est d’utiliser une libraire clé en main pour gérer la connexion aux box Wi-Fi. On peut même avoir un portail de connexion temporaire sur l’ESP32 pour renseigner depuis un autre appareil les identifiants de votre box. Cette solution est plus intéressante avec du code Arduino où le code est vraiment figé. La librairie de référence est https://github.com/tzapu/WiFiManager .
Cette section est réservée aux abonnés. Il vous reste 54% à découvrir.
Devenir membre premiumDéjà abonné ? Connectez-vous