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.
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
Gavin Shuffield
PermalinkNeeded 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.
- Log in or register to post comments
Joined April 22, 2021 4Thursday at 01:29 AM