Si vuole attivare un led tramite la pressione di un pulsante. Alla pressione del pulsante il led si accende, alla pressione successiva si spegne.

 

Soluzione tramite polling:

Si fa l'ipotesi che il pulsante non abbia rimbalzi.

#define ledpin 13
#define buttonpin 2

bool buttonState = LOW;
bool statoLed = LOW;

void setup()
{
pinMode(buttonpin, INPUT);
pinMode(ledpin, OUTPUT);

digitalWrite(ledpin, LOW);
}

void loop()
{
// inizio sequenza di polling
buttonState = digitalRead(buttonpin);
if (buttonState == HIGH) {
if (statoLed == LOW) {
digitalWrite(ledpin, HIGH); // accendi il led
statoLed = HIGH;
} else {
digitalWrite(ledpin, LOW); // spegni il led
statoLed = LOW;
}
while (digitalRead(buttonpin) == HIGH); // attende che il pulsante venga rilasciato
}
// fine sequenza di polling

}

Soluzione tramite interrupt:

 

L'algoritmo si compone di due parti:

  • Il programma principale
  • La routine di interrupt che viene eseguita quando avviene una richiesta di interrupt tramite un segnale di interrupt

La codifica per Arduino viene qui sotto riportata. Si nota come la gestione degli interrupt preveda la possibilità di controllare anche le singole transizioni:

  • RISING: l'interrupt viene attivato quando il livello logico del pin passa da LOW a HIGH
  • FALLING: l'interrupt viene attivato quando il livello logico del pin passa da HIGH a LOW
  • CHANGE: l'interrupt viene attivato in corrispondenza ad un cambio di livello logico qualsiasi
  • LOW: l'interrupt viene attivato quando il livello logico è LOW

e quindi non è necessario attendere il rilascio del pulsante (anche in questo caso si fa l'ipotesi che il pulsante sia ideale, quindi privo di rimbalzi)

Il programma prevede anche l'attivazione degli interrupt della fase di setup. Per approfondimenti sull'implementazione con Arduino è possibile consultare la guida online all'indirizzo https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

#define ledpin 13
#define buttonpin 2

/* Le variabili utilizzate all'interno delle routine di interrupt vanno
* dichiarate di tipo volatile affinché il compilatore le tratti
* nel modo corretto
*/
volatile bool buttonState = LOW;
volatile bool statoLed = LOW;

void setup()
{
pinMode(buttonpin, INPUT);
pinMode(ledpin, OUTPUT);

digitalWrite(ledpin, LOW);
/* usiamo l'interrupt associato al pin digitale 2
* (non tutti i pin di Arduino permettono gli interrupt)
* attachInterrupt chiamerà la funzione "interruptRoutine"
* il modo per la rilevazione dell'interrupt è RISING,
* cioè l'interrupt viene eseguito quando avviene
* un cambiamento di stato da LOW a HIGH sul pin
*/
attachInterrupt(digitalPinToInterrupt(buttonpin), interruptRoutine, RISING);
}

void loop()
{
// Nel loop non viene fatto nulla
}

void interruptRoutine(){
if (statoLed == LOW) {
digitalWrite(ledpin, HIGH); // accendi il led
statoLed = HIGH;
} else {
digitalWrite(ledpin, LOW); // spegni il led
statoLed = LOW;
}
}
Ultime modifiche: mercoledì, 10 gennaio 2024, 18:35