diff --git a/libraries/RTC/examples/AlarmClock/AlarmClock.pde b/libraries/RTC/examples/AlarmClock/AlarmClock.pde index c3bed0a4..fca3676d 100644 --- a/libraries/RTC/examples/AlarmClock/AlarmClock.pde +++ b/libraries/RTC/examples/AlarmClock/AlarmClock.pde @@ -50,6 +50,7 @@ // Offsets of settings in the realtime clock's NVRAM. #define SETTING_24HOUR 0 // 0: 12 hour, 1: 24 hour #define SETTING_ALARM_TIMEOUT 1 // Timeout in minutes for the alarm +#define SETTING_SNOOZE 2 // 0: no snooze, 1: snooze // Initialize the LCD FreetronicsLCD lcd; @@ -75,6 +76,7 @@ SetAlarm alarm2(mainForm, "Alarm 2", 1); SetAlarm alarm3(mainForm, "Alarm 3", 2); SetAlarm alarm4(mainForm, "Alarm 4", 3); IntField alarmTimeout(mainForm, "Alarm timeout", 2, 10, 1, 2, " minutes"); +BoolField snooze(mainForm, "Snooze alarm", "On", "Off", false); SetTime setTime(mainForm, "Set current time"); SetDate setDate(mainForm, "Set current date"); BoolField hourMode(mainForm, "Hour display", "24 hour clock", "12 hour clock", false); @@ -112,6 +114,7 @@ void setup() { frontScreen.set24HourMode(is24HourClock); alarmTimeout.setValue(rtc.readByte(SETTING_ALARM_TIMEOUT)); alarmMelody.setLoopDuration(60000UL * alarmTimeout.value()); + snooze.setValue(rtc.readByte(SETTING_SNOOZE) != 0); // Set the initial time and date and find the next alarm to be triggered. RTCTime time; @@ -171,6 +174,8 @@ void loop() { } else if (alarmTimeout.isCurrent()) { rtc.writeByte(SETTING_ALARM_TIMEOUT, (byte)alarmTimeout.value()); alarmMelody.setLoopDuration(60000UL * alarmTimeout.value()); + } else if (snooze.isCurrent()) { + rtc.writeByte(SETTING_SNOOZE, (byte)snooze.value()); } prevHour = 24; // Force an update of the main screen. findNextAlarm(); // Update the time of the next alarm event. @@ -191,12 +196,28 @@ 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) + if (mins1 <= mins2) return mins2 - mins1; else return 24 * 60 + mins2 - mins1; } +// Add 9 minutes to an alarm to get its snooze time. +RTCAlarm adjustForSnooze(const RTCAlarm &alarm) +{ + if (!alarm.flags) + return alarm; + RTCAlarm snooze; + snooze.hour = alarm.hour; + snooze.minute = alarm.minute + 9; + if (snooze.minute >= 60) { + snooze.hour = (snooze.hour + 1) % 24; + snooze.minute %= 60; + } + snooze.flags = alarm.flags; + return snooze; +} + // Find the time of the next alarm to be triggered. void findNextAlarm() { @@ -215,9 +236,22 @@ void findNextAlarm() findNextAlarm(currentTime, alarm2.alarmValue()); findNextAlarm(currentTime, alarm3.alarmValue()); findNextAlarm(currentTime, alarm4.alarmValue()); + if (snooze.value()) { + findNextAlarm(currentTime, adjustForSnooze(alarm1.alarmValue())); + findNextAlarm(currentTime, adjustForSnooze(alarm2.alarmValue())); + findNextAlarm(currentTime, adjustForSnooze(alarm3.alarmValue())); + findNextAlarm(currentTime, adjustForSnooze(alarm4.alarmValue())); + } // Set the alarm indicator on the front screen. - frontScreen.setAlarmActive(nextAlarm.flags != 0); + if (nextAlarm.flags) { + if (snooze.value()) + frontScreen.setAlarmMode(FrontScreenField::Snooze); + else + frontScreen.setAlarmMode(FrontScreenField::AlarmOn); + } else { + frontScreen.setAlarmMode(FrontScreenField::AlarmOff); + } } void findNextAlarm(const RTCTime ¤tTime, const RTCAlarm &alarm) { diff --git a/libraries/RTC/examples/AlarmClock/FrontScreen.cpp b/libraries/RTC/examples/AlarmClock/FrontScreen.cpp index d4f7712d..d68836db 100644 --- a/libraries/RTC/examples/AlarmClock/FrontScreen.cpp +++ b/libraries/RTC/examples/AlarmClock/FrontScreen.cpp @@ -40,7 +40,7 @@ FrontScreenField::FrontScreenField(Form &form) , _voltageTrunc(36) , _batteryBars(IND_BATTERY_FULL) #endif - , _alarmActive(false) + , _alarmMode(FrontScreenField::AlarmOff) , _hourMode(false) { _date.day = 1; @@ -124,10 +124,45 @@ void FrontScreenField::setVoltage(int voltage) #endif -void FrontScreenField::setAlarmActive(bool active) +static uint8_t alarmActive1[8] = { + B00100, + B01001, + B10010, + B00000, + B10010, + B01001, + B00100, + B00000 +}; +static uint8_t alarmActive2[8] = { + B11000, + B10100, + B10011, + B10011, + B10011, + B10100, + B11000, + B00000 +}; +static uint8_t alarmSnooze[8] = { + B11110, + B00100, + B01000, + B11110, + B00000, + B00000, + B00000, + B00000 +}; + +void FrontScreenField::setAlarmMode(AlarmMode mode) { - if (_alarmActive != active) { - _alarmActive = active; + if (_alarmMode != mode) { + _alarmMode = mode; + if (mode == Snooze) + lcd()->createChar(IND_ALARM_ACTIVE1, alarmSnooze); + else + lcd()->createChar(IND_ALARM_ACTIVE1, alarmActive1); if (isCurrent()) updateAlarm(); } @@ -211,8 +246,8 @@ void FrontScreenField::updateAlarm() #else lcd()->setCursor(14, 0); #endif - lcd()->write(_alarmActive ? IND_ALARM_ACTIVE1 : ' '); - lcd()->write(_alarmActive ? IND_ALARM_ACTIVE2 : ' '); + lcd()->write(_alarmMode != AlarmOff ? IND_ALARM_ACTIVE1 : ' '); + lcd()->write(_alarmMode != AlarmOff ? IND_ALARM_ACTIVE2 : ' '); } #ifdef USE_VOLTAGE_MONITOR @@ -277,26 +312,6 @@ static uint8_t batteryFull[8] = { B00000 }; #endif -static uint8_t alarmActive1[8] = { - B00100, - B01001, - B10010, - B00000, - B10010, - B01001, - B00100, - B00000 -}; -static uint8_t alarmActive2[8] = { - B11000, - B10100, - B10011, - B10011, - B10011, - B10100, - B11000, - B00000 -}; void FrontScreenField::registerIndicators() { diff --git a/libraries/RTC/examples/AlarmClock/FrontScreen.h b/libraries/RTC/examples/AlarmClock/FrontScreen.h index b6cd4d91..7ec8c39b 100644 --- a/libraries/RTC/examples/AlarmClock/FrontScreen.h +++ b/libraries/RTC/examples/AlarmClock/FrontScreen.h @@ -47,8 +47,15 @@ public: void setVoltage(int voltage); #endif - bool isAlarmActive() const { return _alarmActive; } - void setAlarmActive(bool active); + enum AlarmMode + { + AlarmOff, + AlarmOn, + Snooze + }; + + AlarmMode isAlarmMode() const { return _alarmMode; } + void setAlarmMode(AlarmMode mode); bool is24HourMode() const { return _hourMode; } void set24HourMode(bool value); @@ -61,7 +68,7 @@ private: int _voltageTrunc; int _batteryBars; #endif - bool _alarmActive; + AlarmMode _alarmMode; bool _hourMode; void updateDate();