#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// OLED Configuration
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// RTC Module
RTC_DS3231 rtc;
// Button Pins
#define BTN_INC 7 // Increment button
#define BTN_DEC 9 // Decrement button
#define BTN_MODE 10 // Change mode button
// Alarm Pin
#define ALARM_PIN 8
// Modes for adjusting time and alarms
enum Mode { YEAR, MONTH, DAY, HOUR, MINUTE, SET_ALARM };
Mode currentMode = YEAR;
// Time variables
int year = 2024, month = 12, day = 2, hour = 20, minute = 7, second = 0; // Set to 8:07 PM
// Alarm times and labels (24-hour format)
const int alarmCount = 6;
int alarmTimes[alarmCount][2] = {
{8, 0}, // Breakfast
{9, 15}, // Get ready for ITI
{12, 1}, // Lunch
{13, 0}, // Lunch end
{17, 30}, // Tea
{19, 0} // Dinner
};
const char* alarmLabels[alarmCount] = {
"Breakfast", "Get Ready for ITI", "Lunch", "Lunch End", "Tea", "Dinner"
};
bool isHoliday = false; // Flag for holidays
String currentAlarmStatus = "No Alarm"; // To display current alarm status
void setup() {
// Initialize Serial Monitor
Serial.begin(9600);
// Initialize OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
while (1);
}
display.clearDisplay();
// Initialize RTC
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
// Initialize buttons
pinMode(BTN_INC, INPUT_PULLUP);
pinMode(BTN_DEC, INPUT_PULLUP);
pinMode(BTN_MODE, INPUT_PULLUP);
// Initialize Alarm
pinMode(ALARM_PIN, OUTPUT);
digitalWrite(ALARM_PIN, LOW);
// Set RTC to start at 8:07 PM, December 2, 2024
rtc.adjust(DateTime(year, month, day, hour, minute, second));
}
void loop() {
DateTime now = rtc.now();
// Check buttons for manual adjustments
if (digitalRead(BTN_INC) == LOW) {
incrementValue();
delay(200); // Debounce
}
if (digitalRead(BTN_DEC) == LOW) {
decrementValue();
delay(200); // Debounce
}
if (digitalRead(BTN_MODE) == LOW) {
changeMode();
delay(200); // Debounce
}
// Check and trigger alarm
triggerAlarm(now);
// Update OLED
displayStatus(now);
}
void incrementValue() {
switch (currentMode) {
case YEAR: year++; break;
case MONTH: month = (month % 12) + 1; break;
case DAY: day = (day % 31) + 1; break;
case HOUR: hour = (hour + 1) % 24; break;
case MINUTE: minute = (minute + 1) % 60; break;
case SET_ALARM:
alarmTimes[0][0]++; // Increment the first alarm for testing
break;
}
}
void decrementValue() {
switch (currentMode) {
case YEAR: year--; break;
case MONTH: month = (month == 1) ? 12 : month - 1; break;
case DAY: day = (day == 1) ? 31 : day - 1; break;
case HOUR: hour = (hour == 0) ? 23 : hour - 1; break;
case MINUTE: minute = (minute == 0) ? 59 : minute - 1; break;
case SET_ALARM:
alarmTimes[0][0]--; // Decrement the first alarm for testing
break;
}
}
void changeMode() {
currentMode = static_cast<Mode>((currentMode + 1) % 6);
}
void displayStatus(DateTime now) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
// Display current time
display.print("Date: ");
display.print(now.year());
display.print('/');
display.print(now.month());
display.print('/');
display.println(now.day());
display.print("Time: ");
if (now.hour() < 10) display.print('0');
display.print(now.hour());
display.print(':');
if (now.minute() < 10) display.print('0');
display.print(now.minute());
display.print(':');
if (now.second() < 10) display.print('0');
display.println(now.second());
// Display current mode
display.print("Mode: ");
switch (currentMode) {
case YEAR: display.println("Year"); break;
case MONTH: display.println("Month"); break;
case DAY: display.println("Day"); break;
case HOUR: display.println("Hour"); break;
case MINUTE: display.println("Minute"); break;
case SET_ALARM: display.println("Set Alarm"); break;
}
// Display current alarm status
display.setCursor(0, 48);
display.print("Alarm: ");
display.println(currentAlarmStatus);
display.display();
}
void triggerAlarm(DateTime now) {
// Check if today is Sunday or a holiday
if (now.dayOfTheWeek() == 0 || isHoliday) {
digitalWrite(ALARM_PIN, LOW); // No alarm
currentAlarmStatus = "Holiday";
return;
}
// Check if the current time matches any alarm time
currentAlarmStatus = "No Alarm"; // Default status
for (int i = 0; i < alarmCount; i++) {
if (now.hour() == alarmTimes[i][0] && now.minute() == alarmTimes[i][1]) {
digitalWrite(ALARM_PIN, HIGH); // Turn alarm on
currentAlarmStatus = alarmLabels[i]; // Update alarm status
delay(180000); // Keep alarm on for 3 minutes
digitalWrite(ALARM_PIN, LOW); // Turn alarm off
}
}
}