Hello
I modified your sketch and I think that was what you had in mind to achieve your design goal.
Please review it and don't hesitate if you have more questions.
A microLogic analyzer to see what happens inside I have not deleted.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
enum {Up, Down, Select};
const int UpButton {A0};
const int DownButton = {A1};
const int SelectButton = {A2};
int menu = 1;
struct BUTTON {
byte pin;
bool state;
int click;
unsigned long timeStamp;
unsigned long duration;
} button[] {
{UpButton, 1, 1, 0, 20},
{DownButton, 1, 1, 0, 20},
{SelectButton, 1, 1, 0, 20},
};
void debounce() {
for (auto &make : button) {
if (millis() - make.timeStamp >= make.duration) {
make.timeStamp = millis();
make.state = digitalRead(make.pin);
}
}
}
enum {Pressed, Released, Nothing};
int click (BUTTON &button) {
if (button.click == button.state) return Nothing;
button.click = button.state;
return button.click;
}
void setup() {
lcd.init(); // initialize the lcd
lcd.backlight();
lcd.setContrast(255);
for (auto make : button) pinMode(make.pin, INPUT_PULLUP);
updateMenu();
Serial.begin(9600);
Serial.println("und los geht´s");
}
void loop() {
debounce();
int buttonRead = click(button[Down]);
if (buttonRead == Pressed) Serial.println("DownButton pressed");
if (buttonRead == Pressed) {
menu++;
updateMenu();
}
buttonRead = click(button[Up]);
if (buttonRead == Pressed) Serial.println("UpButton pressed");
if (buttonRead == Pressed) {
menu--;
updateMenu();
}
buttonRead = click(button[Select]);
if (buttonRead == Pressed) Serial.println("SelectButton pressed");
if (buttonRead == Pressed) {
static bool selectAction;
if (!selectAction) executeAction();
if (selectAction) updateMenu();
selectAction = !selectAction;
}
}
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");
}
void action2() {
lcd.clear();
lcd.print(">Executing #2");
}
void action3() {
lcd.clear();
lcd.print(">Executing #3");
}
void action4() {
lcd.clear();
lcd.print(">Executing #4");
}