#include <arduino-timer.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "MenuItem.h"
#include "MenuList.h"
#include "MenuController.h"
/**
Timers
*/
Timer<1, millis> appTimer;
const int ENCODER_TIMER = 10;
const int MENU_TIMEOUT = 60000;
const int MENU_REFRESH_TIMEOUT = 1000;
/**
Encoder
*/
#define ENCODER_S1_PIN 32
#define ENCODER_S2_PIN 33
#define ENCODER_BTN_PIN 25
int lastEncoderValue = 0;
unsigned long lastEncoderInput = millis();
bool encoderConfirmValue = false;
/**
LCD
*/
LiquidCrystal_I2C lcd(0x27, 20, 4);
/**
Menu
*/
MenuController menu(lcd);
void setup() {
Serial.begin(115200);
while (!Serial);
initEncoder();
initLCD();
initTimers();
}
void loop() {
try {
appTimer.tick<void>();
} catch (const std::exception& e) {
Serial.println("UNEXPECTED ERROR: " + String(e.what()));
}
}
void initEncoder() {
pinMode(ENCODER_S1_PIN, INPUT);
pinMode(ENCODER_S2_PIN, INPUT);
pinMode(ENCODER_BTN_PIN, INPUT_PULLUP);
}
void initTimers() {
appTimer.every(ENCODER_TIMER, encoderActionTimer);
}
void initLCD() {
lcd.init();
lcd.backlight();
}
bool encoderActionTimer(void *) {
bool menuChanged = false;
int currentEncoderValue = digitalRead(ENCODER_S1_PIN);
if (currentEncoderValue != lastEncoderValue) {
menuChanged = true;
lastEncoderValue = currentEncoderValue;
int dtValue = digitalRead(ENCODER_S2_PIN);
if (lastEncoderValue == LOW && dtValue == HIGH) {
Serial.println("Menu next ...");
menu.next();
}
if (lastEncoderValue == LOW && dtValue == LOW) {
Serial.println("Menu prev ...");
menu.prev();
}
}
if (encoderConfirmValue == false && digitalRead(ENCODER_BTN_PIN) == LOW) {
menuChanged = true;
encoderConfirmValue = true;
Serial.println("Menu confirm ...");
menu.confirm();
} else if (encoderConfirmValue == true && digitalRead(ENCODER_BTN_PIN) == HIGH) {
menuChanged = true;
encoderConfirmValue = false;
}
if (menuChanged == true) {
lastEncoderInput = millis();
menu.render();
} else if (menu.isEnable() && (millis() - lastEncoderInput) > MENU_REFRESH_TIMEOUT) {
menu.render();
}
if ((millis() - lastEncoderInput) > MENU_TIMEOUT) {
menu.disable();
} else {
menu.enable();
}
return true;
}