Go Down

Topic: Switch Case Menu Problem (Read 3254 times) previous topic - next topic

paul23

I´m building a menu system for a timer I am working on.  Its my first proper project and I am trying to do as much of it as I can on my own, but i´m stumped by one particular problem.

What I am trying to is have a main menu with several sub-menus where you change options, etc.  So far I have got to the first option ("logs") and while the main menu and sub menu work, the last option in the sub menu ("back") doesn´t work.  What it should do when you press SW2 (a push button) is go back to the main menu, but instead it reverts back to the first option in "logs" menu.

Here is the relevant code,
Code: [Select]
void mainmenu(){
     switch (menuLV1){
           case 0: //LOGS
                 LCDmsgNo = 5;  
                 LCD2msgNo = 1;
                 if (SW1State == LOW && SW2State == HIGH && SW2PrevState == LOW){
                 logsMenu = 1;
                 }
                 break;
           case 1: //Settings
                 LCDmsgNo = 6;
                 LCD2msgNo = 1;
                 break;
           case 2: //Information
                 LCDmsgNo = 14;
                 LCD2msgNo = 1;
                 break;
           case 3: //Advanced Settings
                 LCDmsgNo = 7;
                 LCD2msgNo = 1;
                 break;
     }
     // Cycle through Menu Options
     if (SW1State == HIGH && SW2State == LOW && SW1PrevState == LOW){
     menuLV1++;
     }
     // Loop back to begining of menu
     if (securityLvL == 0 && menuLV1 > 2){ //normal user
       menuLV1 = 0;
   }
     if (securityLvL == 1 && menuLV1 > 3){ //Engineer
       menuLV1 = 0;
   }
     ////////// LOGS MENU /////////////
     if (logsMenu > 0){ // Only Run if logsMenu is Activated
           if (logsMenu > 4){  //returns menu cycle back to beginning
           logsMenu = 1;
           }
           switch (logsMenu){
           
                 case 1: // Total Credit
                       LCDmsgNo = 9;
                       LCD2msgNo = 4;
                       if (SW1State == HIGH && SW1PrevState == LOW) {
                       logsMenu ++;
                       }
                       break;
           
                 case 2:  // Credit in Coin Box
                       LCDmsgNo = 10;
                       LCD2msgNo = 5;
                       if (SW1State == HIGH && SW1PrevState == LOW) {
                       logsMenu ++;
                       }
                       break;
           
                 case 3: //Total Power Consumption
                       LCDmsgNo = 11;
                       LCD2msgNo = 6;
                       if (SW1State == HIGH && SW1PrevState == LOW) {
                       logsMenu ++;
                       }
                       break;
           
                 case 4: //Back
                       LCDmsgNo = 12;
                       LCD2msgNo = 1;
                       if (SW1State == HIGH && SW1PrevState == LOW) {
                       logsMenu = 1;
                       }
                       if (SW2State == HIGH && SW2PrevState == LOW) {
                       menuLV1 = 1;
                       logsMenu = 0;
                       }
                       break;
           }
  }
}


I can post the rest of the code if required, but I think the problem lies somewhere here.  Either I have misunderstood the use of Switch Case or I´m doing something dumb.

Thanks for any help you can give.

Coding Badly


Nothing jumps out at me.

enums would be a nice replacement for the the integer constants.

PaulS

Use some Serial.print() statements to confirm that the switch states are what you expect them to be, and to see what path is actually taken through the code.

paul23

Ok I tried with the serial.print (very good idea BTW) and found that selecting the back option change the logsmenu value to 1 not 0 like it should do.  The thing is I´ve no idea why, the way I see the code it should be 0.

PaulS

Print out more stuff, then, like menuLV1, SW1PrevState, SW2PrevState, etc.

You may need to post all of your code.

Where are you reading the switch states? Are you debouncing the switches?

paul23

After a bit more searching with the serial monitor I have discovered that I was geting a double press of any button.  However, I have just tried it again to get a print out for this post and I am no longer getting the double push thing, but the menu is still not working.  

Here is how I am doing the switches,
Code: [Select]
void SWstates () { //Sets the switch States
     SW1CurrentState = digitalRead(SW1);  //Get Current State of SW1
     SW2CurrentState = digitalRead(SW2);  //Get Current State of SW2
     SW3CurrentState = digitalRead(SW3);  //Get Current State of SW3
     SW4CurrentState = digitalRead(SW4);  //Get Current State of SW4
     //Sets SW1 State and debounces
     if (SW1CurrentState != SW1PrevState) {  
           SW1DebounceTime = millis();  // reset the debouncing timer
     }
     if ((millis() - SW1DebounceTime) > debounceDelay) {
       SW1State = SW1CurrentState;
     }
       if (SW1PrevState == HIGH && SW1CurrentState == HIGH && (millis() - SW1DebounceTime) > 3000) {
       SW1StateHeld = 1;
     }
     else {
     SW1StateHeld = 0;
     }
     SW1PrevState = SW1CurrentState;


       //repeats if statements for the other buttons
}

The debounce delay is 50ms.
I think I need to look at a different way to do this bit, which I will do when I get home.

EVP

You can get IC's for debouching switches i think so you don't have to do it in software

AWOL

#7
Jan 21, 2011, 06:42 pm Last Edit: Jan 21, 2011, 06:43 pm by AWOL Reason: 1
But ICs cost money.
I'm a little surprised that someone from Yorkshire missed that.
I'm guessing you're not a native.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Go Up