#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DS1307RTC.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define BUZZER_PIN 2
#define BUTTON_PIN_SET 3
#define BUTTON_PIN_HOUR 4
#define BUTTON_PIN_MIN 5
#define BUTTON_PIN_STOP 6
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int alarmHour = 6;
int alarmMinute = 00;
int alarmSecond = 00;
String alarmAMPM = "AM";
bool buzzerActive = false;
bool alarmEnabled = true;
bool alarmSetMode = false;
bool hourEditMode = false;
bool minuteEditMode = false;
int lastState = LOW; // the previous state from the input pin
int currentState; // the current reading from the input pin
unsigned long pressedTime = 0;
unsigned long releasedTime = 0;
tmElements_t tm;
int hour12 = (tm.Hour % 12 == 0) ? 12 : tm.Hour % 12;
String ampm = (tm.Hour < 12) ? "AM" : "PM";
void setup() {
Serial.begin(115200);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
pinMode(BUZZER_PIN, OUTPUT);
pinMode(BUTTON_PIN_SET, INPUT_PULLUP);
pinMode(BUTTON_PIN_HOUR, INPUT_PULLUP);
pinMode(BUTTON_PIN_MIN, INPUT_PULLUP);
pinMode(BUTTON_PIN_STOP, INPUT_PULLUP);
delay(100);
display.clearDisplay();
display.setTextColor(WHITE);
}
void printDateTime(tmElements_t tm, bool showAMPM = true) {
int hour12 = (tm.Hour % 12 == 0) ? 12 : tm.Hour % 12;
String ampm = (tm.Hour < 12) ? "AM" : "PM";
// MM/DD/YY
display.print(tm.Month);
display.print("/");
display.print(tm.Day);
display.print("/");
display.print((tmYearToCalendar(tm.Year)) % 100);
display.print(" ");
// HH:MM
display.print(hour12);
if (tm.Second % 2 == 0) {
display.print(":");
} else {
display.print(" ");
}
if (tm.Minute < 10) display.print("0");
display.print(tm.Minute);
if (showAMPM) {
display.print(" ");
display.println(ampm);
}
}
void printAlarmTime() {
display.print(" Alarm Time: ");
display.print(alarmHour);
display.print(":");
if (alarmMinute < 10) display.print("0");
display.print(alarmMinute);
display.print(" ");
display.println(alarmAMPM);
}
void printSetAlarmTime() {
display.print(" Set Alarm: ");
display.setTextColor(BLACK, WHITE);
static bool ampmChangeDone = false;
if (hourEditMode) {
if (alarmHour == 12 && !ampmChangeDone) {
if (alarmAMPM == "AM") {
alarmAMPM = "PM";
} else {
alarmAMPM = "AM";
}
ampmChangeDone = true;
}
else if (alarmHour != 12) {
ampmChangeDone = false;
}
if (alarmHour < 10) {
display.print(" ");
}
display.print(alarmHour);
display.print(":");
} else {
if (alarmHour < 10) {
display.print(" ");
}
display.print(alarmHour);
display.print(":");
}
if (alarmMinute < 10) display.print("0");
display.print(alarmMinute);
display.print(" ");
display.println(alarmAMPM);
}
void loop() {
// Read current time
tmElements_t tm;
RTC.read(tm);
// Initialize screen
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
// Display current date/time
display.setCursor(0, 0);
int hour12 = (tm.Hour % 12 == 0) ? 12 : tm.Hour % 12;
String ampm = (tm.Hour < 12) ? "AM" : "PM";
printDateTime(tm);
if (!alarmEnabled) {
display.setCursor(0, 15);
display.print(" Alarm OFF");
display.setCursor(0, 27);
display.print(" SLEEP IN, BOZO");
} else {
display.setCursor(0, 15);
display.print(" Alarm ON");
display.setCursor(0, 27);
display.print(" GET UP, BOZO");
}
// Setting the alarm
if (alarmSetMode) {
// Hour adjust
if (digitalRead(BUTTON_PIN_HOUR) == LOW) {
hourEditMode = !hourEditMode;
if (hourEditMode) {
alarmHour = (alarmHour + 1) % 13;
if (alarmHour == 0) alarmHour = 1;
delay(50);
}
}
// Minute adjust
if (digitalRead(BUTTON_PIN_MIN) == LOW) {
minuteEditMode = !minuteEditMode;
if (minuteEditMode) {
alarmMinute = (alarmMinute + 1) % 60;
delay(50);
}
}
}
// Display alarm time
display.setCursor(0, 50);
if (alarmSetMode) {
printSetAlarmTime();
} else {
printAlarmTime();
}
// Toggle between Alarm on/off
int currentState = digitalRead(BUTTON_PIN_SET);
if (lastState == HIGH && currentState == LOW) { // button is pressed
pressedTime = millis();
}
else if (lastState == LOW && currentState == HIGH) { // button is released
releasedTime = millis();
long pressDuration = releasedTime - pressedTime;
if (pressDuration < 1000) // Short press = alarm set mode
alarmSetMode = !alarmSetMode;
if(pressDuration > 1000) // Long press = enable/disable alarm
alarmEnabled = !alarmEnabled;
}
// Save the last state
lastState = currentState;
// Alarm Conditions
//if (hour12 == alarmHour && tm.Minute == alarmMinute && tm.Second == alarmSecond && ampm == alarmAMPM && alarmEnabled == true) {
if (hour12 == alarmHour && tm.Minute == alarmMinute && tm.Second == alarmSecond && ampm == alarmAMPM && alarmEnabled == true && alarmSetMode == false) {
if (!buzzerActive) {
tone(BUZZER_PIN, 1000);
buzzerActive = true;
}
}
// Check if the button is pressed to stop the alarm
if (digitalRead(BUTTON_PIN_STOP) == LOW && alarmEnabled == true) {
noTone(BUZZER_PIN);
buzzerActive = false;
delay(50); // Debounce delay
pinMode(BUTTON_PIN_STOP, INPUT_PULLUP);
}
display.display();
delay(50);
}
// 1/16/24
// added white text for alarm set time. had to rearrange code in void loop() and add stuff to printAlarmSetTime