#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define UP_BUTTON 2
#define DOWN_BUTTON 3
#define ENTER_BUTTON 4
#define BACK_BUTTON 5
#define LED1 6
#define LED2 7
#define LED3 8
LiquidCrystal_I2C lcd(0x27, 16, 2);
int selectedLED = 0;
int timerValues[3] = {1, 1, 1}; // Timer values in minutes
bool ledOn[3] = {false, false, false};
unsigned long ledStartTime[3] = {0, 0, 0};
unsigned long lastUpdateTime = 0;
enum State { INIT_SCREEN, MAIN_MENU, SET_TIMER, CONFIRM, RUNNING };
State currentState = INIT_SCREEN;
void setup() {
pinMode(UP_BUTTON, INPUT_PULLUP);
pinMode(DOWN_BUTTON, INPUT_PULLUP);
pinMode(ENTER_BUTTON, INPUT_PULLUP);
pinMode(BACK_BUTTON, INPUT_PULLUP);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
lcd.init();
lcd.backlight();
showInitScreen();
}
void loop() {
checkLEDTurnOff();
if (currentState == INIT_SCREEN && buttonPressed(ENTER_BUTTON)) {
currentState = MAIN_MENU;
showLEDMenu();
}
switch (currentState) {
case MAIN_MENU:
if (millis() - lastUpdateTime > 1000) { // Update every second
lastUpdateTime = millis();
showLEDMenu();
}
navigateLEDMenu();
break;
case SET_TIMER:
adjustTimer();
break;
case CONFIRM:
startLEDTimer();
break;
case RUNNING:
showLEDRunningScreen();
break;
}
}
void showInitScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("LED Timer Sw V1");
lcd.setCursor(2, 1);
lcd.print("Press ENTER");
}
void navigateLEDMenu() {
if (buttonPressed(UP_BUTTON)) {
selectedLED = (selectedLED == 0) ? 2 : selectedLED - 1; // Cyclic up
showLEDMenu();
}
if (buttonPressed(DOWN_BUTTON)) {
selectedLED = (selectedLED + 1) % 3; // Cyclic down
showLEDMenu();
}
if (buttonPressed(ENTER_BUTTON)) {
currentState = SET_TIMER;
showTimerScreen();
}
}
void showLEDMenu() {
lcd.clear();
for (int i = 0; i < 2; i++) {
int displayIndex = (selectedLED + i) % 3;
lcd.setCursor(0, i);
lcd.print((i == 0) ? "> " : " ");
lcd.print("LED");
lcd.print(displayIndex + 1);
lcd.print(": ");
if (ledOn[displayIndex]) {
unsigned long elapsedSeconds = (millis() - ledStartTime[displayIndex]) / 1000;
int remainingTime = (timerValues[displayIndex] * 60) - elapsedSeconds;
if (remainingTime > 0) {
int minutes = remainingTime / 60;
int seconds = remainingTime % 60;
lcd.print(minutes);
lcd.print("m ");
if (seconds < 10) lcd.print("0");
lcd.print(seconds);
lcd.print("s");
} else {
lcd.print("OFF");
ledOn[displayIndex] = false;
}
} else {
lcd.print("OFF");
}
}
}
void showTimerScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("LED ");
lcd.print(selectedLED + 1);
lcd.print(" Timer");
lcd.setCursor(0, 1);
lcd.print("Time: ");
lcd.print(timerValues[selectedLED]);
lcd.print(" min");
}
void adjustTimer() {
if (buttonPressed(UP_BUTTON) && timerValues[selectedLED] < 60) {
timerValues[selectedLED]++;
showTimerScreen();
}
if (buttonPressed(DOWN_BUTTON) && timerValues[selectedLED] > 1) {
timerValues[selectedLED]--;
showTimerScreen();
}
if (buttonPressed(ENTER_BUTTON)) {
currentState = CONFIRM;
showConfirmScreen();
}
if (buttonPressed(BACK_BUTTON)) {
currentState = MAIN_MENU;
showLEDMenu();
}
}
void showConfirmScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("LED ");
lcd.print(selectedLED + 1);
lcd.print(" Selected");
lcd.setCursor(0, 1);
lcd.print("Enter to Start");
}
void startLEDTimer() {
if (!ledOn[selectedLED] && buttonPressed(ENTER_BUTTON)) {
ledOn[selectedLED] = true;
ledStartTime[selectedLED] = millis();
digitalWrite(LED1 + selectedLED, HIGH);
currentState = MAIN_MENU;
showLEDMenu();
}
if (buttonPressed(BACK_BUTTON)) {
currentState = SET_TIMER;
showTimerScreen();
}
}
void showLEDRunningScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("LED ");
lcd.print(selectedLED + 1);
lcd.print(" ON");
lcd.setCursor(0, 1);
lcd.print("Time Left: ");
unsigned long elapsedSeconds = (millis() - ledStartTime[selectedLED]) / 1000;
int remainingTime = (timerValues[selectedLED] * 60) - elapsedSeconds;
lcd.print(remainingTime / 60);
lcd.print("m ");
if (remainingTime % 60 < 10) lcd.print("0");
lcd.print(remainingTime % 60);
lcd.print("s");
if (buttonPressed(BACK_BUTTON)) {
currentState = MAIN_MENU;
showLEDMenu();
}
}
void checkLEDTurnOff() {
for (int i = 0; i < 3; i++) {
if (ledOn[i]) {
unsigned long elapsedSeconds = (millis() - ledStartTime[i]) / 1000;
if (elapsedSeconds >= (timerValues[i] * 60)) {
ledOn[i] = false;
digitalWrite(LED1 + i, LOW);
}
}
}
}
bool buttonPressed(int buttonPin) {
if (digitalRead(buttonPin) == LOW) {
delay(200);
while (digitalRead(buttonPin) == LOW);
return true;
}
return false;
}