Accendiamo un LED con un Debounce (anti-rimbalzo) del pulsante Arduino
In questo progetto parleremo del debounce ossia in italiano anti-rimbalzo. Nel progetto Controlliamo un LED con un pulsante abbiamo visto come è possibile far accendere e spegnere un led tramite un pulsante. Se noi quel pulsante lo premiamo e lo rilasciamo molto velocemente possiamo notare delle instabilità, ad esempio il led rimane sempre acceso o viceversa. Questo fenomeno capita a causa della velocità di lettura del pulsante. In parole semplici per brevi tempi, Arduino non capisce se abbiamo effettivamente premuto il pulsante oppure no. La cosa migliore da fare, per risolvere il problema, è fare uso della funzione millis() per tenere traccia del tempo in cui si preme il pulsante. In pratica il programma memorizza lo stato di debounce (anti-rimbalzo) corrente del pulsante, ed è lo stato in cui siamo assolutamente certi che il pulsante sia HIGH se premuto, oppure LOW se rilasciato.
Per procedere con questo tutorial abbiamo necessità di un po’ di hardware elettronico:
- 1 breadboard
- 1 pulsante
- 1 led
- 1 resistenza da 220 Ohm
- 1 resistenza da 10 K Ohm
- filo elettrico per breadboard
- ed ovviamente Arduino
– Collegare alla resistenza da 220Ω la gamba del led più lunga.
– Collegare la gamba più corta del led al pin GND (ground) di Arduino.
Inserire il codice su Arduino tramite il software IDE. Se non lo avete scaricato seguite questa guida su come installare il software di Arduino.
/* Visita ArduinoFacile su: https://arduinofacile.altervista.org La Pagina Facebook di ArduinoFacile su: https://www.facebook.com/ArduinoFacile/ LED con Debounce (anti-rimbalzo) del pulsante fruttando millis() */ #define LED 13 // LED collegato al pin digitale 13 #define Pulsante 7 // pin di input dove è collegato il pulsante int val = 0; // si userà val per conservare lo stato del pin di input int vecchio_val = 0; // si userà vecchio_val per conservare lo stato del pin di input al passo precedente int statoLED = 0; // ricorda lo stato in cui si trova il LED, statoLED = 0 LED spento, statoLED = 1 LED acceso boolean StatoCorrente = LOW; // memorizza lo stato attuale del pulsante boolean UltimoStato = LOW; // memorizza l'ultimo stato del pulsante boolean StatoDebounce = LOW; // stato del pulsante debounce (anti-rimbalzo) int IntervalloDebounce = 20; // attendere 20 ms per il settaggio del pin del pulsante unsigned long UltimoEventoPulsante = 0; // memorizza l'ultima volta che è cambiato lo stato del pulsante void setup(){ pinMode(Pulsante, INPUT); // impostiamo il pin 7 come INPUT per il pulsante pinMode(LED, OUTPUT); // impostiamo il pin 13 come OUTPUT per il LED Serial.begin(9600); // inizializza la connessione seriale } void loop(){ StatoCorrente = digitalRead(Pulsante); unsigned long OraAttuale = millis(); if (StatoCorrente != UltimoStato){ UltimoEventoPulsante = OraAttuale; // aggiorna l'ora di questo nuovo evento } if (OraAttuale - UltimoEventoPulsante > IntervalloDebounce){ // se è trascorso abbastanza tempo if (StatoCorrente != StatoDebounce){ // se lo stato corrente è ancora diverso dal nostro ultimo stato di debounce memorizzato StatoDebounce = StatoCorrente; // aggiorna lo stato di debounce (anti-rimbalzo) //innesca un evento if (StatoDebounce == HIGH){ Serial.println("premuto"); // possiamo visualizzare dal monitor seriale l'evento del pulsante statoLED = 1 - statoLED; // imposta lo stato in cui si troverà il LED } else { Serial.println("rilasciato"); // possiamo visualizzare dal monitor seriale l'evento del pulsante } } } UltimoStato = StatoCorrente; if (statoLED == 1) { // se lo stato del LED è 1 digitalWrite(LED, HIGH); // accende il LED } else { // altrimenti digitalWrite(LED, LOW); // spegne il LED } }
In questo codice, notate le alcune variabili di archiviazione:
boolean StatoCorrente = LOW;
boolean UltimoStato = LOW;
int IntervalloDebounce = 20;
unsigned long UltimoEventoPulsante = 0;
StatoCorrente e UltimoStato memorizzano lo stato attuale e l’ultimo stato che era il pulsante, ma non ci dice lo stato del pulsante con certezza, perché potrebbe essere influenzato dal fenomeno transitorio di tipo oscillatorio del pulsante, chiamato microrimbalzo. Per capire meglio cos’è, essendo un qualunque pulsante costituito da lamelle che si toccano o no, a seconda che questo sia premuto o rilasciato, al momento della pressione/rilascio queste non si stabilizzano subito nella posizione voluta, ma si ha questo fenomeno così chiamato microrimbalzo:
Finché l’intenzione di utilizzare un pulsante per controllare l’accensione monostabile di un led (cioè quando è premuto è acceso, altrimenti è spento) allora questo fenomeno non è un problema.
Risulta comunque sprecato utilizzare un Arduino solamente per una funzione simile.
IntervalloDebounce è la quantità in ms (millisecondi) che aspetta quando si stabilizzi il pulsante prima di sapere con certezza in che stato si trova. UltimoEventoPulsante offre un tempo di confronto con OraAttuale (millis) in modo che possa contare quanti secondi sono passati dall’ultima rilevazione del pulsante.
In questa parte di codice, abbiamo reimpostato UltimoEventoPulsante ogni volta che StatoCorrente non è uguale all’ UltimoStato:
if (StatoCorrente ! = UltimoStato) {
UltimoEventoPulsante = OraAttuale;
}
Una volta trascorso abbastanza tempo senza dover reimpostare UltimoEventoPulsante, sappiamo che il pulsante si è stabilizzato in uno stato di rimozione:
OraAttuale- UltimoEventoPulsante > IntervalloDebounce
Quindi è possibile aggiornare lo stato di debounce attualmente memorizzato se è stato modificato e, in tal caso, attivare un evento in base al nuovo stato di debounce nel nostro caso, statoLED cambierà di stato, facendo accendere o spegnere il nostro LED:
if (StatoCorrente ! = StatoDebounce) {
StatoDebounce = StatoCorrente;
if (StatoDebounce == HIGH) {
Serial.println ( “premuto”);
statoLED = 1 – statoLED;
} else {
Serial.println ( “rilasciato”);
}
}