0

So hello everyone. I'm creating simple menu with few sub menus,on my lcd screen. But i have run into small problem, i can't stay in my sub menu. When i press select button, it goes into submenu section and after maybe 1-2 sec it goes back to main menu.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

int upButton = 10;
int downButton = 11;
int selectButton = 12;
int menu = 1;

void setup() {
  lcd.begin();
  lcd.backlight();
  pinMode(upButton, INPUT_PULLUP);
  pinMode(downButton, INPUT_PULLUP);
  pinMode(selectButton, INPUT_PULLUP);
  updateMenu();
}

void loop() {
  if (!digitalRead(downButton)){
    menu++;
    updateMenu();
    delay(100);
    while (!digitalRead(downButton));
  }
  if (!digitalRead(upButton)){
    menu--;
    updateMenu();
    delay(100);
    while(!digitalRead(upButton));
  }
  if (!digitalRead(selectButton)){
    executeAction();
    updateMenu();
    delay(100);
    while (!digitalRead(selectButton));
  }
}

void updateMenu() {
  switch (menu) {
    case 0:
      menu = 1;
      break;
    case 1:
      lcd.clear();
      lcd.print(">MenuItem1");
      lcd.setCursor(0, 1);
      lcd.print(" MenuItem2");
      break;
    case 2:
      lcd.clear();
      lcd.print(" MenuItem1");
      lcd.setCursor(0, 1);
      lcd.print(">MenuItem2");
      break;
    case 3:
      lcd.clear();
      lcd.print(">MenuItem3");
      lcd.setCursor(0, 1);
      lcd.print(" MenuItem4");
      break;
    case 4:
      lcd.clear();
      lcd.print(" MenuItem3");
      lcd.setCursor(0, 1);
      lcd.print(">MenuItem4");
      break;
    case 5:
      menu = 4;
      break;
  }
}

void executeAction() {
  switch (menu) {
    case 1:
      action1();
      break;
    case 2:
      action2();
      break;
    case 3:
      action3();
      break;
    case 4:
      action4();
      break;
  }
}

void action1() {
  lcd.clear();
  lcd.print(">Executing #1");
  delay(1500);
}
void action2() {
  lcd.clear();
  lcd.print(">Executing #2");
  delay(1500);
}
void action3() {
  lcd.clear();
  lcd.print(">Executing #3");
  delay(1500);
}
void action4() {
  lcd.clear();
  lcd.print(">Executing #4");
  delay(1500);
}

Thanks in advanced

7
  • 2
    Do you understand the code you've included? It does exactly what you are describing. There are no submenus defined in your code, only a main menu and actions (which display something on the screen and return to the main menu after 1.5 seconds). You also forgot to ask a question. – StarCat Apr 19 at 7:50
  • Yes, i ment submenu as action. My question is what i'm missing? – Jānis Apr 19 at 7:52
  • What is it that you want your code to do? If you want to have submenus, you should add the code to display submenus and browse through them. – StarCat Apr 19 at 7:59
  • I that, when i go to action 1, i stay in action 1 (not go out from it after 1,5s). – Jānis Apr 19 at 8:15
  • 1
    That's why I asked if you if you understood the code. Every void action1() .. action4() displays something and waits for 1.5 seconds ( = delay(1500);) and then immedately returns to the main menu. If you want to change this, you should change action1() to action4() to do what you want. – StarCat Apr 19 at 8:40
1

take, for instance, one of the submenu action function

   void action1() {
      lcd.clear();
      lcd.print(">Executing #1");
      delay(1500);
    }

action1() function will be called when the value of menu is set to 1.

Let us say, you want to blink an LED 10 times, in the action1() function. In the action1() function, you have to add the required logic / code to be executed. after completing the code execution the control will exit from action1() function. then your code goes something like this:

   void action1() {
      lcd.clear();
      lcd.print(">Executing #1");
      for(int i =0; i<10; i++)
      {
         ledstate = !ledstate; //assume ledstate initial value os zero
         digitalWrite(LED_BUILTIN, !ledstate);
         delay(500);
      }

    }

If you want to stay in the function action1() permanently, you can do this:

   void action1() {
      lcd.clear();
      lcd.print(">Executing #1");
      while(1);
    }

But you see, the control will never come out of that function. It means you may be not able to read the button status again or navigate to other menus. I presume you are not using interrupts. it means, your code will be stuck here forever. To come out of this function, the only way will be a system reset. Still, if this is the one, you need to do, then you can explore sleep functions to save power instead of being in the while(1) function.

You should have a plan to get out of the function. While you are in action1() function, try to monitor the buttons, if certain buttons are pressed, you can detect it and then exit the while loop

while(digitalRead(button1)
{
 //some repeated actions to code
}

as soon as button1 goes LOW the condition in the while function will fail.

I hope my answer gave you some ways to solve your problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.