#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
int menu = 0; // Track the current menu state
LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address and LCD size (16x2)
RTC_DS3231 rtc; // RTC object
// Button pins
int upButton = 2;
int downButton = 3;
int selectButton = 4;
int menuButton = 5; // Menu button to power on/off LCD
// States and timing variables
bool lcdOn = false; // LCD power state
unsigned long startTime = 0; // Start time for the LCD on duration
const unsigned long onDuration = 60000; // Duration to keep LCD on (1 minute)
void setup() {
// Initialize LCD and RTC
lcd.init();
lcd.noBacklight(); // Keep LCD off initially
Serial.begin(115200);
rtc.begin();
// Initialize buttons
pinMode(upButton, INPUT_PULLUP);
pinMode(downButton, INPUT_PULLUP);
pinMode(selectButton, INPUT_PULLUP);
pinMode(menuButton, INPUT_PULLUP);
// Initially, disable all buttons except the menu button
disableOtherButtons();
}
void loop() {
// Check if the menu button is pressed to toggle the LCD on
if (!digitalRead(menuButton) && !lcdOn) {
lcdOn = true;
startTime = millis(); // Record the time LCD was turned on
// Turn on the LCD
lcd.backlight();
lcd.clear();
lcd.print("Menu On");
delay(100);
while (!digitalRead(menuButton)); // Wait until button is released
Serial.println("LCD turned on");
enableOtherButtons(); // Enable other buttons since LCD is on
updateMenu(); // Display initial menu screen
}
// If the LCD is on, check if 1 minute has passed since it was turned on
if (lcdOn && (millis() - startTime >= onDuration)) {
lcdOn = false;
lcd.noBacklight();
lcd.clear();
Serial.println("LCD turned off");
disableOtherButtons(); // Disable other buttons since LCD is off
}
// When the LCD is on, allow menu navigation and selection
if (lcdOn) {
handleMenuNavigation();
}
}
// Function to handle menu navigation and selection
void handleMenuNavigation() {
if (!digitalRead(downButton)) {
menu++;
updateMenu();
delay(100);
while (!digitalRead(downButton));
Serial.println("down");
}
if (!digitalRead(upButton)) {
menu--;
updateMenu();
delay(100);
while (!digitalRead(upButton));
Serial.println("up");
}
if (!digitalRead(selectButton)) {
executeAction();
updateMenu();
delay(100);
while (!digitalRead(selectButton));
Serial.println("select");
}
}
// Update the displayed menu based on current selection
void updateMenu() {
switch (menu) {
case 0:
lcd.clear();
lcd.print(">>Time/Date");
lcd.setCursor(0, 1);
lcd.print(" Add Cycle");
break;
case 1:
lcd.clear();
lcd.print(">>Add Cycle");
lcd.setCursor(0, 1);
lcd.print(" Cancel Cycle");
break;
case 2:
lcd.clear();
lcd.print(" Add Cycle");
lcd.setCursor(0, 1);
lcd.print(">>Cancel Cycle");
break;
}
}
// Execute action based on the current menu selection
void executeAction() {
switch (menu) {
case 0:
action0();
break;
case 1:
action1();
break;
case 2:
action2();
break;
}
}
// Display time and date
void action0() {
DateTime now = rtc.now(); // Get current date and time
lcd.clear();
lcd.setCursor(3, 0);
lcd.print(now.year(), DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.day(), DEC);
lcd.setCursor(3, 1);
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
delay(1500);
}
// Add cycle action
void action1() {
lcd.clear();
lcd.print(" > Add Cycle <");
delay(1500);
}
// Cancel cycle action
void action2() {
lcd.clear();
lcd.print(" > Cancel Cycle <");
delay(1500);
}
// Disable all buttons except the menu button
void disableOtherButtons() {
pinMode(upButton, INPUT_PULLUP);
pinMode(downButton, INPUT_PULLUP);
pinMode(selectButton, INPUT_PULLUP);
Serial.println("Other buttons disabled");
}
// Enable all buttons for menu navigation
void enableOtherButtons() {
pinMode(upButton, INPUT);
pinMode(downButton, INPUT);
pinMode(selectButton, INPUT);
Serial.println("Other buttons enabled");
}