0

I have made a very short version of my code. It has the basic problem I am facing. I explain my code and problem below.

#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

void setup() {
  lcd.begin(16, 2); //format of display
}

int menu = 0;
int subMenu = 99;
void loop() {

  uint8_t buttons = lcd.readButtons();

  lcd.setCursor(0,0);

  if (menu == 0) {
  lcd.print("Select menu option");
    if (buttons & BUTTON_SELECT) {
      lcd.clear();
      menu = 99;
      subMenu = 1;
    }
  }

  if (subMenu == 1) {
    lcd.print("in sub menu 1");
    if (buttons & BUTTON_SELECT) {
       lcd.clear();
       lcd.setCursor(0,1);
       lcd.print("shouldnt happen");
    }
  }
}

I am setting a variable menu, which will keep track of what main menu I am on, and a subMenu, which keeps track of what sub-menu I am on.

The default value of menu (0) prints on the LCD "Select Menu Option".

When pressing SELECT, the LCD is cleared. The menu is being set to an unknown number, so that it doesn't print anything, and subMenu is set to 1.

If subMenu is equal to 1 (which it will be if the user chooses presses SELECT), the LCD prints "in sub menu 1".

Inside this, if the button SELECT is clicked, it should print "shouldnt happen".

The issue I am facing is that when clicking SELECT for entering the menu 1, the SELECT is also carried out to the sub-menu, so instead of waiting for a second key press to confirm going into the sub menu, it goes straight into it.

This makes sense because it is check that SELECT has been pressed, prints a new page, with the button SELECT still having been pressed, so it validated the condition for key press in the sub menu as well.

The user input to LCD display response should be the following:

Select menu option -> presses SELECT -> in sub menu 1 -> presses SELECT -> shouldnt happen

Currently however, it is like this:

Select menu option -> presses SELECT -> in sub menu 1 shouldnt happen

How can I make it so that these key presses only act on the menu on which they are?

Thanks, let me know if something confuses you, I can explain in more details

  • Would still love to read any tips or help regarding these multi-level buttons. Thanks! – Jon Goe Apr 13 '17 at 17:01
  • In your posted code I don't see you changing menu anywhere, except for setting it to 99 if it is zero. – Nick Gammon Apr 14 '17 at 8:25
1

I'm not sure about built-in buttons, however on my projects I always add a debounce feature to any buttons. Adjust this to your uses. If there's any issues let me know and I'll test it properly as I'm not at my programming workstation to fully test at the moment.

For example:

// Updated to include if statements and copy/pasted version of successfully
// compiled version.

// Had to use LiquidCrystal library as I don't have the AdaFruit Display libraries.
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
//

int menu = 0, subMenu = 99, debounce = 200;
unsigned long pMillis = 0, cMillis;

void setup(){
  lcd.begin(16,2);
};

void loop(){
  cMillis = millis(); // sets cMillis to current millis()
  //uint8_t buttons = lcd.readButtons();
  lcd.setCursor(0,0);
  if(cMillis >= (pMillis + debounce)){
    if (menu == 0) {
      lcd.print("Select menu option");
      /*if (buttons & BUTTON_SELECT) {
       *  lcd.clear();
       *  menu = 99;
       *  subMenu = 1;
       *  };
       */
    };
    if (subMenu == 1) {
      lcd.print("in sub menu 1");
      /*if (buttons & BUTTON_SELECT) {
       *  lcd.clear();
       *  lcd.setCursor(0,1);
       *  lcd.print("shouldnt happen");
       *  };
       */
    };
  pMillis = cMillis; // sets pMillis to cMillis for the next iteration of the loop()
  };
  // I always put something similar to this at the end 
  // to make sure that when millis() cycles back to 0 
  // pMillis is reset to less than cMillis.
  if(cMillis < pMillis){
    pMillis = cMillis; // sets pMillis to cMillis for the next iteration of the loop()
  };
};

Edit/Update: This compiles fine using the standard LiquidCrystal library, I am unable to test the AdaFruit display as I don't have one. If this still doesn't work, I'll upload it to the Arduino when I get back and see what's up.

New test:

// Your libraries here

int menu = 0,
    subMenu = 99,
    debounce = 200;

unsigned long pMillis = 0,
          cMillis;

void setup(){
  lcd.begin(16,2);
}

void loop(){
  cMillis = millis(); // sets cMillis to current millis()
  //uint8_t buttons = lcd.readButtons();

  if(buttons & BUTTON_SELECT){ // I used "if(digitalRead(buttonPin) == HIGH){ ... }"
    if(cMillis >= (pMillis + debounce)){
      //I'd normally put counter/menu logic in here for the different buttons, for example:
      //"subMenu += 1;
      // if(subMenu >= totalSubMenus) { subMenu = 0; };"
      subMenu = 1;
      pMillis = cMillis;
    }
  }

  if(menu == 0){
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Select Menu Option");
    menu = 99;
  }
  if(subMenu == 1){
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print("In Sub Menu 1");
  }

  if(cMillis < pMillis){
    pMillis = cMillis; // sets pMillis to cMillis for the next iteration of the loop()
  }
}
  • That doesn't seem to work. Here is my code implemented with your solution if you'd like to test it out. pastebin.com/0Uy3mspN – Jon Goe Apr 13 '17 at 10:56
  • @JonGoe I've updated the original and added the setup() function in there too... I can test this properly later. One thing, is "(buttons & BUTTON_SELECT)" correct? should it be an "&&" in there instead? if there's still no joy, try a search of adding a debounce function. I'll be about later if no one else has answered – Timeless Apr 13 '17 at 11:10
  • No, the single & is correct. Ill be looking online for a debounce function. Looking foward to hear from you! Thanks – Jon Goe Apr 13 '17 at 11:29
  • @JonGoe - Updated with successfully compiled version. Unable to upload it to an Arduino at this moment, but I have the LCD and buttons already in the breadboard at home, and wired, as I was doing this a couple of days ago. – Timeless Apr 13 '17 at 12:57
  • @JonGoe - one last thing. you have subMenu = 1 in the first "if" statement, which then means the next "if(subMenu == 1)" statement will be true. To test that, put "delay(1000);) after "submenu = 1" in the first if statement and see if the first text displays correctly. – Timeless Apr 13 '17 at 13:08

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.