#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
// Pin definitions
#define INCREMENT_BUTTON 2
#define DECREMENT_BUTTON 3
#define START_RESET_BUTTON 4
#define BUZZER_PIN 5
// LCD setup
LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address to 0x27 for a 16x2 display
// Variables
int setTime = 1; // Default time in minutes
int remainingTime = 0; // Remaining time in seconds
bool countdownActive = false;
bool buzzerActive = false;
bool inSetTimeScreen = false; // Track if we are in the set time screen
unsigned long previousMillis = 0;
const long interval = 1000; // 1 second interval
// EEPROM address for storing the set time
const int eepromAddress = 0;
void setup() {
// Initialize LCD
lcd.begin(16, 2); // Initialize the LCD with 16 columns and 2 rows
lcd.backlight();
// Show initial screen message
showInitialScreen();
// Initialize buttons
pinMode(INCREMENT_BUTTON, INPUT_PULLUP);
pinMode(DECREMENT_BUTTON, INPUT_PULLUP);
pinMode(START_RESET_BUTTON, INPUT_PULLUP);
// Initialize buzzer
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
// Load saved time from EEPROM
setTime = EEPROM.read(eepromAddress);
if (setTime < 1 || setTime > 60) {
setTime = 18; // Default to 1 minute if EEPROM value is invalid
}
}
void loop() {
// Handle button presses
if (!countdownActive) {
if (!inSetTimeScreen) {
// Initial screen: Wait for user to press Enter to go to set time screen
if (digitalRead(START_RESET_BUTTON) == LOW) {
delay(200); // Debounce
inSetTimeScreen = true; // Transition to set time screen
lcd.clear();
lcd.print("Set Time: ");
lcd.setCursor(0, 1);
lcd.print(setTime);
lcd.print(" min");
while (digitalRead(START_RESET_BUTTON) == LOW); // Wait for button release
}
} else {
// Set time screen: Allow user to set time and start countdown
if (digitalRead(INCREMENT_BUTTON) == LOW) {
delay(200); // Debounce
if (setTime < 60) {
setTime++;
updateDisplay();
}
while (digitalRead(INCREMENT_BUTTON) == LOW); // Wait for button release
}
if (digitalRead(DECREMENT_BUTTON) == LOW) {
delay(200); // Debounce
if (setTime > 1) {
setTime--;
updateDisplay();
}
while (digitalRead(DECREMENT_BUTTON) == LOW); // Wait for button release
}
if (digitalRead(START_RESET_BUTTON) == LOW) {
delay(200); // Debounce
startCountdown();
while (digitalRead(START_RESET_BUTTON) == LOW); // Wait for button release
}
}
} else {
// Countdown logic
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
remainingTime--;
updateDisplay();
// Check if countdown is complete
if (remainingTime <= 0) {
countdownActive = false;
buzzerActive = true;
lcd.clear();
lcd.print("Time's up!");
digitalWrite(BUZZER_PIN, HIGH); // Continuous buzzer
// Wait for 2 seconds before resetting to the initial screen
delay(2000);
resetSystem();
} else if (remainingTime <= 10) {
// Beep for the last 10 seconds
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
}
}
// Reset on start button press
if (digitalRead(START_RESET_BUTTON) == LOW) {
delay(200); // Debounce
resetSystem();
beep();
}
}
}
void showInitialScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ALARM V 1.0 ");
lcd.setCursor(0, 1);
lcd.print("Press Enter Start");
}
void updateDisplay() {
lcd.setCursor(10, 0);
lcd.print(" "); // Clear previous time
lcd.setCursor(10, 0);
lcd.print(setTime);
lcd.print(" min");
if (countdownActive) {
lcd.setCursor(0, 1);
lcd.print("Remaining: ");
lcd.print(remainingTime / 60);
lcd.print(":");
if (remainingTime % 60 < 10) lcd.print("0");
lcd.print(remainingTime % 60);
}
}
void startCountdown() {
// Save the set time to EEPROM
EEPROM.write(eepromAddress, setTime);
// Initialize countdown
remainingTime = setTime * 60;
countdownActive = true;
buzzerActive = false;
lcd.clear();
lcd.print("Countdown:");
updateDisplay();
}
void resetSystem() {
countdownActive = false;
buzzerActive = false;
inSetTimeScreen = false;
digitalWrite(BUZZER_PIN, LOW);
showInitialScreen();
}
void beep() {
tone(BUZZER_PIN, 1000); // 1kHz beep
delay(100);
noTone(BUZZER_PIN);
}