Go Down

Topic: semplice menu (Read 128 times) previous topic - next topic

SimoneBez

Salve di nuovo Ragazzi,
per esigenze di programmazione volevo creare un piccolo menu a scorrimento, utilizzando un solo pulsante, una carrellata di valori da consultare durante il test sull'hardware:

Code: [Select]

 if (statopok == HIGH){
    flag ++;
    if (flag >= 9){
      flag = 0;   
    } else if (flag == 1){     
      while (flag == 1){
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("SEC PER CARICO1");
     lcd.setCursor(0,1);
     lcd.print(tempocarico1, 2);
     delay (500);
     if (statopok == HIGH){
     flag ++;}
     statopok = digitalRead(pulsok);
    }           
    } else if ( flag == 2){
      while (flag ==2){
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("SEC PER SCARICO1");
     lcd.setCursor(0,1);
     lcd.print(temposcarico1, 2);
     delay (500);
     if (statopok == HIGH){
    flag ++;}
    statopok = digitalRead(pulsok);
    }
    } else if (flag == 3) {
      while (flag ==3){
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("SEC PER CARICO2");
     lcd.setCursor(0,1);
     lcd.print(tempocarico2, 2);
     delay (500);
     if (statopok == HIGH){
     flag ++;}
     statopok = digitalRead(pulsok);
    }   
    } else if (flag == 4){
      while (flag ==4){
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("SEC PER SCARICO2");
     lcd.setCursor(0,1);
     lcd.print(temposcarico2, 2);
     delay (500);
     if (statopok == HIGH){
     flag ++;}
     statopok = digitalRead(pulsok);
    }     
    } else if (flag == 5){
      while (flag ==5){
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("val MODFLUX 1e2");
     lcd.setCursor(0,1);
     lcd.print(modflux);
     lcd.setCursor (6,1);
     lcd.print(modflux2);
     delay (500);
     if (statopok == HIGH){
     flag ++;}
     statopok = digitalRead(pulsok);
    }     
    } else if (flag == 6){
      while (flag ==6){
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("SEC PER CARICO3");
     lcd.setCursor(0,1);
     lcd.print(tempocarico3, 2);
     delay (500);
     if (statopok == HIGH){
     flag ++;}
     statopok = digitalRead(pulsok);
    }     
    } else if (flag == 7){
      while (flag ==7){
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("SEC PER SCARICO3");
     lcd.setCursor(0,1);
     lcd.print(temposcarico3);
     delay (500);
     if (statopok == HIGH){
     flag ++;}
     statopok = digitalRead(pulsok);
    }           
    }
}


ora,
ho inserito il while perchè più comodo, la mia idea era di lasciare a schermo il valore,
per il tempo a me necessario ma ad ogni pressione e rilascio di "pulsok"
mi esce dal loop del while come se fosse rimasto premuto....
ho provato ad inserire un delay per tagliare eventuali rimbalzi sul tasto ma niente...

che ne dite?che sbaglio?

torn24

Rivedrei il menu e lo realizzerei con una macchina a stati finiti! In realtà il tuo menù è già una macchina a stati finiti ma implementata veramente male :)

Ecco un link dove prendere spunto
http://spectrum.altervista.org/programmazione-stati-finiti/

paolo311

Tempo fa per un classico "killer device" avevo fatto una cosa simile, un pulsante che permetteva di scorrere valori e poi se non premevi per un certo intervallo tornava al valore di default.

Io ho trovato comodo separare le gestione del pulsante da quella di visualizzazione.
In pratica il pulsante lo puoi gestire così:

Code: [Select]

bool WaitForEvents()
{
    bool somethingHappened = false;

    if (digitalRead(buttonPin)
        && (millis() - tButton) > debounceInterval)
    {
        menu++;
        if (menu > ITEMS)
            menu = 0;

        tButton = millis();
        somethingHappened = true;
    }

    if (menu > 0
        && (millis() - tButton > cancelInterval))
    {
        menu = 0;
        somethingHappened = true;
    }

    return somethingHappened;
}


dove debounceInterval serve per gestire il debounce, ITEMS è il numero massimo di voci visualizzabile, cancelInterval è il tempo da attendere prima che si torni alla posizione di "riposo"

all'uscita dalla funzione la variabile "menu" contiene la voce da visualizzare
Che puoi gestire facilmente con uno switch tipo questo:

Code: [Select]

    switch (menu)
    {
        case TEMPERATURE_ITEM:
            showTemperature();
            break;

        case HUMIDITY_ITEM:
            showHumidity();
            break;
:
:

etc.



Ciao

Go Up