attachInterrupt()
Utiliser les interruptions :
Les interruptions permettent d’automatiser les opérations dans les programmes de microcontrôleurs et peuvent contribuer à résoudre les problèmes de synchronisation. L’utilisation d’une interruption peut notamment être utile pour la lecture d’un encodeur rotatif ou la surveillance des entrées utilisateur.
Si l’on voulait garantir qu’un programme capte systématiquement les impulsions d’un encodeur rotatif, afin de ne jamais en manquer une, il serait très compliqué d’écrire un programme pour effectuer autre chose, car il devrait interroger en permanence les lignes du capteur pour capter les impulsions lorsqu’elles se produisent. D’autres capteurs ont une dynamique d’interface similaire, comme la lecture d’un capteur sonore qui détecte un clic, ou d’un capteur infrarouge (photo-interrupteur) qui détecte la chute d’une pièce. Dans toutes ces situations, l’utilisation d’une interruption permet au microcontrôleur de se consacrer à d’autres tâches tout en capturant les entrées.
Syntaxe :
- attachInterrupt(digitalPinToInterrupt(pin), ISR, mode) (recommandé)
- attachInterrupt(interrupt, ISR, mode) (non recommandé)
- attachInterrupt(pin, ISR, mode) (non recommandé. De plus, cette syntaxe ne fonctionne que sur les cartes Arduino SAMD, UNO WiFi Rev2, Due et 101.)
Paramètres :
- interrupt : le numéro de l’interruption. Types de données autorisés : int.
- pin : le numéro de la broche Arduino.
- ISR : l’ISR à appeler en cas d’interruption ; cette fonction ne doit accepter aucun paramètre et ne doit rien renvoyer. Cette fonction est parfois appelée routine de service d’interruption.
- mode : définit le moment où l’interruption doit être déclenchée. Quatre constantes sont prédéfinies comme valeurs valides :
- LOW pour déclencher l’interruption lorsque la broche est à l’état bas ;
- CHANGE pour déclencher l’interruption lorsque la broche change de valeur ;
- RISING pour déclencher lorsque la broche passe de l’état bas à l’état haut ;
- FALLING pour déclencher lorsque la broche passe de l’état haut à l’état bas.
Les cartes Due, Zero et MKR1000 permettent également :
- HIGH pour déclencher l’interruption lorsque la broche est à l’état haut.
Interrupt Service Routines (ISR)
Les ISR sont des fonctions spéciales qui présentent des limitations uniques, différentes de la plupart des autres fonctions. Une ISR ne peut avoir aucun paramètre et ne doit rien renvoyer.
En général, une ISR doit être aussi courte et rapide que possible. Si votre sketch utilise plusieurs ISR, une seule peut être exécutée à la fois ; les autres interruptions seront exécutées après la fin de l’interruption en cours, dans un ordre qui dépend de leur priorité. millis() s’appuie sur les interruptions pour compter ; elle n’augmentera donc jamais à l’intérieur d’une ISR. Puisque delay() nécessite des interruptions pour fonctionner, elle ne fonctionnera pas si elle est appelée à l’intérieur d’une ISR. micros() fonctionne initialement, mais commence à se comporter de manière erratique après 1 à 2 ms. delayMicroseconds() n’utilise pas de compteur ; elle fonctionnera donc normalement.
En général, les variables globales servent à transmettre des données entre une routine de service d’interruption (ISR) et le programme principal. Pour garantir que les variables partagées entre une ISR et le programme principal sont correctement mises à jour, déclarez-les comme volatiles.
Pour plus d’informations sur les interruptions, consultez les notes de Nick Gammon.
Retours :
Rien
Exemple de code :
const byte ledPin = 13; const byte interruptPin = 2; // broche d'entrée à laquelle l'interruption sera attachée volatile byte state = LOW; // variable qui sera mise à jour dans l'ISR void setup() { pinMode(ledPin, OUTPUT); pinMode(interruptPin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE); } void loop() { digitalWrite(ledPin, state); } void blink() { state = !state; }
Broches numériques avec interruptions
Le premier paramètre de attachInterrupt() est un numéro d’interruption. Normalement, vous devez utiliser digitalPinToInterrupt(pin) pour convertir la broche numérique réelle en numéro d’interruption spécifique. Par exemple, si vous vous connectez à la broche 3, utilisez digitalPinToInterrupt(3) comme premier paramètre de attachInterrupt().
Board | Broches numériques utilisables pour les interruptions | Remarques |
---|---|---|
UNO R3, Nano, Mini, other 328-based | 2, 3 | |
UNO R4 Minima, UNO R4 WiFi | 2, 3 | |
UNO WiFi Rev2, Nano Every | Toutes les broches digital | |
Mega, Mega 2560, Mega ADK | 2, 3, 18, 19, 20, 21 | les broches 20 et 21 ne sont pas disponibles pour les interruptions alors qu’elles sont utilisées pour la communication I2C ; elles ont également des résistances de rappel externes qui ne peuvent pas être désactivées |
Micro, Leonardo | 0, 1, 2, 3, 7 | |
Zero | 0-3, 5-13, A0-A5 | La broche 4 ne peut pas être utilisée comme interruption. |
MKR Family boards | 0, 1, 4, 5, 6, 7, 8, 9, A1, A2 | |
Nano 33 IoT | 2, 3, 9, 10, 11, 13, A1, A5, A7 | |
Nano 33 BLE, Nano 33 BLE Sense (Rev 1 & 2) | Toutes les broches | |
Nano RP2040 Connect | 0-13, A0-A5 | |
Nano ESP32 | Toutes les broches | |
GIGA R1 WiFi | Toutes les broches | |
Due | Toutes les broches digital | |
101 | Toutes les broches digital | Seules les broches 2, 5, 7, 8, 10, 11, 12, 13 fonctionnent avec CHANGE. |
Numéros d’interruption
Normalement, il est préférable d’utiliser digitalPinToInterrupt(pin) plutôt que d’insérer un numéro d’interruption directement dans votre croquis. Les broches spécifiques avec interruptions et leur correspondance avec le numéro d’interruption varient selon le type de carte. L’utilisation directe des numéros d’interruption peut sembler simple, mais elle peut entraîner des problèmes de compatibilité lorsque votre croquis s’exécute sur une autre carte.
Cependant, les croquis plus anciens utilisent souvent des numéros d’interruption directs. Le numéro 0 (pour la broche numérique 2) ou le numéro 1 (pour la broche numérique 3) étaient souvent utilisés. Le tableau ci-dessous présente les broches d’interruption disponibles sur différentes cartes.
Notez que dans le tableau ci-dessous, les numéros d’interruption correspondent au numéro à transmettre à attachInterrupt(). Pour des raisons historiques, cette numérotation ne correspond pas toujours directement à celle de la puce ATmega (par exemple, int.0 correspond à INT4 sur la puce ATmega2560).
Board | int.0 | int.1 | int.2 | int.3 | int.4 | int.5 |
---|---|---|---|---|---|---|
UNO, Ethernet | 2 | 3 | ||||
Mega 2560 | 2 | 3 | 21 | 20 | 19 | 18 |
32u4 based (e.g Leonardo, Micro) | 3 | 2 | 0 | 1 | 7 |
Pour les cartes UNO WiFi Rev2, Due, Zero, MKR Family et 101, le numéro d’interruption = numéro de broche.
Remarques et avertissements :
Remarque : la fonction associée, delay(), ne fonctionnera pas et la valeur renvoyée par millis() ne s’incrémentera pas. Les données série reçues pendant l’exécution de la fonction risquent d’être perdues. Il est conseillé de déclarer comme volatiles toutes les variables modifiées dans la fonction associée. Consultez la section sur les ISR ci-dessous pour plus d’informations.
Source : https://docs.arduino.cc/language-reference/en/functions/external-interrupts/attachInterrupt/