LCD with buttons, increment selection

I am using an adafruit 16x2 LCD with buttons. I am using the buttons to select a certain number to perform some operations. My code works, but its kind of sloppy and i was hoping someone could help me out.

decrementing from zero goes back to 255 rather than negative. also when incrementing forward from 255 it only adjusts the most significant bit. Also I’ve tried to implement a timer that resets the LCD back to a welcome message if no buttons are pressed for X amount of time.

#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

byte drinkSelection = 0;

void setup() {
  Serial.begin(9600);                       //Open Serial with baud rate 9600
  lcd.begin(0x27,16, 2);                    //Start lcd (address, rows, columns)         
      
  lcd.clear();
  lcd.setCursor(1,0);
  lcd.print("Select a drink"); 

}
void loop() {


  uint8_t buttons = lcd.readButtons();                              //Initiate buttons
  if (buttons) {
    lcd.setCursor(0,1);
    if (buttons & BUTTON_UP) {                                      //If push up, incriment drink selection
      delay(100);
      drinkSelection++;
      Serial.print(drinkSelection);
      lcd.setCursor(1,0);
      lcd.print("Please Confirm");
      lcd.setCursor(7,1);
      lcd.print(drinkSelection);
     }
    
    if (buttons & BUTTON_DOWN) {                                  //if push down, decriment drink selection
      delay(100);
      drinkSelection--;
      Serial.print(drinkSelection);
      lcd.setCursor(1,0);
      lcd.print("Please Confirm");
      lcd.setCursor(7,1);
      lcd.print(drinkSelection);    
     }
    
    if (buttons & BUTTON_LEFT) {                                  //if push left, decriment drink selection
      delay(100);
      drinkSelection--;
      Serial.print(drinkSelection);
      lcd.setCursor(1,0);
      lcd.print("Please Confirm");
      lcd.setCursor(7,1);
      lcd.print(drinkSelection);      
     }
    if (buttons & BUTTON_RIGHT) {                                   //if push right, incriment drink selection
      delay(100);
      drinkSelection++;
      Serial.print(drinkSelection);
      lcd.setCursor(1,0);
      lcd.print("Please Confirm");
      lcd.setCursor(7,1);
      lcd.print(drinkSelection);     
     }
    if (buttons & BUTTON_SELECT) {
      delay(250);
      recipes[drinkSelection - 1]();                                  //run drink function of number selected     
      Serial.print(drinkSelection);
      delay(1000);
      
    }
  }
} // End of loop

decrementing from zero goes back to 255 rather than negative

No surprise there as drinkSelection is declared as a byte. Do you really want/need negative values anyway ?

when incrementing forward from 255 it only adjusts the most significant bit.Do you mean that it goes from 255 to 0 ? If so, then see the answer above.

Also I've tried to implement a timer that resets the LCD back to a welcome message if no buttons are pressed for X amount of time.

Is that in this code ?

UKHeliBob: No surprise there as drinkSelection is declared as a byte. Do you really want/need negative values anyway ?

You are right i do not need negative values. if i change drinkSelection to int, it goes negative. I guess i would rather is stop at zero if there is a way to do that?

what i mean by incrementing the MSB, lets say I'm on -2, then -1, then it goes 01, 11, 21, 31 etc..

it only does that if i decriment first. otherwise it increments from 0++ as it should.

I did try some timeout features but none worked so i only included my working code. this is what i tried...

if(buttons=0){
delay(5000);
  lcd.clear();
  lcd.setCursor(1,0);
  lcd.print("Select a drink");
}

but that obviously wont work because as soon as a button isn't pressed, it immediately goes into 5 second delay and then resets screen. i want it to countdown 5 seconds, then wipe screen.

thank you for your help

I guess i would rather is stop at zero if there is a way to do that?

Test the value after the increment or decrement and it is out of you required range then set its value back into your range.

what i mean by incrementing the MSB, lets say I'm on -2, then -1, then it goes 01, 11, 21, 31 etc..

That's because the 1 from -1 is still on the screen, so when you print a 0 you see 01, then 11 etc. Print a space after your number to write over any left over characters. The same thing would happen if you decrement from 10 to 9. You would see 10 then 90 etc.

UKHeliBob: Test the value after the increment or decrement and it is out of you required range then set its value back into your range. That's because the 1 from -1 is still on the screen, so when you print a 0 you see 01, then 11 etc. Print a space after your number to write over any left over characters. The same thing would happen if you decrement from 10 to 9. You would see 10 then 90 etc.

You nailed it! so simple....

i just set the screen to clear after each button press to fix that issue. i also set an if statement to prohibit the selection to go below zero, and i figured out the screen timeout. Here is what i did.

void loop() {

  unsigned long currentTime = millis(); 

  if (currentTime - previousTime > timeout) {
    
    lcd.clear();                                                       //Reset Screen from inactivity
    lcd.setCursor(4,0);
    lcd.print("Welcome!");
    lcd.setCursor(1,1);
    lcd.print("Select a drink");  
    drinkSelection = 0;
    previousTime = currentTime;
  }
  uint8_t buttons = lcd.readButtons();                              //Initiate buttons
  
  if (buttons) {
    int startTimeoutTimer = millis();
    
    lcd.setCursor(0,1);
    if (buttons & BUTTON_UP) {                                      //If push up, incriment drink selection
      delay(150);
      drinkSelection++;
      Serial.print(drinkSelection);
      lcd.clear();
      lcd.setCursor(1,0);
      lcd.print("Please Confirm");
      lcd.setCursor(7,1);
      lcd.print(drinkSelection);
      previousTime = millis();
     }
    
    if (buttons & BUTTON_DOWN) {                              //if push down, decriment drink selection
      if(drinkSelection >= 1) {
      delay(150);
      drinkSelection--;
      Serial.print(drinkSelection);
      lcd.clear();
      lcd.setCursor(1,0);
      lcd.print("Please Confirm");
      lcd.setCursor(7,1);
      lcd.print(drinkSelection); 
      previousTime = millis();   
     }
    }
    
    if (buttons & BUTTON_LEFT) {                                  //if push left, decriment drink selection
      if(drinkSelection >= 1) {
      delay(150);
      drinkSelection--;
      Serial.print(drinkSelection);
      lcd.clear();
      lcd.setCursor(1,0);
      lcd.print("Please Confirm");
      lcd.setCursor(7,1);
      lcd.print(drinkSelection);  
      previousTime = millis();    
     }
    }
    if (buttons & BUTTON_RIGHT) {                                   //if push right, incriment drink selection
      delay(150);
      drinkSelection++;
      Serial.print(drinkSelection);
      lcd.clear();
      lcd.setCursor(1,0);
      lcd.print("Please Confirm");
      lcd.setCursor(7,1);
      lcd.print(drinkSelection); 
      previousTime = millis();    
     }
    if (buttons & BUTTON_SELECT) {
      delay(250);
      recipes[drinkSelection - 1]();                                  //run drink function of number selected     
      Serial.print(drinkSelection);
      delay(1000);     
     }   
  } //end if loop  
} // End void loop

I assume that recipes[] is an array of functions. What will happen when the program tries to run a recipe function that does not exist ?

UKHeliBob: I assume that recipes[] is an array of functions. What will happen when the program tries to run a recipe function that does not exist ?

yea, i only copied the relevant code. its about 1500 lines now.

recipes is an array of 42 functions that are selected by the number pad on the LCD selecting the number associated to the position in the array.

if i select a number outside of the sizeof recipes array, then the lcd returns to welcome screen. well about 90% of the time. sometimes it freezes up. probably should figure out a failsafe.

probably should figure out a failsafe.

Must stop the recipe number going out of range.