Interrupt esterni di Arduino
Arduino permette ad alcuni pin di generare gli interrupt:
Tipo di board | Pin utilizzabili per gli interrupt |
---|---|
Uno, Nano, Mini, other 328-based | 2, 3 |
Uno WiFi Rev.2, Nano Every | all digital pins |
Mega, Mega2560, MegaADK | 2, 3, 18, 19, 20, 21 |
Micro, Leonardo, other 32u4-based | 0, 1, 2, 3, 7 |
Zero | all digital pins, except 4 |
MKR Family boards | 0, 1, 4, 5, 6, 7, 8, 9, A1, A2 |
Nano 33 IoT | 2, 3, 9, 10, 11, 13, 15, A5, A7 |
Nano 33 BLE, Nano 33 BLE Sense | all pins |
Due | all digital pins |
101 | all digital pins (Only pins 2, 5, 7, 8, 10, 11, 12, 13 work with CHANGE) |
Per poter generare un interrupt un piedino deve essere attivato tramite la funzione
attachInterrupt() (per approfondimenti cliccare qui)
la funzione detachInterrupt() invece disattiva il piedino (per approfondimenti cliccare qui)
L'esempio che segue mostra come si utilizza la funzione attachInterrupt(). Il programma cambia lo stato del led da acceso a spento e viceversa ogni volta che lo stato dell'ingresso al pin 2 cambia stato. In particolare nel passaggio LOW->HIGH il led si accenderà e nel passaggio HIGH->LOW si spegnerà.
const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}
void loop() {
digitalWrite(ledPin, state);
}
void blink() {
state = !state;
}
L'utilizzo degli interrupt modifica il normale flusso del programma (che viene interrotto per eseguire la routine di servizio). Questo può essere un problema in alcune circostanze, per esempio quando una sequenza di istruzioni deve essere completata senza interruzioni. In tal caso può essere significativo utilizzare con attachInterrupt() anche le funzioni:- interrupts() (per approfondimenti cliccare qui)
- nointerrupts() (per approfondimenti cliccare qui)
che rispettivamente abilitano e disabilitano gli interrupt.
Le differenze principali rispetto all'uso di attachInterrupt() e detachInterrupt() che attivano e disattivano gli interrupt su un piedino sono:
- interrupts() e nointerrupts() abilitano e disabilitano tutti gli interrupt del sistema
- se nel periodo di tempo intercorso tra la disabilitazione degli interrupt tramite nointerrupts() e la successiva riabilitazione tramite interrupts() sono arrivati dei segnali di interrupt, questi non vengono persi, ma le periferiche vengono servite immediatamente dopo la riattivazione degli interrupt tramite interrupts().
L'esempio che segue mostra l'utilizzo delle due funzioni:
const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}
void loop() {
noInterrupts();
// Il codice inserito qui dentro viene eseguito senza interruzioni
interrupts();
// Il codice scritto qui può essere interrotto per servire un'interrupt
digitalWrite(ledPin, state);
}
void blink() {
state = !state;
}