Appunti su Arduino: interrupts


Dopo l’estenuante periodo di fine anno scolastico passato tra interrogazioni, recuperi, esami di qualifica, esami di alternanza scuola lavoro, preparazioni tesine e svariate riunioni/scrutini… riesco a rimettere mani sui miei appunti realizzati durante l’anno scolastico e questa volta colgo l’occasione di rispondere al commento di Raffaele che vuole avere ulteriori informazioni sull’uso degli interrupt in Arduino:

salve sono un vecchio appassionato di elettronica (analogica )- Essendo che ci siamo dovuti convertire sui microcontrollori solo 5 mesi fà sono riuscito finalmente dopo aver tentato con i PIC ,sono passato ad Arduino
duemilaenove e finalmente ho incominciato a capirlo e sviluppare tutti i tipi di esempi che dava nel softwere, dal led ai motori passo passo
e i servo perchè il tipo di programmazzione e soprattutto molti esempi erano spiegati
pure in video e come dicevo sono riuscito a capirci qualcosa.Ovviamente nel mio caso
riuscivo a modificare quelli già presenti ma in sostanza ero abbastanza sodisfatto perchè su di uno sviluppavo le modifiche creandone dei nuovi. Adesso però mi sono fermato un pò perchè ho una richiesta da farle.Pur avendo letto e capito l’istruzione
interrupt cosa significa avendola vista in altri programmi qualè il suo scopo non riesco a capire come inserirla avrei bisogno quindi se possibile di qualche esempio o modo di capire. Ci conto molto

A risentirci e Grazie

Di seguito vi riporto la parte (provvisoria) del manuale che ho realizzato per i miei studenti che si riferisce agli interrupt (sto realizzando alcuni esempi pratici che chiarificano questa funzionalità), sono tratte dal reference on-line di Arduino.cc con alcune mie rielaborazioni.

Con il termine interrupt (interruzione) intendiamo un segnale asincrono che indica la necessità di “attenzione” da parte di una periferica collegata ad Arduino.
L’interrupt viene generato quando si verifica una variazione di stato su uno dei piedini di Arduino. Normalmente il microcontrollore esegue all’interno del loop() in modo sequenziale e ripetitivo le istruzioni in esso inserite, ma quando si verifica un interrupt viene interrotto il flusso delle istruzioni all’interno del loop() ed invocate altre routine (create dall’utente). Quando le routine terminano il flusso del programma prosegue normalmente.
L’utilizzo dell’interrupt è particolarmente utile quando abbiamo la necessità di gestitire in background alcune routine ovvero eseguire istantaneamente un’operazione nel caso si manifesti un evento asincrono esterno.

Capita spesso di avere la necessità di controllare lo stato di diversi pin di input, in questa situazione potrebbe capitare che il programma non si accorga del cambiamento di stato su uno dei pin, utilizzando gli interrupt evitiamo questo tipo di errore.

Esempio:

Supponete di dover rilevare lo stato di alcuni sensori esterni. All’interno del loop() tutte le istruzioni sono eseguite in modo sequenziale e quindi anche la rilevazione del cambiamento di stato dei sensori collegati ad Arduino avviene in modo sequenziale. Supponete di dover eseguire il controllo della variazione di stato di 3 sensori, il vostro sketch eseguirà il controllo sul primo sensore, sul secondo e poi sul terzo.

Supponete che tutti i sensori si trovino al medesimo stato iniziale che chiameremo S1 e che il controllo di Arduino sia in un determinato istante sul secondo sensore, potrebbe capitare nello stesso istante una variazione repentina di stato sul primo sensore che passa da S1 a S2 e poi a S1, Arduino non si accorgerà di nulla perché la sua attenzione è sul secondo sensore; ecco che in questa situazione potrebbe essere utile l’utilizzo degli interrupt.

La maggior parte delle schede Arduino hanno due piedini abilitati alla ricezione di interrupt:

pin digitale 2: interrupt 0
pin digitale 3: interrupt 1

L’Arduino mega dispone di 4 piedini abilitati alla ricezione di interrupt:

pin digitale 21: interrupt 2
pin digitale 20: interrupt 3
pin digitale 19: interrupt 4
pin digitale 18: interrupt 5

Funzioni utilizzate per gli interrupt

attachInterrupt(interrupt,funzione,modo)

istruzione che specifica la funzione da chiamare quando avviene interrupt (interruzione esterna).
Sostituisce ogni altra precedente funzione che è stata collegata all’interrupt.

funzione: è la funzione che viene chiamata quando si verifica l’interrupt; questa funzione non deve avere parametri e non deve restituire alcun valori; questa funzione a volte viene rinviata alle routine di gestione degli interrupt.

La rilevazione della variazione di stato sui pin di Arduino può avvenire in modi diversi è può essere configurata in funzione di come è impostato il parametro modo utilizzato per scatenare l’interrupt, questo parametro può assumere quattro valori

  • LOW l’interrupt viene eseguito quando il livello del segnale è basso
  • CHANGE l’interrupt viene eseguito quando avviene un cambiamento di stato sul pin
  • RISING l’interrupt viene eseguito quando si passa da un livello LOW ad un livello HIGH
  • FALLING l’interrupt viene eseguito quando si passa da un livello HIGH ad un livello LOW

Nota: all’interno della funzione utilizzata in attachInterrupt:

  • delay() non funziona;
  • il valore restituito dalla funzione millis() non verrà incrementato.
  • i dati seriali ricevuti durante l’esecuzione della funzione di interrupt possono essere sbagliati.
  • qualsiasi variabile modificabile all’interno della funzione attached (chiamata all’interno attachInterrupt) devono essere dichiarare come volatili.
int pin = 13;
volatile int state = LOW;

/* dichiariamo volatile la variabile
state usata nella funzione usata all'interno di attachInterrupt */

void setup()
{
pinMode(pin, OUTPUT); // definiamo pin output
attachInterrupt(0, blink, CHANGE);

// usiamo l'interrupt 0 che è associato al pin digitale 2
// attachInterrupt chiamerà la funzione collegata blink
// il modo per la rilevazione del cambiamento di stato
// sarà di tipo: CHANGE
// cioè l'interrupt viene eseguito quando avviene
// un qualsiasi cambiamento di stato sul pin

}

void loop()
{
digitalWrite(pin, state);
// il pin digitale 13 viene impostato a "state"
// che può essere LOW o HIGH
}

void blink()
// la funzione blink() esegue la funzione NOT di "state" cioè
// se state = LOW viene cambiato in HIGH, se state = HIGH viene cambiato in LOW

{
state = !state;
}
detachInterrupt(interrupt)

funzione che interrompe l’interrupt.
Il parametro “interrupt” definisce il numero dell’interrupt da disabilitare (0 oppure 1)

interrupts()

Abilita nuovamente gli interrupt (dopo che questi sono stati disabilitati da noInterrupts()).

Gli interrupts, abilitati per defalut, consentono ad eventi esterni di essere eseguiti in background.
Quando gli interrupts sono disabilitati, alcune funzioni non lavorano e le comunicazioni in arrivo (eventi esterni) potrebbero essere ignorate.
Gli interrupt possono variare leggermente il timing di esecuzione del codice per particolari sezioni critiche del codice possono essere disabilitati.

void setup( ) { }
void loop( ){
noInterrupts( );
// ... sezione critica, codice dipendente dal tempo
interrupts( );
// altro codice
}
noInterrupts()

disabilita interrupts (che sono stati abilitati con interrupts( ) ).

void setup() {}

void loop()
{
noInterrupts();
// ... sezione critica, codice dipendente dal tempo
interrupts();
// altro codice
}

Riferimenti:

Un pensiero su “Appunti su Arduino: interrupts

  1. Giorgio

    Buongiorno,
    ho mosso i primi passi con Arduino grazie alle sue lezioni, sempre chiare ed esaurienti.
    Ora sto cercando di implementare gli interrupts, purtroppo senza successo, o meglio non forniscono un risultato costante. Nelle mie prove ho collegato un pulsante ai due pin riservati su Arduino agli interrupts esterni, e considerando i rimbalzi (alla pressione del tasto il led si accende e spegne immediatamente), che non dovrebbero avvenire in pratica in quanto i cambiamenti di stato sono generati da un plc, se premo velocemente e consecutivamente il programma si blocca, non so cosa stia facendo e non saprei proprio come vedere che istruzione ha generato il blocco. Per riprendere devo premere il tasto reset di Arduino. Il mio problema è che il cambio di stato sui pin 2 e 3 avviene ogni 0,058333 secondi, che è quello che cerco di simulare premendo velocemente e consecutivamente il pulsante della prova.
    Può darmi qualche suggerimento?
    Grazie
    Saluti
    Giorgio

    Rispondi

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.