Menu help and guidance

Hi Everyone,

With the help and guidance from LightuC I am attempting to work on a very simple menu for myself since the others that I have seen were overkill for me to really understand and work with. So far the test menu seems to be working as I go from screen to screen, I am having a few difficulties however.

This setup is just an lCD screen with 3 push buttons. The LCD only has 4 pins to connect to the arduino.

I took out some of the comments to keep the code a bit more compact. I do have two requests if I can get some help with them i will have made my menu system.

  1. My function below I am not getting my value to flip back and forth from auto to manual.
void updateBoolValue()
  1. While looking at the code how do I get everything a bit more compact without having code duplicated? Can someone offer some guidance? I was just trying to get what I was working on to work and I am sure there are areas that can be coded better.
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);


#define btnSelect 2   // select push button to scroll menu pages
#define btnUp     3   // up pushbutton to increment values
#define btnDown   4   // down pushbutton to decrement values

bool btn_Select_Pressed = false;    // keep track if the button has been pressed
int btnSelectCurState;              // the current reading from the input pin
int btnSelectLastState = HIGH;      // the previous reading from the select button
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 50;

bool btn_Up_Pressed = false;    // keep track if the button has been pressed
int btnUpCurState;              // the current reading from the input pin
int btnUpLastState = HIGH;      // the previous reading from the select button

int menuScreen = 0;
int value = 0;
bool disp;

#define DEBUG


bool isSelectButtonPressed()
{
  int btnSelectState = digitalRead(btnSelect);
  if(btnSelectState != btnSelectLastState) 
  {
    lastDebounceTime = millis();
  }

  if((millis() - lastDebounceTime) > debounceDelay) 
  {
    if(btnSelectState != btnSelectCurState) 
    {
      btnSelectCurState = btnSelectState;
      if(btnSelectCurState == LOW) 
      {
        btn_Select_Pressed = true;
        menuScreen++;
        if((menuScreen < 0) || (menuScreen > 2))
        {
          menuScreen = 0;  
        }
      }
    }
  }
  btnSelectLastState = btnSelectState;

  if(btn_Select_Pressed == true)
  {
    #ifdef DEBUG
        Serial.print("btn_Select_Pressed = ");
        Serial.println(btn_Select_Pressed);
    #endif

    btn_Select_Pressed = false;  // reset the variable back to false  
    return true;
  }
  else
  {
    return false;
  }
}

bool isButtonUpPressed()
{
  int btnUpState = digitalRead(btnUp);
  if(btnUpState != btnUpLastState) 
  {
    lastDebounceTime = millis();
  }

  if((millis() - lastDebounceTime) > debounceDelay) 
  {
    if(btnUpState != btnUpCurState) 
    {
      btnUpCurState = btnUpState;
      if(btnUpCurState == LOW) 
      {
        btn_Up_Pressed = true;
      }
    }
  }
  btnUpLastState = btnUpState;

  if(btn_Up_Pressed == true)
  {
    #ifdef DEBUG
        Serial.print("btn_Up_Pressed = ");
        Serial.println(btn_Up_Pressed);
    #endif

    btn_Up_Pressed = false;  // reset the variable back to false  
    return true;
  }
  else
  {
    return false;
  }
}

void getNextMenuPage()
{
  switch(menuScreen)
  {
    case 0:
      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print(" *Main Screen *"); 
      lcd.setCursor(4, 2);
      lcd.print("Testing the");
      lcd.setCursor(4, 3);
      lcd.print("Main Screen"); 
    break;
    case 1:
      lcd.clear();
      lcd.setCursor(2, 2);
      lcd.print("              "); 
      lcd.setCursor(2, 2);
      lcd.print("Config Screen"); 
      lcd.setCursor(0, 3);
      lcd.print(value);
    break;
    case 2:
      lcd.setCursor(2, 2);
      lcd.print("Runtime Screen"); 
      lcd.setCursor(0, 3);
      lcd.print(disp);
    break;
  }
  
}

void updatePageValue()
{
  if(menuScreen == 1)
  {
    value++;
    lcd.setCursor(0, 3);
    lcd.print(value);
  }
} 

void updateBoolValue()
{
  #ifdef DEBUG
      Serial.print("disp value = ");
      Serial.println(disp);
  #endif

  lcd.setCursor(0, 3);
  lcd.print((disp == false) ? "MANUAL" : "AUTO" );
  
}

void setup() 
{
  #ifdef DEBUG
      Serial.begin(9600);
  #endif
  
  pinMode(btnSelect, INPUT_PULLUP); 
  pinMode(btnUp, INPUT_PULLUP); 
  pinMode(btnDown, INPUT_PULLUP); 

  
  lcd.init(); // initialize the lcd
  lcd.backlight(); // open the backlight 

  lcd.setCursor(2, 0);
  lcd.print("**Main Screen**");

  #ifdef DEBUG
      Serial.println("Ready.");
  #endif
}

void loop() 
{
  if(isSelectButtonPressed())
  {
    getNextMenuPage();
  }

  if(isButtonUpPressed())
  {
    if(menuScreen == 1)
    {
      updatePageValue();
    }
    else if(menuScreen == 2)
    {
      updateBoolValue();
    }
  } 
}

Thanks

John

Thats correct. I actually dont really know how to get the values to flip back and forth.

Delta_G:
You mean this function:

void updateBoolValue()

{
  #ifdef DEBUG
      Serial.print("disp value = ");
      Serial.println(disp);
  #endif

lcd.setCursor(0, 3);
  lcd.print((disp == false) ? "MANUAL" : "AUTO" );
 
}




It doesn't change any value. disp never changes in here. It just displays it. Is that what you mean? It's supposed to change here?

Delta_G:
How can you have all that code written and you don't know how to assign a value to a variable? I'm not trying to be mean here, I just honestly don't understand how you get something that complicated and then you can't assign a simple value to a simple variable.

Good question. It actually made me laugh as I read your comment because thats what I was asking myself too.

Ever since I have been coding I have never used logic like that. I always used if statements. Thats hows little I do any coding, thats why I like to keep it very simple so I can understand and not get confused when I look at the code years later. There are code examples I have looked at and its so complex that I dont even waste my time trying to go nuts.

Appreicate the help on that variable.

I was hoping for an example like this one that you gave.

disp = !disp;

I didnt want to use my usual if statements as I am trying to make the code short without a lot of if statements. Its actually not a lot of code, very short and easy to understand.

Didn’t someone write a library for menus ?

Many people wrote libraries for menus, but I hadn't found any that i could work with. If I did find a good one I couldn't get any of the examples to compile so I never bothered. I searched for weeks and weeks every day looking for examples, or, even a simple library but had no luck. I even asked in the forum about libraries, still I couldn't find what I needed.

Or the examples were so complex that i didn't understand most of it. By me writing what i needed will work, as I fix the code up and add a few more things to it to make it an entire program it should be cool.

I will not be surprised at all that after I wrote my own that i will stumble into something out there on the web and then wonder why I hadn't found that in the first place.