mirror of
https://github.com/taigrr/arduinolibs
synced 2025-01-18 04:33:12 -08:00
Add a snooze feature to the alarm clock
This commit is contained in:
parent
dce1ede576
commit
a872972c9d
@ -50,6 +50,7 @@
|
|||||||
// Offsets of settings in the realtime clock's NVRAM.
|
// Offsets of settings in the realtime clock's NVRAM.
|
||||||
#define SETTING_24HOUR 0 // 0: 12 hour, 1: 24 hour
|
#define SETTING_24HOUR 0 // 0: 12 hour, 1: 24 hour
|
||||||
#define SETTING_ALARM_TIMEOUT 1 // Timeout in minutes for the alarm
|
#define SETTING_ALARM_TIMEOUT 1 // Timeout in minutes for the alarm
|
||||||
|
#define SETTING_SNOOZE 2 // 0: no snooze, 1: snooze
|
||||||
|
|
||||||
// Initialize the LCD
|
// Initialize the LCD
|
||||||
FreetronicsLCD lcd;
|
FreetronicsLCD lcd;
|
||||||
@ -75,6 +76,7 @@ SetAlarm alarm2(mainForm, "Alarm 2", 1);
|
|||||||
SetAlarm alarm3(mainForm, "Alarm 3", 2);
|
SetAlarm alarm3(mainForm, "Alarm 3", 2);
|
||||||
SetAlarm alarm4(mainForm, "Alarm 4", 3);
|
SetAlarm alarm4(mainForm, "Alarm 4", 3);
|
||||||
IntField alarmTimeout(mainForm, "Alarm timeout", 2, 10, 1, 2, " minutes");
|
IntField alarmTimeout(mainForm, "Alarm timeout", 2, 10, 1, 2, " minutes");
|
||||||
|
BoolField snooze(mainForm, "Snooze alarm", "On", "Off", false);
|
||||||
SetTime setTime(mainForm, "Set current time");
|
SetTime setTime(mainForm, "Set current time");
|
||||||
SetDate setDate(mainForm, "Set current date");
|
SetDate setDate(mainForm, "Set current date");
|
||||||
BoolField hourMode(mainForm, "Hour display", "24 hour clock", "12 hour clock", false);
|
BoolField hourMode(mainForm, "Hour display", "24 hour clock", "12 hour clock", false);
|
||||||
@ -112,6 +114,7 @@ void setup() {
|
|||||||
frontScreen.set24HourMode(is24HourClock);
|
frontScreen.set24HourMode(is24HourClock);
|
||||||
alarmTimeout.setValue(rtc.readByte(SETTING_ALARM_TIMEOUT));
|
alarmTimeout.setValue(rtc.readByte(SETTING_ALARM_TIMEOUT));
|
||||||
alarmMelody.setLoopDuration(60000UL * alarmTimeout.value());
|
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.
|
// Set the initial time and date and find the next alarm to be triggered.
|
||||||
RTCTime time;
|
RTCTime time;
|
||||||
@ -171,6 +174,8 @@ void loop() {
|
|||||||
} else if (alarmTimeout.isCurrent()) {
|
} else if (alarmTimeout.isCurrent()) {
|
||||||
rtc.writeByte(SETTING_ALARM_TIMEOUT, (byte)alarmTimeout.value());
|
rtc.writeByte(SETTING_ALARM_TIMEOUT, (byte)alarmTimeout.value());
|
||||||
alarmMelody.setLoopDuration(60000UL * 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.
|
prevHour = 24; // Force an update of the main screen.
|
||||||
findNextAlarm(); // Update the time of the next alarm event.
|
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 mins1 = currentTime.hour * 60 + currentTime.minute;
|
||||||
int mins2 = alarm.hour * 60 + alarm.minute;
|
int mins2 = alarm.hour * 60 + alarm.minute;
|
||||||
if (mins1 < mins2)
|
if (mins1 <= mins2)
|
||||||
return mins2 - mins1;
|
return mins2 - mins1;
|
||||||
else
|
else
|
||||||
return 24 * 60 + mins2 - mins1;
|
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.
|
// Find the time of the next alarm to be triggered.
|
||||||
void findNextAlarm()
|
void findNextAlarm()
|
||||||
{
|
{
|
||||||
@ -215,9 +236,22 @@ void findNextAlarm()
|
|||||||
findNextAlarm(currentTime, alarm2.alarmValue());
|
findNextAlarm(currentTime, alarm2.alarmValue());
|
||||||
findNextAlarm(currentTime, alarm3.alarmValue());
|
findNextAlarm(currentTime, alarm3.alarmValue());
|
||||||
findNextAlarm(currentTime, alarm4.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.
|
// 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)
|
void findNextAlarm(const RTCTime ¤tTime, const RTCAlarm &alarm)
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,7 @@ FrontScreenField::FrontScreenField(Form &form)
|
|||||||
, _voltageTrunc(36)
|
, _voltageTrunc(36)
|
||||||
, _batteryBars(IND_BATTERY_FULL)
|
, _batteryBars(IND_BATTERY_FULL)
|
||||||
#endif
|
#endif
|
||||||
, _alarmActive(false)
|
, _alarmMode(FrontScreenField::AlarmOff)
|
||||||
, _hourMode(false)
|
, _hourMode(false)
|
||||||
{
|
{
|
||||||
_date.day = 1;
|
_date.day = 1;
|
||||||
@ -124,10 +124,45 @@ void FrontScreenField::setVoltage(int voltage)
|
|||||||
|
|
||||||
#endif
|
#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) {
|
if (_alarmMode != mode) {
|
||||||
_alarmActive = active;
|
_alarmMode = mode;
|
||||||
|
if (mode == Snooze)
|
||||||
|
lcd()->createChar(IND_ALARM_ACTIVE1, alarmSnooze);
|
||||||
|
else
|
||||||
|
lcd()->createChar(IND_ALARM_ACTIVE1, alarmActive1);
|
||||||
if (isCurrent())
|
if (isCurrent())
|
||||||
updateAlarm();
|
updateAlarm();
|
||||||
}
|
}
|
||||||
@ -211,8 +246,8 @@ void FrontScreenField::updateAlarm()
|
|||||||
#else
|
#else
|
||||||
lcd()->setCursor(14, 0);
|
lcd()->setCursor(14, 0);
|
||||||
#endif
|
#endif
|
||||||
lcd()->write(_alarmActive ? IND_ALARM_ACTIVE1 : ' ');
|
lcd()->write(_alarmMode != AlarmOff ? IND_ALARM_ACTIVE1 : ' ');
|
||||||
lcd()->write(_alarmActive ? IND_ALARM_ACTIVE2 : ' ');
|
lcd()->write(_alarmMode != AlarmOff ? IND_ALARM_ACTIVE2 : ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_VOLTAGE_MONITOR
|
#ifdef USE_VOLTAGE_MONITOR
|
||||||
@ -277,26 +312,6 @@ static uint8_t batteryFull[8] = {
|
|||||||
B00000
|
B00000
|
||||||
};
|
};
|
||||||
#endif
|
#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()
|
void FrontScreenField::registerIndicators()
|
||||||
{
|
{
|
||||||
|
@ -47,8 +47,15 @@ public:
|
|||||||
void setVoltage(int voltage);
|
void setVoltage(int voltage);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool isAlarmActive() const { return _alarmActive; }
|
enum AlarmMode
|
||||||
void setAlarmActive(bool active);
|
{
|
||||||
|
AlarmOff,
|
||||||
|
AlarmOn,
|
||||||
|
Snooze
|
||||||
|
};
|
||||||
|
|
||||||
|
AlarmMode isAlarmMode() const { return _alarmMode; }
|
||||||
|
void setAlarmMode(AlarmMode mode);
|
||||||
|
|
||||||
bool is24HourMode() const { return _hourMode; }
|
bool is24HourMode() const { return _hourMode; }
|
||||||
void set24HourMode(bool value);
|
void set24HourMode(bool value);
|
||||||
@ -61,7 +68,7 @@ private:
|
|||||||
int _voltageTrunc;
|
int _voltageTrunc;
|
||||||
int _batteryBars;
|
int _batteryBars;
|
||||||
#endif
|
#endif
|
||||||
bool _alarmActive;
|
AlarmMode _alarmMode;
|
||||||
bool _hourMode;
|
bool _hourMode;
|
||||||
|
|
||||||
void updateDate();
|
void updateDate();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user