#include #include #include const byte dataPins[7] = {2, 3, 4, 5, 6, 7, 8}; // Segment data pins: D0 - D6 const byte addrPins[2] = {A1, A2}; // Segment address pins: A0, A1 const byte wrenPins[] = {A0, A3}; // Write Enable pins (left to right) RTC_DS3231 rtc; char msg[] = " *** MICRO CLOCK - MIRCEMK *** "; char t[32]; HPDL1414 hpdl(dataPins, addrPins, wrenPins, sizeof(wrenPins)); // Button pins const int buttonHourPin = 9; const int buttonMinutePin = 10; const int buttonSetPin = 11; // Buzzer pin const int buzzerPin = 12; // Add a pin for the buzzer // Variables for setting time and alarm manually int hours = 0; int minutes = 0; int alarmHours = 0; int alarmMinutes = 0; bool setMode = false; // Time setting mode flag bool alarmMode = false; // Alarm setting mode flag bool alarmEnabled = false; // Alarm enabled flag bool alarmActive = false; // Alarm active (sounding) flag bool alarmAcknowledged = false; // Alarm acknowledged (stopped) flag // Buzzer timing unsigned long previousMillis = 0; const long beepInterval = 500; // 500ms on, 500ms off bool buzzerState = false; // To track buzzer state (on/off) void setup() { Serial.begin(9600); Wire.begin(); hpdl.begin(); hpdl.clear(); // Set up buttons and buzzer pinMode(buttonHourPin, INPUT_PULLUP); pinMode(buttonMinutePin, INPUT_PULLUP); pinMode(buttonSetPin, INPUT_PULLUP); pinMode(buzzerPin, OUTPUT); digitalWrite(buzzerPin, LOW); // Make sure the buzzer is off initially // Display scrolling message at startup for (byte i = 0; i < (sizeof(msg) / sizeof(char)); i++) { for (byte j = 0; j < 16; j++) { hpdl.setCursor(j); if (i + j < (sizeof(msg) / sizeof(char))) { hpdl.print(msg[i + j]); } else { hpdl.print(" "); } } delay(200); } rtc.begin(); // Initialize time variables from the RTC DateTime now = rtc.now(); hours = now.hour(); minutes = now.minute(); } void loop() { // Get the current time from the RTC DateTime now = rtc.now(); // Check if the alarm is active (buzzer sounding) if (alarmActive) { unsigned long currentMillis = millis(); // Toggle the buzzer every 500ms (buzzerState controls on/off) if (currentMillis - previousMillis >= beepInterval) { previousMillis = currentMillis; // Save the last time the buzzer toggled buzzerState = !buzzerState; // Toggle the buzzer state digitalWrite(buzzerPin, buzzerState ? HIGH : LOW); // Turn the buzzer on or off } // Check if D11 is pressed to stop the alarm if (digitalRead(buttonSetPin) == LOW) { alarmActive = false; // Stop the alarm alarmAcknowledged = true; // Mark the alarm as acknowledged digitalWrite(buzzerPin, LOW); // Turn off the buzzer delay(500); // Debounce delay return; // Return to normal loop operation } } // Check if we are in time or alarm setting mode if (setMode) { // Display the manually set time sprintf(t, "%02d-%02d", hours, minutes); hpdl.clear(); hpdl.print(t); // Check if buttons to adjust hours or minutes are pressed if (digitalRead(buttonHourPin) == LOW) { hours = (hours + 1) % 24; // Increment hours and roll over after 23 delay(200); // Debouncing } if (digitalRead(buttonMinutePin) == LOW) { minutes = (minutes + 1) % 60; // Increment minutes and roll over after 59 delay(200); // Debouncing } } else if (alarmMode) { // Display the manually set alarm time sprintf(t, "A%02d-%02d", alarmHours, alarmMinutes); hpdl.clear(); hpdl.print(t); // Check if buttons to adjust alarm hours or minutes are pressed if (digitalRead(buttonHourPin) == LOW) { alarmHours = (alarmHours + 1) % 24; // Increment alarm hours and roll over after 23 delay(200); // Debouncing } if (digitalRead(buttonMinutePin) == LOW) { alarmMinutes = (alarmMinutes + 1) % 60; // Increment alarm minutes and roll over after 59 delay(200); // Debouncing } } else { // Normal operation: Display the current time from the RTC sprintf(t, "%02d-%02d-%02d", now.hour(), now.minute(), now.second()); hpdl.clear(); hpdl.print(t); // Check if the current time matches the alarm time and alarm is not acknowledged if (alarmEnabled && !alarmAcknowledged && now.hour() == alarmHours && now.minute() == alarmMinutes && now.second() == 0) { alarmActive = true; // Mark the alarm as active previousMillis = millis(); // Initialize the timer for buzzer beeping } // Reset the alarm acknowledgement flag if the minute has changed if (now.minute() != alarmMinutes) { alarmAcknowledged = false; // Allow the alarm to trigger again when the time matches next } } // Check if the Set button (buttonSetPin) is pressed to toggle between modes if (digitalRead(buttonSetPin) == LOW && !alarmActive) { if (setMode) { // Exiting time set mode, update the RTC with the manually set time rtc.adjust(DateTime(2024, 1, 1, hours, minutes, 0)); // Arbitrary date setMode = false; alarmMode = true; // Move to alarm setting mode } else if (alarmMode) { // Exiting alarm set mode, enable the alarm alarmEnabled = true; alarmMode = false; // Back to normal mode } else { // Enter time setting mode setMode = true; } delay(500); // Debouncing delay } }