#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Initialize the LCD with the correct I2C address and dimensions
LiquidCrystal_I2C lcd(0x27, 16, 2); // Change 0x27 to your LCD's I2C address
// Pin definitions
const int startButtonPin = 3; // Button to start the timer
const int setButtonPin = 2; // Button to change the timer setting
const int alarmPin = 4; // Alarm output (e.g., buzzer or LED)
// Timer variables
unsigned long timerDuration = 60 * 60 * 1000; // Default: 60 minutes in milliseconds
unsigned long remainingTime = timerDuration;
unsigned long startTime = 0;
bool timerRunning = false;
bool alarmTriggered = false;
// Timer options
const int timerOptions[] = {15, 30, 45, 60}; // Timer options in minutes
int currentTimerIndex = 3; // Default: 60 minutes (index 3)
void setup() {
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Timer: 60 min");
lcd.setCursor(0, 1);
lcd.print("Press to start");
// Set pin modes
pinMode(startButtonPin, INPUT_PULLUP);
pinMode(setButtonPin, INPUT_PULLUP);
pinMode(alarmPin, OUTPUT);
// Initialize outputs
digitalWrite(alarmPin, LOW);
}
void loop() {
// Check if the set button is pressed to change the timer
if (digitalRead(setButtonPin) == LOW) {
delay(200); // Debounce delay
changeTimer();
while (digitalRead(setButtonPin) == LOW); // Wait for button release
}
// Check if the start button is pressed to start the timer
if (digitalRead(startButtonPin) == LOW) {
delay(200); // Debounce delay
startTimer();
while (digitalRead(startButtonPin) == LOW); // Wait for button release
}
// Update the countdown timer if it is running
if (timerRunning) {
updateCountdown();
}
// Check if the timer has expired
if (timerRunning && remainingTime <= 0) {
timerRunning = false;
triggerAlarm();
}
}
void changeTimer() {
// Cycle through timer options
currentTimerIndex = (currentTimerIndex + 1) % 4;
timerDuration = timerOptions[currentTimerIndex] * 60 * 1000; // Convert minutes to milliseconds
remainingTime = timerDuration;
// Update the LCD display
lcd.setCursor(0, 0);
lcd.print("Timer: ");
lcd.print(timerOptions[currentTimerIndex]);
lcd.print(" min ");
// Reset the timer if it was running
if (timerRunning) {
timerRunning = false;
lcd.setCursor(0, 1);
lcd.print("Press to start");
}
}
void startTimer() {
if (!timerRunning && !alarmTriggered) {
startTime = millis();
timerRunning = true;
lcd.setCursor(0, 1);
lcd.print("Running... ");
}
}
void updateCountdown() {
unsigned long elapsedTime = millis() - startTime;
remainingTime = timerDuration - elapsedTime;
// Display the remaining time on the LCD
int minutes = remainingTime / 60000;
int seconds = (remainingTime % 60000) / 1000;
lcd.setCursor(0, 1);
lcd.print("Time left: ");
if (minutes < 10) lcd.print("0");
lcd.print(minutes);
lcd.print(":");
if (seconds < 10) lcd.print("0");
lcd.print(seconds);
lcd.print(" ");
}
void triggerAlarm() {
// Trigger the alarm
digitalWrite(alarmPin, HIGH);
alarmTriggered = true;
// Display alarm message on LCD
lcd.setCursor(0, 1);
lcd.print("Alarm! ");
// Keep the alarm on until reset
while (alarmTriggered) {
if (digitalRead(startButtonPin) == LOW) {
delay(200); // Debounce delay
resetAlarm();
while (digitalRead(startButtonPin) == LOW); // Wait for button release
}
}
}
void resetAlarm() {
// Reset the alarm and timer
digitalWrite(alarmPin, LOW);
alarmTriggered = false;
timerRunning = false;
remainingTime = timerDuration;
// Update the LCD display
lcd.setCursor(0, 1);
lcd.print("Press to start");
}