ESP32. Utiliser les interruptions externes avec du code Arduino • Domotique et objets connectés à faire soi-même

L’ESP32 dispose de 26 broches numériques qui peuvent être utilisées pour déclencher l’exécution d’une fonction à l’aide d’une interruption externe. Une interruption est un processus qui est déclenché de manière asynchrone par un évènement extérieur. Les interruptions permettent de détecter un évènement en temps réel tout en laissant le processeur du micro-contrôleur faire d’autres tâches.

L’utilisation des interruptions externes permet de simplifier la programmation des événements.

L’ESP32 dispose également de 4 Timers qui permettent de programmer le déclenchement d’alarmes. Tout est expliquée en détail dans ce tutoriel

A LIRE AUSSI :

ESP32. Utiliser les Timers et alarmes avec du code Arduino

Installer le SDK ESP-IDF pour ESP32 sur IDE Arduino et PlatformIO

Si vous débutez avec les cartes de développement ESP32 vous devez d’abord installer le kit de développement ESP-IDF. Voici deux tutoriels pour débuter en fonction de votre éditeur de code

Suivez les instructions de ce tutoriel pour l’IDE Arduino

Et celui-ci pour PlatformIO (idéalement avec VSCode)

Introduction aux interruptions (externes)

La façon classique de programmer lorsqu’on veut déclencher un événement à l’aide d’une entrée numérique est de tester sa valeur régulièrement dans la boucle loop(). En fonction de sa valeur, on exécute le code correspondant à l’état

void loop() { 
  // Lit la valeur du bouton 
  button_state = digitalRead(PIN_BUTTON); 
 
  // si le bouton est appuye, passe l etat de la sortie a HIGH, sinon LOW 
  if (button_state == HIGH) { 
    // Allume la LED 
    digitalWrite(PIN_LED, HIGH); 
  } else { 
    // Eteint la LED 
    digitalWrite(PIN_LED, LOW); 
  } 
}

Cette façon de programmer convient parfaitement la plupart du temps mais pose des problèmes dans les cas suivants :

  • On souhaite ralentir la boucle loop avec un delay()
  • On souhaite mettre en sommeil l’ESP32 et le réveiller lorsqu’un événement externe se produit. Par exemple une détection de mouvement, l’appui sur un bouton ou une touche tactile…

C’est dans ce cas que les interruptions sont utiles

Comme l’interruption est déclenchée depuis un événement extérieur au processeurs, c’est une interruption externe.

Broches du GPIO de l’ESP32 compatibles avec les interruptions

Les interruptions fonctionnent uniquement avec les entrées numériques. Les entrées numériques pouvant déclencher une interruption sont entourée d’un cercle sur le schéma ci-dessous.

fplg6cbyyyoogvgkkb9s-1263642

Attention toutefois car certaines broches passent à l’état haut (HIGH) ou émettent des signaux PWM au démarrage ou lors de la réinitialisation. D’autres broches sont utilisées par le système pour accéder à la mémoire flash ou téléverser le programme.

N’utilisez pas les broches colorées en orange ou en rouge. Votre programme pourrait avoir un comportement inattendu en utilisant celles-ci.

Broche du GPIO Entrée numérique (Input) Remarque
0 PULL UP Envoi un signal PWM au démarrage.
1 TX Sortie de débogage au démarrage
2 Connecté à la LED embarquée
3 Prend l’état HIGH au démarrage
4
5 Envoi un signal PWM au démarrage
6 Utilisé pour la mémoire flash SPI
7 Utilisé pour la mémoire flash SPI
8 Utilisé pour la mémoire flash SPI
9 Utilisé pour la mémoire flash SPI
10 Utilisé pour la mémoire flash SPI
11 Utilisé pour la mémoire flash SPI
12 Echec de démarrage si en mode PULLUP
13
14 Envoi un signal PWM au démarrage
15 Envoi un signal PWM au démarrage
16
17
18
19
21
22
23
25
26
27
32
33
34
35
36
39

Données collectées depuis la documentation officielle.

Configurer l’entrée numérique de l’ESP32

Avoir de pouvoir utiliser sur une entrée numérique du GPIO, il faut tout d’abord configurer la broche comme une entrée à l’aide de la fonction pinMode() comme ceci

pinMode(broche, mode);

La méthode pinMode a deux arguments

  • Le numéro de la broche
  • Le mode

3 modes sont disponibles pour configurer la broche comme une entrée numérique

  • INPUT En fonction du périphérique d’entré utilisé, il faudra adapter le circuit. Par exemple, lorsqu’on utilise un bouton poussoir de type Momentary Switch, il faudra intégrer une résistance de tirage pull-up ou de rappel pull-down au circuit. Sans résistance de pull-up ou pull-down l’entrée de l’ESP32 est flottante. Le niveau logique est indéfini ce qui peut entraîner un fonctionnement erratique du programme. Par exemple ne pas détecter la pression sur un bouton ou au contraire détecter qu’il est enfoncé alors que ce n’est pas le cas.
  • INPUT_PULLUP On utilise la résistance de tirage (PULL UP) de l’ESP32
  • INPUT_PULLDOWN On utilise la résistance de rappel (PULL DOWN) de l’ESP32

Comment ajouter une interruption externe à un projet ESP32 ?

Ensuite on assigner une fonction qui sera exécutée dès qu’un événement est détecté sur la broche à l’aide de la méthode attachInterrupt(GPIO, FUNCTION, MODE). La méthode nécessite 3 arguments

  • GPIO La broche qui déclenche l’événement. C’est la broche que l’on a configuré précédemment
  • FUNCTION la fonction à exécuter lorsqu’un événement survient
  • MODE mode de déclenchement

5 modes de déclenchement sont possibles

  • LOW pour déclencher l’interruption chaque fois que la broche est à l’état bas (LOW)
  • HIGH pour déclencher l’interruption chaque fois que la broche est à l’état haut (HIGH)
  • CHANGE pour déclencher l’interruption chaque fois que la broche change d’état. Par exemple lorsqu’elle passer de HIGH à LOW ou LOW à HIGH
  • FALLING pour quand la broche passe de HIGH à LOW. C’est la détection du front montant.
  • RISING pour déclencher lorsque la broche passe de LOW à HIGH. C’est la détection du front descendant.

Déclarer la fonction à exécuter dans la IRAM (IRAM_ATTR)

L’execution d’une fonction appelée par une interruption est bloquante, c’est à dire qu’il faut attendre la fin de son exécution pour que le reste du code puisse continuer.

Habituellement, le code est exécuté directement sur la mémoire flash de la carte de développement. Il est possible de déplacer la fonction dans la RAM interne de l’ESP32 qui est beaucoup plus rapide.

Pour cela, il suffit de placer l’attribut IRAM_ATTR juste avant le nom de la fonction comme ceci

void IRAM_ATTR mafonctionrapide(){
   ...
}

Ce n’est pas obligatoire et vous pourrez d’ailleurs le tester vous même avec le code proposé à la fin du tutoriel. Cependant, il est fortement conseillé de placer dans la RAM de l’ESP32 toutes les fonctions appelées par les interruptions pour un projet réel.

Exemple pour déclencher une interruption à l’aide d’un interrupteur

Passons maintenant à un exemple concret. On compte à l’aide d’une interruption le nombre de fois que l’utilisateur appuie sur un bouton poussoir (momentary switch en anglais). Dès que le compteur atteint 5 clics, on allume une LED durant 5 secondes à l’aide d’un Timer puis on détache l’interruption.

Il existe de nombreuses solutions pour déclencher un événement externe :

Quelque soit le matériel utilisé, on recevra toujours un signal de type LOW / HIGH. Donc quelque soit votre projet, le code restera parfaitement identique

Ici, nous allons utiliser un bouton poussoir. Il est équipé d’un ressort de rappel qui fait retourner le bouton à l’état BAS dès qu’on relâche ce dernier.

Circuit

Le bouton poussoir est connecté à l’entrée numérique 4. La LED est connectée à la sortie 32.

Vous pouvez tester le fonctionnement du programme en l’absence de résistance de tirage (PULL_UP). Vous pouvez tester en utilisant la résistance de tirage (PULL_UP) interne de l’ESP32 ou ajouter une résistance au circuit (10 kΩ par exemple).

3xyk9ctyjp5n1pzhr1eq-9647848

La LED doit être protégée par une résistance dont la valeur dépend de la tension et l’intensité de sortie de la broche (3,3V – 40mA) et de la tension d’alimentation maximale de la LED.

Vous pouvez utiliser ce calculateur pour déterminer la valeur de la résistance nécessaire pour votre circuit.