From 6e61524a0f2d39ce7ad5d2fcbfe8dc93b4e04ac3 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Wed, 23 May 2012 10:13:11 +1000 Subject: [PATCH] Sound the alarm when the specific time is reached --- .../RTC/examples/AlarmClock/AlarmClock.pde | 67 +++++++++++++++++++ .../examples/AlarmClock/LowPowerMelody.cpp | 5 ++ 2 files changed, 72 insertions(+) diff --git a/libraries/RTC/examples/AlarmClock/AlarmClock.pde b/libraries/RTC/examples/AlarmClock/AlarmClock.pde index 658b5e06..cfc4c4ec 100644 --- a/libraries/RTC/examples/AlarmClock/AlarmClock.pde +++ b/libraries/RTC/examples/AlarmClock/AlarmClock.pde @@ -63,6 +63,7 @@ LowPowerMelody alarmMelody(BUZZER); uint8_t prevHour = 24; bool is24HourClock = false; +RTCAlarm nextAlarm; // Create the main form and its fields. Form mainForm(lcd); @@ -106,6 +107,15 @@ void setup() { hourMode.setValue(is24HourClock); frontScreen.set24HourMode(is24HourClock); + // Set the initial time and date and find the next alarm to be triggered. + RTCTime time; + RTCDate date; + rtc.readTime(&time); + rtc.readDate(&date); + frontScreen.setTime(time); + frontScreen.setDate(date); + findNextAlarm(); + // Show the main form for the first time. mainForm.show(); } @@ -133,6 +143,14 @@ void loop() { if (voltage > 500) voltage = 500; frontScreen.setVoltage(voltage); + + // Trigger an alarm if necessary. + if (time.second == 0 && nextAlarm.flags && !alarmMelody.isPlaying()) { + if (time.hour == nextAlarm.hour && time.minute == nextAlarm.minute) { + findNextAlarm(); + alarmMelody.play(); + } + } } // Dispatch button events to the main form. @@ -144,6 +162,7 @@ void loop() { rtc.writeByte(SETTING_24HOUR, (byte)is24HourClock); } prevHour = 24; // Force an update of the main screen. + findNextAlarm(); // Update the time of the next alarm event. } // If the alarm is playing and a button was pressed, then turn it off. @@ -156,3 +175,51 @@ void loop() { sleepFor(SLEEP_15_MS); } } + +inline int timeToAlarm(const RTCTime ¤tTime, const RTCAlarm &alarm) +{ + int mins1 = currentTime.hour * 60 + currentTime.minute; + int mins2 = alarm.hour * 60 + alarm.minute; + if (mins1 < mins2) + return mins2 - mins1; + else + return 24 * 60 + mins2 - mins1; +} + +// Find the time of the next alarm to be triggered. +void findNextAlarm() +{ + // Get the current time plus 1 minute, to avoid repeating the same alarm. + RTCTime currentTime = frontScreen.time(); + if (++(currentTime.minute) >= 60) { + currentTime.minute = 0; + currentTime.hour = (currentTime.hour + 1) % 24; + } + + // Process each of the alarms to find the closest. + nextAlarm.hour = 0; + nextAlarm.minute = 0; + nextAlarm.flags = 0; + findNextAlarm(currentTime, alarm1.alarmValue()); + findNextAlarm(currentTime, alarm2.alarmValue()); + findNextAlarm(currentTime, alarm3.alarmValue()); + findNextAlarm(currentTime, alarm4.alarmValue()); + + // Set the alarm indicator on the front screen. + frontScreen.setAlarmActive(nextAlarm.flags != 0); +} +void findNextAlarm(const RTCTime ¤tTime, const RTCAlarm &alarm) +{ + if (!alarm.flags) + return; // Alarm is disabled. + if (!nextAlarm.flags) { + // First valid alarm. + nextAlarm = alarm; + return; + } + if (timeToAlarm(currentTime, nextAlarm) > + timeToAlarm(currentTime, alarm)) { + // Found an alarm that is closer in time. + nextAlarm = alarm; + } +} diff --git a/libraries/RTC/examples/AlarmClock/LowPowerMelody.cpp b/libraries/RTC/examples/AlarmClock/LowPowerMelody.cpp index 0548af97..e90d90bc 100644 --- a/libraries/RTC/examples/AlarmClock/LowPowerMelody.cpp +++ b/libraries/RTC/examples/AlarmClock/LowPowerMelody.cpp @@ -23,6 +23,8 @@ #include "LowPowerMelody.h" #include +extern void findNextAlarm(); + void LowPowerMelody::play() { // Turn on Timer2. @@ -39,4 +41,7 @@ void LowPowerMelody::stop() // Turn off Timer2. power_timer2_disable(); + + // Find the next alarm to be triggered. + findNextAlarm(); }