Skip to content

RtcAlarmManager object

Michael Miller edited this page Jul 6, 2023 · 3 revisions

The RtcAlarmManager object provides a software RTC using the CPU timing to manage and activate user defined alarms. It does not require a RTC module but does require some trusted accurate source to initialize it and sync it for long term time keeping. Due to it using the CPU timing to keep a software "RTC" running, the timing is usually not very accurate over periods of more than a few hours so Sync'ing regularly from a trusted source is recommended.

Callbacks

void RtcAlarmCallback(uint8_t id, const RtcDateTime& alarm);

The user provided callback must follow this format, but the name of the method should be unique and defined by the author. This single callback will be called when an alarm is triggered.

id - the id of the alarm, returned when AddAlarm is called.
alarm - the RtcDateTime that the alarm was defined to trigger at. If it is a repeating alarm then it will be the calculated alarm time unique to this call.

void alarmCallback(uint8_t id, [[maybe_unused]] const RtcDateTime& alarm)
{
    switch (id)
    {
    case 0:
        Serial.println("ALARM: Its 5:30am!");
        break;
    case 1:
        Serial.println("ALARM: Its Saturday at 7:30am!");
        break;
    defualt:
        break;
    }
}

Constructors

RtcAlarmManager<RtcAlarmCallback V_CALLBACK>(uint8_t count)

Constructs an RtcAlarmManger using the given callback.

V_CALLBACK - the callback method.
count - the maximum number of Alarms that can be used at one time.

// foreward declare our alarm manager callback
void alarmCallback(uint8_t id, const RtcDateTime& alarm);
// global instance of the manager with three possible alarms
RtcAlarmManager<alarmCallback> Alarms(3);

Methods

int32_t Sync(const RtcDateTime& now)

Set and Sync the RtcAlarmManagers software RTC to the given date and time. This should be done at least once before any other member methods are called. It should also be called at a regular interval as the CPU timing is notorious for being inaccurate and time will drift if this isn't called.

now - the date and time to sync the software RTC to.
<return>, the difference in seconds between the new "now" and the previous date and time in the software RTC. This can be used to gauge how much drift happens with your specific CPU.

RtcDateTime Now()

<return>, the current date and time the software RTC has.

int8_t AddAlarm(const RtcDateTime& when, uint32_t period)

Add an alarm to the collection.

when - the date and time the first occurrence of the new Alarm should happened at.
period - the period of time the alarm should repeat at. The enum AlarmPeriod can be used to define the common periods, or any value above 60 representing seconds.
<return>, if positive it will be the id of the alarm just added. This is used in the callback and other methods that represents this alarm. Note that the first time this is successfully called, it will always return 0, then the second time will be 1. If you do not delete and create more alarms, you can assume the ids.
If negative an error has happened the value can be compared to the enum AlarmAddError to diagnose what went wrong.

    int8_t result;
    // add an alarm to sync time from rtc at a regular interval,
    // due to CPU timing variance, the Alarms time can get off over
    // time, so this alarm will trigger a resync every 20 minutes 
    result = Alarms.AddAlarm(now, 20 * c_MinuteAsSeconds); // every 20 minutes
    if (result < 0) {
        // an error happened
    }

    // add a daily alarm at 5:30am
    RtcDateTime working(now.Year(), now.Month(), now.Day(), 5, 30, 0);
    result = Alarms.AddAlarm(working, AlarmPeriod_Daily);
    if (result < 0) {
        // an error happened
    }

    // add a weekly alarm for Saturday at 7:30am
    working = RtcDateTime(now.Year(), now.Month(), now.Day(), 7, 30, 0);
    working = working.NextDayOfWeek(DayOfWeek_Saturday);
    result = Alarms.AddAlarm(working, AlarmPeriod_Weekly);
    if (result < 0) {
        // an error happened
    }

void RemoveAlarm(uint8_t id)

This will remove a previously added alarm. It will free its use for the next call to AddAlarm().

id - the id returned from AddAlarm() that will be removed.

bool IsAlarmActive(uint8_t id)

This will check if the given alarm is still active.

id - the id returned from AddAlarm()
<return>, true if the alarm either hasn't triggered yet or is a reoccurring alarm which will always be active.

void ProcessAlarms()

This will allow the software RTC to update its internal time and check if any alarms have passed. This should be called at regular intervals to provide the best response to alarms. The alarm callback is triggered and called within the context of this call. There is little need to call this faster than a few times a second, but it is a good practice to just place it the loop().

references:

enum AlarmPeriod

enum AlarmAddError