Ciao, volevo condividere con voi questo piccolo sketch per gestire in un modo un po alternativo l'antirimbalzo di un bottone. Sembra una cosa da poco ma una gestione del genere potrebbe essere utile per gestire poi con Arduino anche una piccola tastiera perchè in questo modo evito degli stalli del codice.
In pratica creo un buffer circolare per evitare di attendere anche poco tempo in un applicazione embedded. Si tratta di creare un piccolo automa che viene richiamato ad intervalli di tempo fissi, ad esempio lo richiamo all’interno di una routine di interrupt di un timer o cose simili. Ad ogni interrupt viene letto lo stato dell’ingresso, supponiamo che con il pulsante non premuto sia a 0. Lo stato del pulsante viene memorizzato in una variabile intera, es. un byte non prima di aver shiftato il suo contenuto a sx di una posizione (0)00000000. Quando il pulsante viene premuto viene premuto e per la prima volta viene letto lo stato a 1, il contenuto del byte diventa (1)000001. Se al passaggio successivo per un rimbalzo lo stato è a zero si avrà (2)00000010. Se al passaggio successivo lo stato viene riconosciuto a 1 si avrà (3)00000101. Ne passaggi successivi ad ogni passo l’evoluzione risulta:
(4 ) 00001011
(5) 00010111
(6) 00101111
(7) 01011111
(8) 10111111
(9) 01111111
(10)11111111
Se ad ogni passo verifichi se il contenuto del byte risulta pari a 01111111 e assegni a questo valore il riconoscimento del pulsante premuto ti rendi conto che solamente al passaggio (9) riconosci la pressione del pulsante.
Analogamente se vuoi rilevare il rilascio del pulsante senza rimbalzo puoi controllare che il contenuto sia ad esempio 11111110.
per l'esempio non ho utilizzato l'interrupt ma una chiamata in polling.
#define KEY_OFF 1000
#define KEY_PRESS 1001
#define KEY_HOLD 1011
#define KEY_REL 1010
#define btnPin 3
#define ledPin 13
//byte per lo stato del bottone
byte btnStatus = 0x0;
void setup(){
pinMode(btnPin, INPUT);
pinMode(ledPin, OUTPUT);
}
void loop(){
if(getInputSwitchStatus() == KEY_PRESS){
digitalWrite(ledPin, HIGH);
}
if(getInputSwitchStatus() == KEY_HOLD){
//BOTTONE PREMUTO
}
if(getInputSwitchStatus() == KEY_REL){
digitalWrite(ledPin, LOW);
}
}
int getInputSwitchStatus(){
//SFHIT stato tasto
btnStatus <<= 1;
if(digitalRead(btnPin)){
btnStatus |= 0x01;
delay(10);
}
if( btnStatus == 0 ) return KEY_OFF;
else if( btnStatus == 0x7F ) return KEY_PRESS;
else if( btnStatus == 0xFF ) return KEY_HOLD;
else if( btnStatus == 0xFE ) return KEY_REL;
else return "KEY_NO_PRESS";
}
che ve ne pare?