#include <LiquidCrystal.h>
#include <EEPROM.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// Timer variables
int hours[4] = {0, 0, 0, 0};
int minutes[4] = {0, 0, 0, 0};
int seconds[4] = {0, 0, 0, 0};
unsigned long startTime[4] = {0, 0, 0, 0};
const unsigned long updateInterval = 1000;
// Button pins
const int buttonPins[5] = {6, 7, 8, 9, 10};
int buttonStates[5] = {HIGH, HIGH, HIGH, HIGH, HIGH};
// Alarm variables
int alarmHours[4] = {0, 0, 0, 0};
int alarmMinutes[4] = {0, 0, 0, 0};
bool alarmEnabled[4] = {false, false, false, false};
// Setting mode
int settingChannel = -1;
// Buzzer pin
const int buzzerPin = 13;
unsigned long buttonPressTime[4] = {0, 0, 0, 0};
unsigned long alarmStartTime[4] = {0, 0, 0, 0};
// Global variable declaration
bool setButtonPressed = false;
bool alarmSettingMode = false;
bool displayNeedsUpdate = true;
// Function declarations
void readAlarmsFromEEPROM();
void writeAlarmsToEEPROM();
void checkAlarm(int channel);
void resetTimer(int channel);
void stopAlarm(int channel);
void displayTimers();
void updateTimer(int channel);
void printTime(int h, int m);
void readButtons();
void handleButtons();
void displayAllAlarms();
void displayAlarmSettings(int channel);
void setup() {
lcd.begin(16, 2);
Serial.begin(9600); // Initialize Serial communication
for (int i = 0; i < 4; i++) {
startTime[i] = millis();
}
for (int i = 0; i < 5; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
pinMode(buzzerPin, OUTPUT);
readAlarmsFromEEPROM();
displayTimers();
}
void loop() {
unsigned long currentTime = millis();
bool anyTimerUpdated = false;
for (int i = 0; i < 4; i++) {
if (currentTime - startTime[i] >= updateInterval) {
startTime[i] += updateInterval;
seconds[i]++;
if (seconds[i] >= 60) {
seconds[i] = 0;
minutes[i]++;
if (minutes[i] >= 60) {
minutes[i] = 0;
hours[i]++;
if (hours[i] >= 100) {
hours[i] = 0;
}
}
}
checkAlarm(i);
startTime[i] = currentTime;
if (!alarmSettingMode) {
updateTimer(i);
anyTimerUpdated = true;
}
}
}
readButtons();
handleButtons();
if (displayNeedsUpdate || anyTimerUpdated) {
if (alarmSettingMode) {
displayAllAlarms();
} else {
displayTimers();
}
displayNeedsUpdate = false;
}
}
void displayTimers() {
static int previousHours[4] = { -1, -1, -1, -1 };
static int previousMinutes[4] = { -1, -1, -1, -1 };
static int previousSeconds[4] = { -1, -1, -1, -1 };
for (int i = 0; i < 4; i++) {
if (hours[i] != previousHours[i] ||
minutes[i] != previousMinutes[i] ||
seconds[i] != previousSeconds[i]) {
lcd.setCursor((i % 2) * 8, i / 2);
lcd.print(i + 1);
lcd.print("-");
if (hours[i] > 0) {
printTime(hours[i], minutes[i]);
} else {
printTime(minutes[i], seconds[i]);
}
lcd.print(" ");
previousHours[i] = hours[i];
previousMinutes[i] = minutes[i];
previousSeconds[i] = seconds[i];
}
}
}
void updateTimer(int channel) {
static int previousHours[4] = { -1, -1, -1, -1 };
static int previousMinutes[4] = { -1, -1, -1, -1 };
static int previousSeconds[4] = { -1, -1, -1, -1 };
if (hours[channel] != previousHours[channel] ||
minutes[channel] != previousMinutes[channel] ||
seconds[channel] != previousSeconds[channel]) {
int cursorPosition = (channel < 2) ? (channel * 8 + 2) : ((channel - 2) * 8 + 2);
int row = (channel < 2) ? 0 : 1;
lcd.setCursor(cursorPosition, row);
if (hours[channel] > 0) {
printTime(hours[channel], minutes[channel]);
} else {
printTime(minutes[channel], seconds[channel]);
}
previousHours[channel] = hours[channel];
previousMinutes[channel] = minutes[channel];
previousSeconds[channel] = seconds[channel];
}
}
void printTime(int h, int m) {
if (h < 10) lcd.print("0");
lcd.print(h);
lcd.print(":");
if (m < 10) lcd.print("0");
lcd.print(m);
}
void readButtons() {
for (int i = 0; i < 5; i++) {
buttonStates[i] = digitalRead(buttonPins[i]);
}
}
void handleButtons() {
unsigned long currentTime = millis();
static unsigned long lastSetButtonReleaseTime = 0;
if (buttonStates[4] == LOW) {
if (!setButtonPressed) {
alarmSettingMode = true;
setButtonPressed = true;
displayNeedsUpdate = true;
}
bool alarmUpdated = false;
for (int i = 0; i < 4; i++) {
if (buttonStates[i] == LOW) {
alarmMinutes[i]++;
if (alarmMinutes[i] >= 60) {
alarmMinutes[i] = 0;
alarmHours[i]++;
if (alarmHours[i] >= 100) {
alarmHours[i] = 0;
}
}
alarmUpdated = true;
delay(150);
}
}
if (alarmUpdated) {
displayNeedsUpdate = true;
}
} else {
lastSetButtonReleaseTime = currentTime;
if (alarmSettingMode) {
writeAlarmsToEEPROM();
for (int i = 0; i < 4; i++) {
if (alarmHours[i] != 0 || alarmMinutes[i] != 0) {
alarmEnabled[i] = true;
}
}
}
alarmSettingMode = false;
setButtonPressed = false;
}
if (!alarmSettingMode) {
for (int i = 0; i < 4; i++) {
if (buttonStates[i] == LOW) {
if (buttonPressTime[i] == 0) {
buttonPressTime[i] = currentTime;
}
if (currentTime - buttonPressTime[i] > 500) {
resetTimer(i);
displayNeedsUpdate = true;
buttonPressTime[i] = currentTime;
}
} else {
if (buttonPressTime[i] != 0 && currentTime - buttonPressTime[i] <= 500) {
stopAlarm(i);
displayNeedsUpdate = true
;}
buttonPressTime[i] = 0;
}
}
}
}
void displayAllAlarms() {
lcd.clear();
for (int i = 0; i < 4; i++) {
lcd.setCursor((i % 2) * 8, i / 2);
lcd.print(i + 1);
lcd.print("-");
printTime(alarmHours[i], alarmMinutes[i]);
}
}
void displayAlarmSettings(int channel) {
lcd.clear();
lcd.print("Set alarm ");
lcd.print(channel + 1);
lcd.setCursor(0, 1);
lcd.print(alarmHours[channel]);
lcd.print(":");
lcd.print(alarmMinutes[channel]);
}
void checkAlarm(int channel) {
static bool blinkState[4] = {false, false, false, false};
static unsigned long previousMillis[4] = {0, 0, 0, 0};
const int blinkInterval = 250;
Serial.print("Channel: ");
Serial.print(channel);
Serial.print(", Enabled: ");
Serial.print(alarmEnabled[channel]);
Serial.print(", Alarm Time: ");
Serial.print(alarmHours[channel]);
Serial.print(":");
Serial.print(alarmMinutes[channel]);
if (alarmEnabled[channel] && (alarmHours[channel] != 0 && alarmMinutes[channel] != 0)) {
unsigned long currentMillis = millis();
unsigned long elapsedTime = hours[channel] * 60 + minutes[channel];
unsigned long alarmTime = alarmHours[channel] * 60 + alarmMinutes[channel];
Serial.print(", Elapsed Time: ");
Serial.print(elapsedTime);
Serial.print(", Alarm Time (min): ");
Serial.println(alarmTime);
if (elapsedTime >= alarmTime) {
Serial.println("Alarm Triggered!"); // Debugging message
tone(buzzerPin, 1000);
if (alarmStartTime[channel] == 0) {
alarmStartTime[channel] = millis();
}
if (millis() - alarmStartTime[channel] >= 2000) {
noTone(buzzerPin);
alarmStartTime[channel] = 0;
}
if (currentMillis - previousMillis[channel] >= blinkInterval) {
previousMillis[channel] = currentMillis;
blinkState[channel] = !blinkState[channel];
lcd.setCursor((channel % 2) * 8, channel / 2);
if (blinkState[channel]) {
lcd.print(channel + 1);
lcd.print("-");
if (hours[channel] > 0) {
printTime(hours[channel], minutes[channel]);
} else {
printTime(minutes[channel], seconds[channel]);
}
lcd.print(" ");
} else {
lcd.print(" ");
}
}
} else {
alarmStartTime[channel] = 0;
noTone(buzzerPin);
lcd.setCursor((channel % 2) * 8, channel / 2);
lcd.print(channel + 1);
lcd.print("-");
if (hours[channel] > 0) {
printTime(hours[channel], minutes[channel]);
} else {
printTime(minutes[channel], seconds[channel]);
}
lcd.print(" ");
}
} else {
Serial.println(); // Just a newline for clarity
}
}
void resetTimer(int channel) {
hours[channel] = 0;
minutes[channel] = 0;
seconds[channel] = 0;
updateTimer(channel);
}
void stopAlarm(int channel) {
alarmEnabled[channel] = false;
noTone(buzzerPin);
displayTimers();
}
void readAlarmsFromEEPROM() {
for (int i = 0; i < 4; i++) {
int hour = EEPROM.read(i * 2);
int minute = EEPROM.read(i * 2 + 1);
if (hour >= 0 && hour < 100 && minute >= 0 && minute < 60) {
alarmHours[i] = hour;
alarmMinutes[i] = minute;
} else {
alarmHours[i] = 0;
alarmMinutes[i] = 0;
}
}
}
void writeAlarmsToEEPROM() {
for (int i = 0; i < 4; i++) {
EEPROM.write(i * 2, alarmHours[i]);
EEPROM.write(i * 2 + 1, alarmMinutes[i]);
}
}