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){}
}
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;
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.
In reply to Case 4 of the main menu sets by Gavin Shuffield
a little more specific. the program loops twice then jumps directly into case 1 of menu2.
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
Great. I am also suspecting that. Thanks for sharing.
Gavin Shuffield
Joined April 22, 2021 4Thursday at 01:29 AM
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.