Go Down

Topic: Analog antibounce (Read 558 times) previous topic - next topic

Hydrarian

Sep 13, 2013, 10:32 am Last Edit: Sep 13, 2013, 10:34 am by Hydrarian Reason: 1
Rieccomi di nuovo qua. So che l'argomento è ampiamente trattato ovunque, ma tutti gli antibounce che ho trovato sono per i digitalRead. Nel mio caso io leggo i valori analogici con un analogRead (li leggo tutti sul pin A0) e quindi ho dei range, non HIGH e LOW. Visto che i pulsanti a volte non sembrano rispondere come vorrei, mi chiedevo se il funzionamento dei debounce che ho visto funziona anche per valori analogici. Posto il mio codice nel caso fosse mio l'errore.

Code: [Select]

// Costanti globali per i pulsanti
#define buttonPin 0 // input analogico
#define debounce 10 // in ms: periodo di debounce (tra una pressione e un'altra)
#define tolleranza 2000 //(500)in ms: periodo di tolleranza di pressione azione/non azione
#define holdTime 5000 // in ms: tempo che bisogna aspettare per andare all'evento press+hold

// variabili pulsanti
int buttonVal = 0; // valore letto dal pulsante
int buttonLast = 0; // valore dello stato dell'ultimo pulsante premuto (se è zero vuol dire che è passato del tempo da una pressione all'altra)
unsigned long btnDnTime; // tempo in cui il pulsante è premuto
unsigned long btnUpTime; // tempo in cui il pulsante è rilasciato
boolean ignoreUp = false; // whether to ignore the button release because the click+hold was triggered

int last_Pressed = 6;  //ultimo pulsante premuto: serve per riconoscere quando si cambiano i pulsanti in modo da saltare da una parte del menu all'INIZIO di un'altra
int current_Pressed =  6;
int i;  // indice del menù
int cambiostato = 0; // presa 1: indice di stato temporaneo (stato non selezionato, solo scorso) Serve a mantenere traccia dello stato così da poterlo selezionare quando si tiene premuto il pulsante

void switchPulsanti(){
 if (buttonVal == 0 && buttonLast != 0 && (millis() - btnUpTime) > long(debounce))
 {
   btnDnTime = millis();
 }


 // Pulsante P1 (SHORT): scorrimento
 if (buttonVal > 886 && buttonLast == 0 && (millis() - btnDnTime) > long(debounce) && (millis() - btnDnTime) < tolleranza)
 {
   current_Pressed=0;  // setto il pulsante che premo
   if (last_Pressed != current_Pressed) i=0; // controllo se il pulsante premuto prima di quello attuale: nel caso resetto l'indice del menu in modo da riniziare dalla prima voce quando cambio menu presa
   if (ignoreUp == false) scorri(0); //SCORRIMENTO
   else ignoreUp = false;
   btnUpTime = millis();
   last_Pressed=0;  // setto il pulsante che ho appena premuto per il prossimo confronto
 }


 // Pulsante P1 (LONG): selezione
 if (buttonVal > 886 && last_Pressed==0 && (millis() - btnDnTime) > long(holdTime) && current_Pressed==last_Pressed)
 {
   seleziona(0);  //SELEZIONE
   scorrimento_orizzontale(0); //riconosco che ho premuto il pulsante 0 e vado a scorrere le voci del menu
   ignoreUp = true;
   btnDnTime = millis();
 }

 // Pulsante P2 (SHORT): scorrimento
 if (buttonVal > 624 && buttonVal < 885 && buttonLast == 0 && (millis() - btnDnTime) > long(debounce) && (millis() - btnDnTime) < tolleranza)
 {
   current_Pressed=1;
   if (last_Pressed != current_Pressed) i=0;
   if (ignoreUp == false) scorri(1);
   else ignoreUp = false;
   btnUpTime = millis();
   last_Pressed=1;
 }


 // Pulsante P2 (LONG): selezione
 if (buttonVal > 624 && buttonVal < 885 && (millis() - btnDnTime) > long(holdTime) && current_Pressed==last_Pressed)
 {
   seleziona(1);
   scorrimento_orizzontale(1); //riconosco che ho premuto il pulsante  e vado a scorrere le voci del menu
   ignoreUp = true;
   btnDnTime = millis();
 }


 // Pulsante P3 (SHORT): scorrimento
 if (buttonVal > 436 && buttonVal < 623 && buttonLast == 0 && (millis() - btnDnTime) > long(debounce) && (millis() - btnDnTime) < tolleranza)
 {
   current_Pressed=2;
   if (last_Pressed != current_Pressed) i=0;
   if (ignoreUp == false) scorri(2);
   else ignoreUp = false;
   btnUpTime = millis();
   last_Pressed=2;
 }


 // Pulsante P3 (LONG): selezione
 if (buttonVal > 436 && buttonVal < 623 && (millis() - btnDnTime) > long(holdTime) && current_Pressed==last_Pressed)
 {
   seleziona(2);
   scorrimento_orizzontale(2); //riconosco che ho premuto il pulsante  e vado a scorrere le voci del menu
   ignoreUp = true;
   btnDnTime = millis();
 }


 // Pulsante P4 (SHORT): scorrimento
 if (buttonVal > 334 && buttonVal < 435 && buttonLast == 0 && (millis() - btnDnTime) > long(debounce) && (millis() - btnDnTime) < tolleranza)
 {
   current_Pressed=3;
   if (last_Pressed != current_Pressed) i=0;
   if (ignoreUp == false) scorri(3);
   else ignoreUp = false;
   btnUpTime = millis();
   last_Pressed=3;
 }


 // Pulsante P4 (LONG): selezione
 if (buttonVal > 334 && buttonVal < 435 && (millis() - btnDnTime) > long(holdTime) && current_Pressed==last_Pressed)
 {
   seleziona(3);
   scorrimento_orizzontale(3); //riconosco che ho premuto il pulsante  e vado a scorrere le voci del menu
   ignoreUp = true;
   btnDnTime = millis();
 }


 // Pulsante P5 (SHORT): setta l'ora
 if (buttonVal > 1 && buttonVal < 333 && buttonLast == 0 && (millis() - btnDnTime) > long(debounce) && (millis() - btnDnTime) < tolleranza)
 {
   setManualClock();
 }


 // Pulsante P5 (LONG): ritorna
 if (buttonVal > 100 && buttonVal < 333  && (millis() - btnDnTime) > long(holdTime) && current_Pressed==last_Pressed)
 {
   Serial.println("Cambio");
   step++;
   ignoreUp = true;
   btnDnTime = millis();
 }
 buttonLast = buttonVal;
}


ratto93

Puoi mettere un piccolo condensatore al poliestere da una decina o un centinaio di picoFarad in tra il pin che vuoi leggere e massa, in questo modo stabilizzi la lettura anche se la reattività diminuisce ma si parla di cose nell'ordine di uS quindi non percettibile ad occhio
Se corri veloce come un fulmine, ti schianterai come un tuono.

Hydrarian

Per quanto riguarda il software non ci sono soluzioni?

gingardu

#3
Sep 19, 2013, 08:43 am Last Edit: Sep 20, 2013, 06:50 am by gingardu Reason: 1
il debounce te lo fai tu a piacimento  ]:D

con l'aiuto del Blink without Delay  
appena la lettura analogica supera il valore stabilito da te   assegni 1 a una variabile  che mantiene questo stato per tot millisecondi (a tua scelta)  
poi quando  la lettura analogica non supera il valore stabilito da te ed il tempo in millisecondi stabilito da te  è passato   la variabile torna a zero
questa e la base (per me)  poi puoi renderlo più sofisticato come desideri
ricordarsi che le cose su arduino non tornano al punto di partenza se non glielo "ordini"

Code: [Select]


byte pulsante_premuto = 0;  //  variabile che passa da 0 a 1 se viene premuto il pulsante
byte variabile_disupporto = 0;
long previousMillis = 0;      

long interval = 1000; // questo e il tempo che il led rimane acceso (o variabile pulsante_premuto rimane a 1 )quando si rilascia/spegne il pulsante

void setup() {pinMode (13, OUTPUT);  // messo solo per avere un effetto visivo del pulsante premuto  (si accende/spegne il led)
}

void loop()
{

 unsigned long currentMillis = millis();

 if(currentMillis - previousMillis > interval) {
 
if (analogRead (A0) > 500 && variabile_disupporto == 0) // se tutte queste condizioni sono vere si eseguono quelle della prossima riga
pulsante_premuto = 1, previousMillis = currentMillis, variabile_disupporto = 1, digitalWrite (13, HIGH);
     
if (analogRead (A0) < 500  && currentMillis - previousMillis > interval)  pulsante_premuto = 0, variabile_disupporto = 0, digitalWrite (13, LOW) ;


 }
}
Le cose si possono considerare facili in due casi: quando le si conosce bene o quando non le si conosce affatto...

ratto93

Ma senza usare i millis() puoi tranquillamente fare la lettura metterci un ritardo delay(xx) e poi riesegui la lettura.
Se corri veloce come un fulmine, ti schianterai come un tuono.

Hydrarian

Il delay in questo caso non va bene perché arduino resta inattivo, mentre a me serve qualcosa che non blocchi l'esecuzione del programma. Seguirò il tuo consiglio, gingardu, grazie.

ratto93

tieni conto che comunque lo puoi fare con delaymicrosecond ed ovviamente sono microsecondi che perdi di tempo, comunque se la tua app ha bisogno di non aver blocchi millis è la retta via :)
Se corri veloce come un fulmine, ti schianterai come un tuono.

Go Up