#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
// LCD and button definitions
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int startButton = 2;
const int resetButton = 3;
const int upButton = 4;
const int downButton = 5;
const int selectButton = 6;
const int relayPin = 7;
// Variables to store the on/off times and number of cycles
int onSeconds = 0;
int onMinutes = 0;
int onHours = 0;
int offSeconds = 0;
int offMinutes = 0;
int offHours = 0;
int numCycles = 0;
// Enum to track the current menu being displayed
enum Menu {
ON_SECONDS,
ON_MINUTES,
ON_HOURS,
OFF_SECONDS,
OFF_MINUTES,
OFF_HOURS,
NUM_CYCLES,
START,
STOP
};
Menu currentMenu = ON_SECONDS;
bool isProgramRunning = false;
void setup() {
// Initialize the LCD screen and buttons
lcd.begin(0,0);
pinMode(startButton, INPUT_PULLUP);
pinMode(resetButton, INPUT_PULLUP);
pinMode(upButton, INPUT_PULLUP);
pinMode(downButton, INPUT_PULLUP);
pinMode(selectButton, INPUT_PULLUP);
pinMode(relayPin, OUTPUT);
// Load the on/off times and number of cycles from EEPROM
onSeconds = EEPROM.read(0);
onMinutes = EEPROM.read(1);
onHours = EEPROM.read(2);
offSeconds = EEPROM.read(3);
offMinutes = EEPROM.read(4);
offHours = EEPROM.read(5);
numCycles = EEPROM.read(6);
}
void loop() {
// Check the buttons and update the values accordingly
if (digitalRead(resetButton) == LOW) {
resetValues();
} else if (digitalRead(upButton) == LOW) {
incrementValue();
} else if (digitalRead(downButton) == LOW) {
decrementValue();
} else if (digitalRead(selectButton) == LOW) {
nextMenu();
} else if (digitalRead(startButton) == LOW) {
if (isProgramRunning) {
stopProgram();
} else {
startProgram();
}
}
// Display the current menu on the LCD screen
displayMenu();
delay(500);
}
void resetValues() {
// Reset the on/off times and number of cycles to their default values
onSeconds = 0;
onMinutes = 0;
onHours = 0;
offSeconds = 0;
offMinutes = 0;
offHours = 0;
numCycles = 0;
// Save the reset values to EEPROM
EEPROM.write(0, onSeconds);
EEPROM.write(1, onMinutes);
EEPROM.write(2, onHours);
EEPROM.write(3, offSeconds);
EEPROM.write(4, offMinutes);
EEPROM.write(5, offHours);
EEPROM.write(6, numCycles);
}
void incrementValue() {
// Increment the value for the current menu
switch (currentMenu) {
case ON_SECONDS:
onSeconds++;
if (onSeconds > 59) {
onSeconds = 0;
}
break;
case ON_MINUTES:
onMinutes++;
if (onMinutes > 59) {
onMinutes = 0;
}
break;
case ON_HOURS:
onHours++;
if (onHours > 23) {
onHours = 0;
}
break;
case OFF_SECONDS:
offSeconds++;
if (offSeconds > 59) {
offSeconds = 0;
}
break;
case OFF_MINUTES:
offMinutes++;
if (offMinutes > 59) {
offMinutes = 0;
}
break;
case OFF_HOURS:
offHours++;
if (offHours > 23) {
offHours = 0;
}
break;
case NUM_CYCLES:
numCycles++;
break;
default:
break;
}
}
void decrementValue() {
// Decrement the value for the current menu
switch (currentMenu) {
case ON_SECONDS:
onSeconds--;
if (onSeconds < 0) {
onSeconds = 59;
}
break;
case ON_MINUTES:
onMinutes--;
if (onMinutes < 0) {
onMinutes = 59;
}
break;
case ON_HOURS:
onHours--;
if (onHours < 0) {
onHours = 23;
}
break;
case OFF_SECONDS:
offSeconds--;
if (offSeconds < 0) {
offSeconds = 59;
}
break;
case OFF_MINUTES:
offMinutes--;
if (offMinutes < 0) {
offMinutes = 59;
}
break;
case OFF_HOURS:
offHours--;
if (offHours < 0) {
offHours = 23;
}
break;
case NUM_CYCLES:
numCycles--;
if (numCycles < 0) {
numCycles = 0;
}
break;
default:
break;
}
}
void nextMenu() {
// Move to the next menu
switch (currentMenu) {
case ON_SECONDS:
currentMenu = ON_MINUTES;
break;
case ON_MINUTES:
currentMenu = ON_HOURS;
break;
case ON_HOURS:
currentMenu = OFF_SECONDS;
break;
case OFF_SECONDS:
currentMenu = OFF_MINUTES;
break;
case OFF_MINUTES:
currentMenu = OFF_HOURS;
break;
case OFF_HOURS:
currentMenu = NUM_CYCLES;
break;
case NUM_CYCLES:
currentMenu = ON_SECONDS;
break;
default:
break;
}
}
void previousMenu() {
// Move to the previous menu
switch (currentMenu) {
case ON_SECONDS:
currentMenu = NUM_CYCLES;
break;
case ON_MINUTES:
currentMenu = ON_SECONDS;
break;
case ON_HOURS:
currentMenu = ON_MINUTES;
break;
case OFF_SECONDS:
currentMenu = ON_HOURS;
break;
case OFF_MINUTES:
currentMenu = OFF_SECONDS;
break;
case OFF_HOURS:
currentMenu = OFF_MINUTES;
break;
case NUM_CYCLES:
currentMenu = OFF_HOURS;
break;
default:
break;
}
}
void startProgram() {
Menu currentMenu = START;
// If the program is running, stop it and set the relay to off
if (isProgramRunning) {
isProgramRunning = false;
digitalWrite(relayPin, LOW);
return;
}
// Otherwise, start the program and set the relay to on
isProgramRunning = true;
digitalWrite(relayPin, HIGH);
// Keep track of the current cycle and on/off time
int currentCycle = 0;
unsigned long onTime = 0;
unsigned long offTime = 0;
// Calculate the on and off times in milliseconds
onTime = (onHours * 3600 + onMinutes * 60 + onSeconds) * 1000;
offTime = (offHours * 3600 + offMinutes * 60 + offSeconds) * 1000;
while (isProgramRunning && currentCycle < numCycles) {
// Turn the relay on
digitalWrite(relayPin, HIGH);
delay(onTime);
// Turn the relay off
digitalWrite(relayPin, LOW);
delay(offTime);
// Increment the current cycle
currentCycle++;
}
// Set the relay to off when the program is finished
digitalWrite(relayPin, LOW);
}
void stopProgram() {
Menu currentMenu = STOP;
isProgramRunning = false;
}
void displayMenu() {
switch (currentMenu) {
lcd.clear
case ON_SECONDS:
lcd.setCursor(0, 0);
lcd.print("On Time (secs):");
lcd.setCursor(17, 0);
lcd.print(onSeconds);
break;
case ON_MINUTES:
lcd.setCursor(0, 0);
lcd.print("On Time (mins):");
lcd.setCursor(17, 0);
lcd.print(onMinutes);
break;
case ON_HOURS:
lcd.setCursor(0, 0);
lcd.print("On Time (hours):");
lcd.setCursor(17, 0);
lcd.print(onHours);
break;
case OFF_SECONDS:
lcd.setCursor(0, 0);
lcd.print("Off Time (secs):");
lcd.setCursor(17, 0);
lcd.print(offSeconds);
break;
case OFF_MINUTES:
lcd.setCursor(0, 0);
lcd.print("Off Time (mins):");
lcd.setCursor(17, 0);
lcd.print(offMinutes);
break;
case OFF_HOURS:
lcd.setCursor(0, 0);
lcd.print("Off Time (hours):");
lcd.setCursor(17, 0);
lcd.print(offHours);
break;
case NUM_CYCLES:
lcd.setCursor(0, 0);
lcd.print("Num Cycles:");
lcd.setCursor(13, 0);
lcd.print(numCycles);
break;
case START:
lcd.setCursor(0, 0);
lcd.print("Start Program:");
lcd.setCursor(0, 1);
lcd.print("Press to Start");
break;
case STOP:
lcd.setCursor(0, 0);
lcd.print("Stop Program:");
lcd.setCursor(0, 1);
lcd.print("Press to Stop");
break;
default:
break;
}
}