Dans ce guide, nous examinerons les bases de la programmation asynchrone MicroPython avec les NodeMCU ESP32 et ESP8266 à l’aide du module asyncio. Vous apprendrez à exécuter plusieurs tâches simultanément, créant ainsi l’illusion du multitâche et évitant de bloquer votre code sur des tâches de longue durée.

Nouveau sur MicroPython ? Consultez notre eBook : Programmation MicroPython avec ESP32 et ESP8266.
Par exemple, votre programme peut attendre la réponse d’un serveur tout en étant capable d’effectuer d’autres tâches, comme vérifier si un bouton a été enfoncé ou faire clignoter une LED en même temps.
La programmation asynchrone peut être utile dans des projets qui incluent : l’interaction avec des bases de données, la communication sur des réseaux (comme lors de la demande de données à un serveur ou lorsque l’ESP32/ESP8266 agit comme un serveur Web), la lecture des données du capteur, l’affichage de la sortie sur un écran, la réception les contributions des utilisateurs, et bien plus encore.
Table des matières:
Dans ce didacticiel, nous aborderons les sujets suivants :
Conditions préalables
Pour suivre ce tutoriel, vous devez installer le firmware MicroPython sur vos cartes ESP32 ou ESP8266. Vous avez également besoin d’un IDE pour écrire et télécharger le code sur votre tableau. Nous vous suggérons d’utiliser Thonny IDE ou uPyCraft IDE :
- ThonnyIDE :
- L’EDI uPyCraft :
Pièces requises
Pour suivre ce tutoriel vous avez besoin des pièces suivantes :
Vous pouvez utiliser les liens précédents ou vous rendre directement sur MakerAdvisor.com/tools pour trouver toutes les pièces pour vos projets au meilleur prix !

Présentation de la programmation asynchrone
La programmation asynchrone est une technique qui permet à votre programme de démarrer une tâche potentiellement longue tout en restant réactif aux autres événements pendant l’exécution de cette tâche, plutôt que d’avoir à attendre que cette tâche soit terminée.
Ceci est réalisé en exécutant des tâches de manière non bloquante et en utilisant des fonctions de rappel pour gérer les résultats. De cette façon, le programme peut continuer à exécuter d’autres tâches en attendant les résultats de la tâche asynchrone. En revanche, en programmation synchrone, chaque tâche doit attendre la fin de la tâche précédente avant de démarrer.
En résumé…
- L’asynchrone est une architecture non bloquante, donc l’exécution d’une tâche ne dépend pas d’une autre. Les tâches peuvent s’exécuter simultanément.
- Synchrone est une architecture bloquante, donc l’exécution de chaque opération dépend de l’achèvement de la précédente.

Le module MicroPython asyncio
MicroPython fournit le module asyncio, qui est un framework d’E/S asynchrones léger inspiré du module asyncio de Python. Vous pouvez vérifier tous les détails sur ce module MicroPython sur le lien suivant :
Jetons un coup d’œil rapide à quelques concepts de base que vous devez connaître pour commencer à utiliser asyncio pour la programmation asynchrone :
- Boucle d’événement : c’est une boucle qui vérifie en permanence les événements (tâches ou coroutines) et les exécute.
- Tâches : unités de travail individuelles ou coroutines planifiées pour s’exécuter simultanément dans la boucle d’événements
- Fonctions asynchrones : également appelées coroutines, ce sont des fonctions qui peuvent être suspendues et reprises sans bloquer d’autres opérations, permettant l’exécution simultanée de plusieurs tâches.
- wait : est un mot-clé utilisé dans les coroutines pour suspendre l’exécution de la coroutine actuelle jusqu’à ce qu’un événement ou une opération spécifique soit terminé, permettant à d’autres coroutines de s’exécuter entre-temps.
Examinons maintenant plus en détail chacun de ces concepts, ainsi que le flux de travail et les méthodes du module asyncio pour écrire un programme asynchrone.
Boucle d’événement
Une boucle d’événements est au cœur de la programmation asynchrone. C’est une boucle qui vérifie en permanence les événements (tâches ou coroutines) et les exécute. Dans asyncio, vous créez une boucle d’événements en utilisant asyncio.get_event_loop().
La ligne suivante crée une instance de la boucle d’événements appelée boucle. Vous pouvez utiliser cette boucle pour gérer et planifier des tâches asynchrones.
loop = asyncio.get_event_loop()
Création de tâches
En programmation asynchrone, les tâches représentent des unités de travail. Vous créez des tâches pour exécuter des coroutines simultanément. Les coroutines sont des fonctions définies avec le mot-clé async, qui peuvent être mises en pause et reprises, permettant une programmation asynchrone.
Par exemple:
async def blink_led():
#Code to blink an LED
Ensuite, nous pouvons utiliser loop.create_task() pour planifier cette coroutine en tant que tâche à exécuter par la boucle d’événements.
loop.create_task(blink_led())
Exécution de la boucle d’événements
Une fois que vous avez créé des tâches, vous démarrez la boucle d’événements pour les exécuter. La boucle vérifiera en permanence les tâches planifiées et les exécutera. La ligne suivante initie la boucle d’événements, comme nous l’avons vu précédemment.
loop = asyncio.get_event_loop()
Ensuite, loop.run_forever() le fait fonctionner indéfiniment, vérifiant constamment les tâches à exécuter.
loop.run_forever()
Fonctions asynchrones – async def
Une fonction asynchrone est définie à l’aide de la syntaxe async def. Ces fonctions, également appelées coroutines, peuvent être suspendues avec le mot-clé wait, permettant ainsi à d’autres coroutines de s’exécuter entre-temps. Par exemple:
async def blink_led():
while True:
led.toggle() # Toggle LED state
await asyncio.sleep(1)
Ici, clin_led() est une fonction asynchrone. Il active une LED puis fait une pause d’une seconde en utilisant wait asyncio.sleep(1). Pendant cette pause, d’autres tâches peuvent s’exécuter.
await asyncio.sleep(1)
Délai asynchrone – acyncio.sleep()
asyncio.sleep() est une coroutine fournie par le module asyncio et elle est utilisée pour introduire un retard dans l’exécution d’une coroutine pour une durée spécifiée sans bloquer toute la boucle d’événements. Ainsi, pour créer une fonction asynchrone, vous devez remplacer tout votre time.sleep() par asyncio.sleep().
Lorsque asyncio.sleep() est appelé dans une coroutine, il suspend temporairement l’exécution de cette coroutine, permettant à d’autres coroutines de s’exécuter entre-temps.
La boucle d’événements continue de s’exécuter pendant que la coroutine est en pause, vérifiant d’autres tâches et événements.
Après la durée spécifiée (secondes), la coroutine en pause reprend l’exécution à partir du point où asyncio.sleep() a été appelé.
wait asyncio.sleep() est un moyen non bloquant de céder le contrôle à d’autres coroutines dans la boucle d’événements sans introduire de délai réel. Cela permet effectivement à d’autres coroutines de s’exécuter immédiatement.
attendre
Le mot-clé wait est utilisé dans les coroutines pour indiquer un point où la coroutine peut être temporairement suspendue jusqu’à ce qu’un événement spécifique soit terminé.
Dans l’exemple suivant, la coroutine s’arrête pendant 1 seconde sans bloquer toute la boucle d’événements.
await asyncio.sleep(1)
En résumé…
Lorsque vous exécutez un programme asynchrone, la boucle d’événements s’exécute en continu, exécutant simultanément les tâches planifiées. Chaque coroutine s’exécute à tour de rôle et les instructions wait permettent à la boucle d’événements de basculer entre les tâches, créant ainsi une apparence de parallélisme.
Ainsi, vous pouvez effectuer plusieurs tâches simultanément sans avoir à attendre que chacune soit terminée avant de passer à la suivante.
Exemple de base d’un programme asynchrone
Maintenant que vous connaissez les concepts de base de la programmation asynchrone et les méthodes de base du module asyncio, créons un exemple simple pour appliquer les concepts appris.
Nous allons créer deux coroutines différentes. Chaque coroutine fera clignoter une LED différente à une fréquence différente.
- LED verte : GPIO 14 >> clignote toutes les deux secondes ;
- LED bleue : GPIO 12 >> clignote toutes les demi-secondes.
Pour vérifier visuellement le résultat final, connectez deux LED à l’ESP32 ou à l’ESP8266, une au GPIO 14 et l’autre au GPIO 12.
ESP32

Nœud MCU ESP8266

Voici notre exemple de code.
# Rui Santos & Sara Santos - Raspberryme.com
# Complete project details at https://Raspberryme.com/micropython-esp32-esp8266-asynchronous-programming/
import asyncio
from machine import Pin
green_led_pin = 14
green_led = Pin(green_led_pin, Pin.OUT)
blue_led_pin = 12
blue_led = Pin(blue_led_pin, Pin.OUT)
# Define coroutine function
async def blink_green_led():
while True:
green_led.value(not green_led.value() )
await asyncio.sleep(0.5)
# Define coroutine function
async def blink_blue_led():
while True:
blue_led.value(not blue_led.value())
await asyncio.sleep(1)
# Define the main function to run the event loop
async def main():
# Create tasks for blinking two LEDs concurrently
asyncio.create_task(blink_green_led())
asyncio.create_task(blink_blue_led())
# Create and run the event loop
loop = asyncio.get_event_loop()
loop.create_task(main()) # Create a task to run the main function
loop.run_forever() # Run the event loop indefinitely
Afficher le code brut
Comment fonctionne le code
Jetons un coup d’œil rapide au code.
Nous créons deux coroutines. Un pour chaque LED :
# Define coroutine function
async def blink_green_led():
while True:
green_led.value(not green_led.value())
await asyncio.sleep(0.5)
# Define coroutine function
async def blink_blue_led():
while True:
blue_led.value(not blue_led.value())
await asyncio.sleep(1)
À l’intérieur de chaque coroutine, nous basculons l’état de la LED dans une boucle et attendons (attente asynchrone) pendant un intervalle spécifique wait asyncio.sleep(0.5).
Nous créons une autre coroutine appelée main() qui sert de point central où vous pouvez organiser et coordonner l’exécution de ces tâches.
Dans la coroutine main(), nous créons des tâches pour les fonctions clignotant_green_led() et clignotant_blue_led() à exécuter simultanément.
# Define the main function to run the event loop
async def main():
# Create tasks for blinking two LEDs concurrently
asyncio.create_task(blink_green_led())
asyncio.create_task(blink_blue_led())
Ensuite, nous créons une boucle d’événements.
loop = asyncio.get_event_loop()
Le loop.create_task(main()) crée une tâche pour exécuter la fonction coroutine main().
loop.create_task(main()) # Create a task to run the main function
Enfin, la méthode run_forever() commencera à exécuter la boucle d’événements indéfiniment. La boucle d’événements vérifie en permanence les tâches à exécuter, les exécute simultanément et gère leur exécution.
loop.run_forever() # Run the event loop indefinitely
Tester le code
Exécutez le code précédent sur votre ESP32 ou ESP8266. Le résultat sera deux LED clignotantes à des rythmes différents.
Conclusion
Ceci est juste un exemple simple pour vous montrer comment écrire un programme asynchrone en MicroPython pour ESP32 et ESP8266. Maintenant, vous devez comprendre qu’au lieu de faire clignoter une LED, vous pouvez effectuer des tâches plus complexes comme lire un fichier, demander des données sur Internet, gérer un serveur Web avec plusieurs clients, et bien plus encore.
Nous espérons que ce guide vous sera utile. Pour en savoir plus sur MicroPython avec ESP32/ESP8266, assurez-vous de consulter nos ressources :
Plongez dans l’histoire de Raspberry Pi avec cette vidéo :

-
Lot de 2 écrans LCD I2C 16x2 - Rétroéclairage bleu - Contraste réglable - Compatible avec Arduino, ESP32, ESP8266, Raspberry Pi, MicroPython
-
ELECROW Écran Tactile ESP32 800 × 480, écran Tactile LCD TFT HMI ESP32 RVB 7", processeur LX6 Dual-Core 32 Bits, jusqu'à 240 MHz, Compatible avec Arduino, LVGL, PlatformIO, MicroPython (sans boîtier
