#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);
// Struct for time
struct TIME {
uint8_t hour;
uint8_t minute;
uint8_t second;
};
// Timer and alarm variables
TIME timers[4];
TIME alarms[4];
bool alarmEnabled[4] = {false, false, false, false};
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};
// 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(uint8_t h, uint8_t m);
void readButtons();
void handleButtons();
void displayAllAlarms();
void displayAlarmSettings(int channel);
void setup() {
lcd.begin(16, 2);
Serial.begin(9600);
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;
timers[i].second++;
if (timers[i].second >= 60) {
timers[i].second = 0;
timers[i].minute++;
if (timers[i].minute >= 60) {
timers[i].minute = 0;
timers[i].hour++;
if (timers[i].hour >= 100) {
timers[i].hour = 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 TIME previousTimers[4];
for (int i = 0; i < 4; i++) {
if (timers[i].hour != previousTimers[i].hour ||
timers[i].minute != previousTimers[i].minute ||
timers[i].second != previousTimers[i].second) {
lcd.setCursor((i % 2) * 8, i / 2);
lcd.print(i + 1);
lcd.print("-");
if (timers[i].hour > 0) {
printTime(timers[i].hour, timers[i].minute);
} else {
printTime(timers[i].minute, timers[i].second);
}
lcd.print(" ");
previousTimers[i] = timers[i];
}
}
}
void updateTimer(int channel) {
static TIME previousTimers[4];
if (timers[channel].hour != previousTimers[channel].hour ||
timers[channel].minute != previousTimers[channel].minute ||
timers[channel].second != previousTimers[channel].second) {
int cursorPosition = (channel < 2) ? (channel * 8 + 2) : ((channel - 2) * 8 + 2);
int row = (channel < 2) ? 0 : 1;
lcd.setCursor(cursorPosition, row);
if (timers[channel].hour > 0) {
printTime(timers[channel].hour, timers[channel].minute);
} else {
printTime(timers[channel].minute, timers[channel].second);
}
previousTimers[channel] = timers[channel];
}
}
void printTime(uint8_t h, uint8_t 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) {
alarms[i].minute++;
if (alarms[i].minute >= 60) {
alarms[i].minute = 0;
alarms[i].hour++;
if (alarms[i].hour >= 100) {
alarms[i].hour = 0;
}
}
alarmUpdated = true;
delay(150);
}
}
if (alarmUpdated) {
displayNeedsUpdate = true;
}
} else {
lastSetButtonReleaseTime = currentTime;
if (alarmSettingMode) {
writeAlarmsToEEPROM();
for (int i = 0; i < 4; i++) {
if (alarms[i].hour != 0 || alarms[i].minute != 0) {
alarmEnabled[i] = true;
} else {
alarmEnabled[i] = false;
}
}
}
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(alarms[i].hour, alarms[i].minute);
}
}
void displayAlarmSettings(int channel) {
lcd;
lcd.clear();
lcd.print("Set alarm ");
lcd.print(channel + 1);
lcd.setCursor(0, 1);
lcd.print(alarms[channel].hour);
lcd.print(":");
lcd.print(alarms[channel].minute);
}
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(alarms[channel].hour);
Serial.print(":");
if (alarms[channel].minute < 10) {
Serial.print("0");
}
Serial.print(alarms[channel].minute);
if (alarmEnabled[channel] && (alarms[channel].hour != 0 || alarms[channel].minute != 0)) {
unsigned long currentMillis = millis();
// Calculate elapsed time in minutes
unsigned long elapsedTime = timers[channel].hour * 60 + timers[channel].minute;
// Calculate alarm time in minutes
unsigned long alarmTime = alarms[channel].hour * 60 + alarms[channel].minute;
// Calculate time left in minutes
long timeLeft = alarmTime - elapsedTime;
// Print values
Serial.print(", Elapsed Time: ");
Serial.print(elapsedTime);
Serial.print(", Alarm Time (min): ");
Serial.print(alarmTime);
Serial.print(", Time Left (min): ");
Serial.println(timeLeft);
if (elapsedTime >= alarmTime) {
Serial.println("Alarm Triggered!");
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("-");
printTime(timers[channel].hour, timers[channel].minute);
lcd.print(" ");
} else {
lcd.print(" ");
}
}
} else {
alarmStartTime[channel] = 0;
noTone(buzzerPin);
lcd.setCursor((channel % 2) * 8, channel / 2);
lcd.print(channel + 1);
lcd.print("-");
printTime(timers[channel].hour, timers[channel].minute);
lcd.print(" ");
}
} else {
Serial.println();
}
}
void resetTimer(int channel) {
timers[channel].hour = 0;
timers[channel].minute = 0;
timers[channel].second = 0;
updateTimer(channel);
}
void stopAlarm(int channel) {
alarmEnabled[channel] = false;
noTone(buzzerPin);
displayTimers();
}
void readAlarmsFromEEPROM() {
for (int i = 0; i < 4; i++) {
EEPROM.get(i * sizeof(TIME), alarms[i]);
}
}
void writeAlarmsToEEPROM() {
for (int i = 0; i < 4; i++) {
EEPROM.put(i * sizeof(TIME), alarms[i]);
}
}