Puoi farlo usando interrupt esterni. La maggior parte degli Arduinos lo supporta solo su un numero limitato di pin. Per i dettagli completi, consultare la documentazione su attachInterrupt()
.
Supponendo che tu stia utilizzando uno Uno, potresti farlo in questo modo:
void pinChanged()
{
//...
}
void setup()
{
pinMode(2, INPUT);
attachInterrupt(0, pinChanged, CHANGE);
}
void loop()
{
}
Questo chiamerà pinChanged()
ogni volta che viene rilevata una modifica sull'interrupt esterno 0. Su Uno, che corrisponde al pin GPIO 2. La numerazione degli interrupt esterni è diversa su altre schede, quindi è importante controllare la relativa documentazione.
Vi sono tuttavia limiti a questo approccio. La pinChanged()
funzione personalizzata viene utilizzata come routine di servizio di interruzione (ISR). Ciò significa che il resto del codice (tutto in loop()
) viene temporaneamente arrestato durante l'esecuzione della chiamata. Al fine di prevenire l'interruzione di qualsiasi tempismo importante, si dovrebbe mirare a rendere gli ISR il più rapidamente possibile.
È anche importante notare che durante il tuo ISR non verranno eseguiti altri interrupt. Ciò significa che tutto ciò che si basa sugli interrupt (come il core delay()
e le millis()
funzioni) potrebbe non funzionare correttamente al suo interno.
Infine, se il tuo ISR deve modificare eventuali variabili globali nello schizzo, di solito dovrebbero essere dichiarate come volatile
, ad esempio:
volatile int someNumber;
Questo è importante perché dice al compilatore che il valore potrebbe cambiare inaspettatamente, quindi si dovrebbe fare attenzione a non utilizzare copie / cache non aggiornate.