#include <EnableInterrupt.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#define ENCODER_PIN_A 5
#define ENCODER_PIN_B 6
#define SWITCH_PIN 7
#define ENCODER_DEBOUNCE_DELAY 1
#define SWITCH_DEBOUNCE_DELAY 50
#define LCD_ADDRESS 0x27
#define LCD_COLUMNS 16
#define LCD_ROWS 2
volatile int encoderValue = 0;
volatile bool switchPressed = false;
LiquidCrystal_I2C lcd(LCD_ADDRESS, LCD_COLUMNS, LCD_ROWS);
int mainMenuSelection = 0;
int submenuSelection = 0;
int submenuValue = 0;
unsigned long lastEncoderChangeTime = 0;
unsigned long lastSwitchChangeTime = 0;
void setup() {
pinMode(SWITCH_PIN, INPUT_PULLUP);
enableInterrupt(ENCODER_PIN_A, readEncoder, CHANGE);
enableInterrupt(ENCODER_PIN_B, readEncoder, CHANGE);
enableInterrupt(SWITCH_PIN, switchISR, FALLING);
lcd.begin(LCD_COLUMNS, LCD_ROWS);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Main Menu");
lcd.setCursor(0, 1);
lcd.print("> Menu 1");
}
void loop() {
if (encoderValue != 0 && (millis() - lastEncoderChangeTime) > ENCODER_DEBOUNCE_DELAY) {
submenuSelection = (submenuSelection + encoderValue) % 3;
displayMainMenu();
encoderValue = 0;
lastEncoderChangeTime = millis();
}
if (switchPressed && (millis() - lastSwitchChangeTime) > SWITCH_DEBOUNCE_DELAY) {
switchPressed = false;
enterSubMenu();
}
}
void displayMainMenu() {
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("> Menu ");
lcd.print(submenuSelection + 1);
}
void enterSubMenu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Submenu ");
lcd.print(submenuSelection + 1);
lcd.setCursor(0, 1);
lcd.print("Value: ");
int oldValue = submenuValue;
bool valueConfirmed = false;
while (!valueConfirmed) {
if (encoderValue != 0 && (millis() - lastEncoderChangeTime) > ENCODER_DEBOUNCE_DELAY) {
submenuValue += encoderValue;
displaySubMenuValue();
encoderValue = 0;
lastEncoderChangeTime = millis();
}
if (switchPressed && (millis() - lastSwitchChangeTime) > SWITCH_DEBOUNCE_DELAY) {
switchPressed = false;
valueConfirmed = true;
}
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Confirm:");
lcd.setCursor(0, 1);
lcd.print("Value: ");
lcd.print(submenuValue);
// Use this section to perform any actions with the confirmed value
delay(2000); // Display the confirmation for 2 seconds
submenuValue = oldValue;
displayMainMenu();
}
void displaySubMenuValue() {
lcd.setCursor(7, 1);
lcd.print(" ");
lcd.setCursor(7, 1);
lcd.print(submenuValue);
}
void readEncoder() {
unsigned long currentTime = millis();
if (currentTime - lastEncoderChangeTime > ENCODER_DEBOUNCE_DELAY) {
static unsigned int previousState = 0;
unsigned int currentState = (digitalRead(ENCODER_PIN_A) << 1) | digitalRead(ENCODER_PIN_B);
if ((previousState == 0b00 && currentState == 0b01) || (previousState == 0b01 && currentState == 0b11) ||
(previousState == 0b11 && currentState == 0b10) || (previousState == 0b10 && currentState == 0b00)) {
encoderValue++;
} else if ((previousState == 0b00 && currentState == 0b10) || (previousState == 0b10 && currentState == 0b11) ||
(previousState == 0b11 && currentState == 0b01) || (previousState == 0b01 && currentState == 0b00)) {
encoderValue--;
}
previousState = currentState;
lastEncoderChangeTime = currentTime;
}
}
void switchISR() {
unsigned long currentTime = millis();
if (currentTime - lastSwitchChangeTime > SWITCH_DEBOUNCE_DELAY) {
if (!switchPressed) {
switchPressed = true;
lastSwitchChangeTime = currentTime;
}
}
}