C Language How to Get a Submenu to Execute Properly?

Gavin Shuffield's picture

Offline

Joined: Apr 22, 2021

Replies: 4
C Language How to Get a Submenu to Execute Properly?
April 22, 2021 - 1:32am

When I run the below code, I can see the program hit the "void WaitBtnRelease()" but it only loops twice then goes into the LevelmenuBtn and drops directly into case 1. I can't figure out how to get it to display the submenu and scroll through LevelMenuPage. I am using an Arduino Mega 2560 with a 16x2 LCD Keypad Shield. My flow intent is: Start -> MainMenuDisplay() -> Case 4: "Setup" -> LevelMenuDisplay(); -> BreaksHere Scroll LevelMenuDisplay for selection.

I know it is a lot of code, but I wanted it to be fully easily reproduceable for someone that has an Arduino and a LCD Keypad Shield.

 

#include <LiquidCrystal.h> //from newliquidcrystal library
 LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int keypad_pin = A0;
int keypad_value = 0;
int keypad_value_old = 0;
int pwtry = 0;
int mybutton = 1;

bool menu2 = false;
bool qr = false;
bool safeopen = false;
bool btqr = false;

char btn_push;

int selection1 = 0;
int selection2 = 0;
int mainMenuPage = 1;
int mainMenuPageOld = 1;
int mainMenuTotal = 4;
int levelMenuPage = 1;
int levelMenuPageOld = 1;
int levelMenuTotal = 6;

String qrpw;
String qrpwconf;
String qrpwconf2;
String qrpwread;
String openpw;
String openpwconf;
String openpwconf2;
String openpwread;
String currentopenpw;
String currentqrpw;
String qrtimer;

void setup()
{
Serial.begin(9600);
lcd.begin(16,2);  //Initialize a 2x16 type LCD
MainMenuDisplay();
delay(1000);

}
void loop()
{
MainmenuBtn();


if((btn_push == 'S')&&(menu2 == false))//enter selected menu
{
    WaitBtnRelease();
    switch (mainMenuPage)
    {
        case 1:
          QuickReleaseMenu();
          break;
        case 2:
          OpenMenu();
          break;
        case 3:
          DisableQR();
          break;
        case 4:
          menu2 = true;
          break;
    }

      MainMenuDisplay();
      WaitBtnRelease();
  }
  else
{
   if((btn_push == 'S')&&(menu2 == true))//enter selected menu
   {
     LevelmenuBtn();
     WaitBtnRelease();
     switch (levelMenuPage)
  {
    case 1:
       Serial.println("setqrpw");
       SetQRPW();
       break;
    case 2:
       SetOpenPW();
       break;
    case 3:
       enableBTQR();
       break;
    case 4:
       AddBTDevice();
       break;
    case 5:
       RmvBTDevice();
       break;
    case 6:
       FactoryReset();
       break;
    }

      LevelMenuDisplay();
      WaitBtnRelease();
    }
    delay(10);
}
delay(10);
}
//--------------- End of loop() loop ---------------------
void MainmenuBtn()
{
  btn_push = ReadKeypad();
WaitBtnRelease();
if(btn_push == 'U')
{
    mainMenuPage++;
    if(mainMenuPage > mainMenuTotal)
      mainMenuPage = 1;
      Serial.println(mainMenuPage);
}
else if(btn_push == 'D')
{
    mainMenuPage--;
    Serial.print(mainMenuPage);
    if(mainMenuPage == 0)
      mainMenuPage = mainMenuTotal; 
      Serial.println(mainMenuPage);   
}

if(mainMenuPage != mainMenuPageOld) //only update display when page change
{
    MainMenuDisplay();
    mainMenuPageOld = mainMenuPage;
}
}
void LevelmenuBtn()
{
  btn_push = ReadKeypad();
  WaitBtnRelease();
if(btn_push == 'U')
{
    mainMenuPage++;
    if(levelMenuPage > levelMenuTotal)
      levelMenuPage = 1;
      Serial.println(levelMenuPage);
}
else if(btn_push == 'D')
{
    levelMenuPage--;
    Serial.print(levelMenuPage);
    if(levelMenuPage == 0)
      levelMenuPage = levelMenuTotal; 
      Serial.println(levelMenuPage);   
}

if(levelMenuPage != levelMenuPageOld) //only update display when page change
{
    LevelMenuDisplay();
    levelMenuPageOld = levelMenuPage;
}
}

void MainMenuDisplay()
{
lcd.clear();
lcd.setCursor(0,0);
switch (mainMenuPage)
{
    case 1:
      lcd.print("Quick Release");
      break;
    case 2:
      lcd.print("Open");
      break;
    case 3:
      lcd.print("Disable QR");
      break;
    case 4:
      lcd.print("Setup");
      menu2 = true;
      break;
}
}
void LevelMenuDisplay()
{
lcd.clear();
lcd.setCursor(0,0);
switch (levelMenuPage)
{
    case 1:
      lcd.print("Set QR PW");
      break;
    case 2:
      lcd.print("Set Open PW");
      break;
    case 3:
      lcd.print("Dis QR Confirm?");
      break;
    case 4:
      lcd.print("Factory Reset");
      break;
}
}



void QuickReleaseMenu()
{  
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Enter QR PW:");
lcd.setCursor(0,1);
while (Serial.available() == 0){}
qrpw = Serial.readString();
lcd.print(qrpw);
delay(500);
  if (currentqrpw == qrpw){
    qr=true;
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Quick Release");
    lcd.setCursor(0,1);
    lcd.print("Enabled");
    delay(1000);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Set Timer:");
    while (Serial.available() == 0){}
    qrtimer = Serial.readString();
    lcd.print(qrtimer);
    //----------------------Set Timer for RTC here---------------------------------
    delay(2000);
    }
  else if (currentqrpw != qrpw){
    lcd.clear();
    lcd.setCursor(0,0);
    pwtry = pwtry + 1;
    if (pwtry == 3){
      lcd.print("Too Many Attempts");
      pwtry = 0;
      delay(2000);
      MainMenuDisplay();
      }
    else{
      lcd.print("Incorrect PW");
      lcd.setCursor(0,1);
      lcd.print("Try Again");
      delay(2000);
      QuickReleaseMenu();
      }
  }
  
menu2 = true;
}


void OpenMenu()
{  
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Enter Open PW:");
lcd.setCursor(0,1);
while (Serial.available() == 0){}
openpwread = Serial.readString();
lcd.print(openpwread);
delay(500);
  if (currentopenpw == openpwread){
    safeopen=true;
    //--------------Open Lock Here-----------------
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Safe Open");
    delay(1000);
    }
  else if (currentopenpw != openpwread){
    lcd.clear();
    lcd.setCursor(0,0);
    pwtry = pwtry + 1;
    if (pwtry == 3){
      lcd.print("Too Many Attempts");
      pwtry = 0;
      delay(2000);
      menu2 = false;
      MainMenuDisplay();
      }
    else{
      lcd.print("Incorrect PW");
      lcd.setCursor(0,1);
      lcd.print("Try Again");
      delay(2000);
      OpenMenu();
      }
    }
  
menu2 = true;
}


void DisableQR()
{  
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Disable QR?");
//delay(500);
lcd.setCursor(0,1);
Serial.println(mybutton);
while (mybutton == 1){
btn_push = ReadKeypad();
Serial.println(btn_push);
WaitBtnRelease();
delay(100);
if(btn_push == 'S')
    {
    //delay(500);
    mybutton = 2;
    ConfDisQR();
    break;
    }
  else if (btn_push == 'L'){
   // delay(500);
   mybutton = 2;
    MainMenuDisplay();
    break;
    }
}
}

void ConfDisQR()
{  
lcd.clear();
lcd.setCursor(0,0);
qr=false;
mybutton = 1;
lcd.print("QR Disabled");
delay(1000);
menu2 = false;
}

void MenuD2()
{  
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Inside Menu D2");
delay(2000);
menu2 = false;
} 

void SetQRPW()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Enter QR PW:");
lcd.setCursor(0,1);
while (Serial.available() == 0){}
qrpw = Serial.readString();
lcd.print(qrpwread);
delay(500);
  if (currentqrpw == qrpwread){
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Enter New QR PW");
    lcd.setCursor(0,1);
    while (Serial.available() == 0){}
    qrpwconf = Serial.readString();
    lcd.print(qrpwconf);
    delay(1000);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Confirm QR PW");
    while (Serial.available() == 0){}
    qrpwconf2 = Serial.readString();
    lcd.print(qrpwconf2);
    delay(1000);
    if (qrpwconf == qrpwconf2){
      qrpw = qrpwconf;
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("QR PW SET");
      currentqrpw = qrpwconf;
    }
  else if (qrpwconf != qrpwconf2){
    lcd.clear();
    lcd.setCursor(0,0);
    pwtry = pwtry ++;
    if (pwtry == 4){
      lcd.print("Too Many Attempts");
      pwtry = 0;
      delay(2000);
      MainMenuDisplay();
      }
    lcd.print("PW Do Not Match");
    lcd.setCursor(0,1);
    lcd.print("Try Again");
    delay(2000);
    SetQRPW();
    }
  
menu2 = true;
}

}
void SetOpenPW()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Enter Open PW:");
lcd.setCursor(0,1);
while (Serial.available() == 0){}
openpwread = Serial.readString();
lcd.print(openpwread);
delay(500);
  if (currentqrpw == qrpwread){
    qr=true;
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Enter New QR PW");
    lcd.setCursor(0,1);
    while (Serial.available() == 0){}
    openpwconf = Serial.readString();
    lcd.print(openpwconf);
    delay(1000);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Confirm QR PW");
    while (Serial.available() == 0){}
    qrpwconf2 = Serial.readString();
    lcd.print(openpwconf2);
    delay(1000);
    if (qrpwconf == qrpwconf2){
      openpw = openpwconf;
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Open PW SET");
    }
  else if (openpwconf != openpwconf2){
    lcd.clear();
    lcd.setCursor(0,0);
    pwtry = pwtry ++;
    if (pwtry == 4){
      lcd.print("Too Many Attempts");
      pwtry = 0;
      delay(2000);
      MainMenuDisplay();
      }
    lcd.print("PW Do Not Match");
    lcd.setCursor(0,1);
    lcd.print("Try Again");
    delay(2000);
    SetOpenPW();
    }
  
menu2 = true;
}
}

void enableBTQR()
{  
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Enter QR PW:");
lcd.setCursor(0,1);
while (Serial.available() == 0){}
qrpw = Serial.readString();
lcd.print(qrpw);
delay(500);
  if (currentqrpw == qrpw){
    qr=true;
    btqr=true;
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("BT Quick Release");
    lcd.setCursor(0,1);
    lcd.print("Enabled");
    delay(1000);
    }
  else if (currentqrpw != qrpw){
    lcd.clear();
    lcd.setCursor(0,0);
    pwtry = pwtry ++;
    if (pwtry == 4){
      lcd.print("Too Many Attempts");
      pwtry = 0;
      delay(2000);
      MainMenuDisplay();
      }
    lcd.print("Incorrect PW");
    lcd.setCursor(0,1);
    lcd.print("Try Again");
    delay(2000);
    enableBTQR();
    }
  
menu2 = true;
}

void AddBTDevice()
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Add BT Device");
  delay(2000);
  menu2 = true;
}
void RmvBTDevice()
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Remove BT Device");
  delay(2000);
  menu2 = true;
}
void FactoryReset()
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Enter Open PW:");
  lcd.setCursor(0,1);
  while (Serial.available() == 0){}
  openpw = Serial.readString();
  lcd.print(openpw);
  delay(500);
    if (currentopenpw == openpw){
      lcd.clear();
      lcd.setCursor(0,0);
      openpw = 1234;
      qrpw = 1234;
      //------------------remove all bt devices------------
      lcd.print("Factory Reset Done");
      lcd.setCursor(0,1);
      lcd.print("PWs Reset 1234");
      delay(1000);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("BT Device Rmoved");
      delay(1000);
      }
    else if (currentopenpw != openpw){
      lcd.clear();
      lcd.setCursor(0,0);
      pwtry = pwtry ++;
      if (pwtry == 4){
        lcd.print("Too Many Attempts");
        delay(1000);
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Switch to Reset");
        lcd.setCursor(0,1);
        lcd.print("Using QR Passwrd");
        pwtry = 0;
        delay(2000);
        menu2 = false;
        qrFactReset();
        }
      lcd.print("Incorrect PW");
      lcd.setCursor(0,1);
      lcd.print("Try Again");
      delay(2000);
      FactoryReset();
      }
  LevelMenuDisplay();
  menu2 = true;


}

void qrFactReset()
{
  {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Enter QR PW:");
  lcd.setCursor(0,1);
  while (Serial.available() == 0){}
  openpw = Serial.readString();
  lcd.print(qrpw);
  delay(500);
    if (currentqrpw == qrpw){
      lcd.clear();
      lcd.setCursor(0,0);
      openpw = 1234;
      qrpw = 1234;
      //------------------remove all bt devices------------
      lcd.print("Factory Reset Done");
      lcd.setCursor(0,1);
      lcd.print("PWs Reset 1234");
      delay(1000);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("BT Device Rmoved");
      delay(1000);
      }
    else if (currentqrpw != qrpw){
      lcd.clear();
      lcd.setCursor(0,0);
      pwtry = pwtry ++;
      if (pwtry == 4){
        lcd.print("Too Many Attempts");
        lcd.setCursor(0,1);
        pwtry = 0;
        delay(2000);
        menu2 = false;
        MainMenuDisplay();
        }
      lcd.print("Incorrect PW");
      lcd.setCursor(0,1);
      lcd.print("Try Again");
      delay(2000);
      FactoryReset();
      }
  LevelMenuDisplay();
  menu2 = true;


}
}

char ReadKeypad()
{
/* Keypad button analog Value
no button pressed 1023
nul     <450
select  <400
left    <350
down    <290
up      <190
right   <50
*/
keypad_value = analogRead(keypad_pin);

if(keypad_value < 50){
Serial.println(keypad_value);
return 'R';}
else if(keypad_value < 250){
Serial.println(keypad_value);
return 'D';}
else if(keypad_value < 450){
Serial.println(keypad_value);
return 'U';}
else if(keypad_value < 600){
Serial.println(keypad_value);
return 'L';}
else if(keypad_value < 920){
Serial.println(keypad_value);
return 'S';}
else if(keypad_value < 1000){
Serial.println(keypad_value);
return 'N';}

}

void WaitBtnRelease()
{
  Serial.println("hitbuttonrelease");
  while( analogRead(keypad_pin) < 1000){}
}

 

Gavin Shuffield's picture

Offline

Joined: Apr 22, 2021

Replies: 4

Needed code is in the top half and the very bottom. Bottom half is all processes that relate to the menu that I am trying to get functional. I didn't want to butcher it down and get someone to help with code that will not work. I know the issue lies in the loop to call upon the second menu, I just can't figure out where.

I am a begginer in C but not in programming in general. 

Sourav Gupta's picture

Offline

Joined: Feb 12, 2018

Replies: 627

This requires testing. What are you pressing on the keypad two times? Is there any chances that the Case1, 2 , 3 , 4 making the menu2 = true?

case 1:
          QuickReleaseMenu();
          break;
        case 2:
          OpenMenu();
          break;
        case 3:
          DisableQR();
          break;
Gavin Shuffield's picture

Offline

Joined: Apr 22, 2021

Replies: 4

Case 4 of the main menu sets Menu2 to true. I then jump into menu2, the program jumps to the very bottom where it should loop over and over again until a button is pushed, however the program loops twice then jumps directly into case 1.  I can't fingure out why it is not looping over and over again until I push a button to scroll through the menu. I turned on serial monitor and that is how that this was happening. And the serial is showing that no button was pushed. 

Gavin Shuffield's picture

Offline

Joined: Apr 22, 2021

Replies: 4

a little more specific. the program loops twice then jumps directly into case 1 of menu2.

Gavin Shuffield's picture

Offline

Joined: Apr 22, 2021

Replies: 4

I fixed it!!!!

 

In the main loop it was calling upon the MainmenuBtn() wether menu2 was true or not. I changed it tothe below and it worked. I had to check if menu2 == true; at the very beginning of the loop!!!

void loop()
{
  if(menu2 == false){MainmenuBtn();}
  else if(menu2 == true){LevelmenuBtn();}

if((btn_push == 'S')&&(menu2 == false))//enter selected menu

//rest of code doesn't matter for answer

Sourav Gupta's picture

Offline

Joined: Feb 12, 2018

Replies: 627

Great. I am also suspecting that. Thanks for sharing.