Go Down

Topic: [RISOLTO]problemi con debounce + chiarimento switch case per gestione menu (Read 1 time) previous topic - next topic

leo72

Io non voglio passare da quello che pontifica a destra e manca però dico e domando: se puoi fare una cosa con un semplice delay messo fra 2 letture successive perché andare a scomodare una libreria?  :smiley-sweat:

peppe123



Nulla.. direi che sono capitato nell' 1%  :)

forse c'è qualcosa di sbagliato nel codice?

Beh, intanto tu non usi il metodo che ti ho detto io ma uno basato sugli intervalli misurati con millis().  ;)

E poi mi pare che tu condivida la variabile lastButtonState per entrambi i pulsanti. Prova a mettere lastButtonStateDown e lastButtonStateUp perché ho come il timore che il problema sia qui.


risolto :)
ho messo lastButtonStateDown.. Up.. Left.. etc.. ora va perfettamente

grazie!

leo72

Bravo.
Ora arrivano le tiratine d'orecchie  ]:D

Code: [Select]
const int pulsanteUp = 1;     // pin pulate Up
const int pulsanteDown = 2;   // pin pulsante Down
const int pulsanteLeft = 3;   // pin pulsante Left
const int pulsanteRight = 4;  // pin pulsante Right
const int pulsanteEnter = 5;  // pin pulsante Enter
const int pulsanteEsc = 6;    // pin pulsante Esc

// variabili per lettura pulsanti
int statopulsanteUp = 0;
int statopulsanteDown = 0;
int statopulsanteLeft = 0;
int statopulsanteRight = 0;
int statopulsanteEnter = 0;
int statopulsanteEsc = 0;

// variabili per debouncing
int lastButtonState = LOW;
boolean flag = false;
long lastDebounceTime = 0;
long debounceDelay = 30;
//variabili lettura colonne e righe lcd
int numRighe = 0;
int numColonne = 0;

Sai queste dichiarazioni di variabili di tipo "int" quanto consuma in RAM?
30 byte! 30 byte quando ne potresti consumare 15 semplicemente usando il typo "byte".
A meno che tu non voglia ad esempio leggere il pulsante -15000 ;)
I pin del microcontrollore non arriveranno mai a 255, basta un tipo "byte"

Altra cosa.
Code: [Select]
long lastDebounceTime = 0;
long debounceDelay = 30;

è sbagliato. Ammettiamo che il tuo Arduino resti acceso per più di 25 giorni. Arriverai ad avere problemi con la gestione del valore restituito da millis() perché quest'ultimo è di tipo "unsigned long", non "long". Per cui quando arriverai a memorizzare un valore più grande di 2147483647 ti ritroverai con numeri negativi e non saprai perché  :P

peppe123

#8
Dec 10, 2012, 09:29 am Last Edit: Dec 10, 2012, 09:35 am by peppe123 Reason: 1
Grazie, praticamente sono al mio primo progetto, critiche e consigli sono ben accetti.
riposto il codice, magari mi aiutate a capire come posso creare un menu con sottomenu.. sto provando utilizzando solo switch case ma dal case 0 riesco a passare al case 1 poi sono bloccato li. come faccio a saltare da un case all'altro?
grazie
Code: [Select]

// include the library code:
#include <LiquidCrystalFast.h>

// initialize the library with the numbers of the interface pins
LiquidCrystalFast lcd(23, 25, 27, 29, 31, 33, 35, 37);
        // LCD pins: RS RW  E1  E2 D4 D5 D6 D7

// costanti per assegnazione pin
const int pulsanteUp = 1;     // pin pulate Up
const int pulsanteDown = 2;   // pin pulsante Down
const int pulsanteLeft = 3;   // pin pulsante Left
const int pulsanteRight = 4;  // pin pulsante Right
const int pulsanteEnter = 5;  // pin pulsante Enter
const int pulsanteEsc = 6;    // pin pulsante Esc

// variabili per lettura pulsanti
byte statopulsanteUp = 0;
byte statopulsanteDown = 0;
byte statopulsanteLeft = 0;
byte statopulsanteRight = 0;
byte statopulsanteEnter = 0;
byte statopulsanteEsc = 0;

// variabili per debouncing
int lastButtonStateUp = LOW;
int lastButtonStateDown = LOW;
int lastButtonStateLeft = LOW;
int lastButtonStateRight = LOW;
int lastButtonStateEnter = LOW;
int lastButtonStateEsc = LOW;


boolean flag = false;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 30;
//variabili lettura colonne e righe lcd
int numRighe = 0;
int numColonne = 0;

//variabile menu
unsigned int cont_pag = 0;

//carattere speciale per cursore di selezione menu
byte boccale[8] = {B00000, B01000, B11100, B11111, B11101, B11111, B11100, B00000,};


void setup() {
 //inizializza pin input dove sono collegati i pulsanti
 pinMode(pulsanteUp, INPUT);
 pinMode(pulsanteDown, INPUT);
 pinMode(pulsanteLeft, INPUT);
 pinMode(pulsanteRight, INPUT);
 pinMode(pulsanteEnter, INPUT);
 pinMode(pulsanteEsc, INPUT);
 

//creazione carattere speciale
 lcd.createChar(0, boccale);
 
// set lcd numero colonne e righe:
 lcd.begin(40, 4);

}

void loop() {
// lettura stato dei vari pulsanti
 statopulsanteUp = digitalRead(pulsanteUp);
 statopulsanteDown = digitalRead(pulsanteDown);
 statopulsanteLeft = digitalRead(pulsanteLeft);
 statopulsanteRight = digitalRead(pulsanteRight);
 statopulsanteEnter = digitalRead(pulsanteEnter);
 statopulsanteEsc = digitalRead(pulsanteEsc);
 
   
 
 
switch (cont_pag) {

 case 0:
 lcd.setCursor (numColonne, numRighe); lcd.write(0);
 lcd.setCursor (1, 0); lcd.print ("voce 1");
 lcd.setCursor (1, 1); lcd.print ("voce 2");
 lcd.setCursor (1, 2); lcd.print ("voce 3");
 lcd.setCursor (1, 3); lcd.print ("voce 4");
 lcd.setCursor (21, 0); lcd.print ("voce 5");
 lcd.setCursor (21, 1); lcd.print ("voce 6");
 lcd.setCursor (21, 2); lcd.print ("voce 7");
 lcd.setCursor (21, 3); lcd.print ("voce 8");
 
  if ((statopulsanteDown != lastButtonStateDown) && (flag==false))
    {
    flag=true;
    lcd.clear();
    if (statopulsanteDown==HIGH)//premo Down per spostare il cursore char
    numRighe--; lcd.setCursor (numColonne, numRighe); lcd.write(0);
    lastDebounceTime = millis();
    if (numRighe == -1 && numColonne == 0){numRighe = 3; numColonne = 20;lcd.clear();}
    if (numRighe == -1 && numColonne == 20){numRighe = 3; numColonne = 0;lcd.clear();}
   
    }    
        if (millis() > (lastDebounceTime + debounceDelay))
     flag = false;
     lastButtonStateDown = statopulsanteDown;
     
 

 if ((statopulsanteUp != lastButtonStateUp) && (flag==false))
    {
    flag=true;
    lcd.clear();
    if (statopulsanteUp==HIGH) //sposto verso l'alto il cursore char per selezionare voci del menu principale
    numRighe++; lcd.setCursor (numColonne, numRighe); lcd.write(0);
    lastDebounceTime = millis();
    if (numRighe == 4 && numColonne == 0){numRighe = 0; numColonne = 20;}
    if (numRighe == 4 && numColonne == 20){numRighe = 0; numColonne = 0;lcd.clear();}

    }
       if (millis() > (lastDebounceTime + debounceDelay))
     flag = false;
     lastButtonStateUp = statopulsanteUp;
     
 
    break;
 
 
       case 1:
 lcd.setCursor (1, 0);lcd.print("menu2");
 if ((statopulsanteRight != lastButtonStateRight) && (flag==false))
    {
    flag=true;
    lcd.clear();
    if (statopulsanteRight==HIGH)
    cont_pag = 2;
    lastDebounceTime = millis();
    lcd.clear();
    if (millis() > (lastDebounceTime + debounceDelay))
     flag = false;
     lastButtonStateRight = statopulsanteRight;
     
    }
 
    break;
   
    case 2:
 lcd.setCursor (1, 0);lcd.print("menu3");
    if ((statopulsanteLeft != lastButtonStateUp) && (flag==false))
    {
    flag=true;
    lcd.clear();
    if (statopulsanteLeft==HIGH)
    cont_pag = 0;
    lastDebounceTime = millis();
    lcd.clear();
    if (millis() > (lastDebounceTime + debounceDelay))
     flag = false;
     lastButtonStateLeft = statopulsanteLeft;
   
    }
 
    break;
   
 }

}

leo72

Secondo me stai sbagliando la logica del tuo programma.
cont_pag, che è la variabile controllata dallo switch, devi modificarla esternamente allo switch stesso, altrimenti non ha senso come hai fatto tu: mi pare di vedere che tu entri in uno case, lì dentro cambi il valore di cont_pag e poi il tuo programma riparte e rientra nello switch e da lì nel case impostato in precedenza, dove poi ricambi ancora cont_pag ecc....

La logica alla base dello switch..case è
Code: [Select]

var = imposto_la_variabile_con_qualcosa;
switch (var) {
  case 0:
    ...
    break;
  case 1:
    ..
    break;
  ecc....
}

Tu lo usi come una specie di salto, alla fine, per passare da un case all'altro.

Go Up