AceTime
0.1
Date and time classes for Arduino that supports the TZ DAtabase, and a system clock synchronized from an NTP server or an RTC chip.
|
A TimeKeeper that uses the Arduino millis() function to advance the time returned to the user. More...
#include <SystemTimeKeeper.h>
Public Member Functions | |
SystemTimeKeeper (TimeProvider *syncTimeProvider, TimeKeeper *backupTimeKeeper) | |
void | setup () |
acetime_t | getNow () const override |
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z). More... | |
void | setNow (acetime_t epochSeconds) override |
Set the time to the indicated seconds. More... | |
void | sync (acetime_t epochSeconds) |
Similar to setNow() except that backupNow() is called only if the backupTimeKeeper is different from the syncTimeKeeper. More... | |
acetime_t | getLastSyncTime () const |
Return the time (seconds since Epoch) of the last valid sync() call. More... | |
bool | isInit () const |
Return true if initialized by setNow() or sync(). More... | |
![]() | |
virtual | ~TimeProvider () |
Virtual destructor. More... | |
virtual void | sendRequest () const |
Send a time request asynchronously. More... | |
virtual bool | isResponseReady () const |
Return true if a response is ready. More... | |
virtual acetime_t | readResponse () const |
Returns number of seconds since AceTime epoch (2000-01-01). More... | |
Protected Member Functions | |
virtual unsigned long | millis () const |
Return the Arduino millis(). More... | |
Friends | |
class | SystemTimeSyncCoroutine |
class | SystemTimeSyncLoop |
Additional Inherited Members | |
![]() | |
static const acetime_t | kInvalidSeconds = INT32_MAX |
A TimeKeeper that uses the Arduino millis() function to advance the time returned to the user.
The real time is returned as the number of seconds since the AceTime epoch of 2000-01-01T00:00:00Z.
The built-in millis() is not accurate, so this class allows a periodic sync using the (presumably) more accurate syncTimeProvider. The current time can be periodically backed up into the backupTimeKeeper which is expected to be an RTC chip that continues to keep time during power loss.
The value of the previous system time millis() is stored internally as a uint16_t. That has 2 advantages: 1) it saves memory, 2) the upper bound of the execution time of getNow() limited to 65 iterations. The disadvantage is the that internal counter will rollover within 65.535 milliseconds. To prevent that, getNow() or setNow() must be called more frequently than every 65.536 seconds. This can be satisfied by using the SystemTimeHeartbeatCoroutine or SystemTimeHeartbeatLoop helper classes.
There are 2 ways to perform syncing from the syncTimeProvider:
1) Create an instance of SystemTimeSyncCoroutine and register it with the CoroutineSchedule so that it runs periodically. The SystemTimeSyncCoroutine::runCoroutine() method uses the non-blocking sendRequest(), isResponseReady() and readResponse() methods of TimeProvider to retrieve the current time. Some time providers (e.g. NtpTimeProvider) can take 100s of milliseconds to return, so using the coroutine infrastructure allows other coroutines to continue executing.
2) Call the SystemTimeSyncLoop::loop() method from the global loop() function. This method uses the blocking TimeProvider::getNow() method which can take O(100) milliseconds for something like NtpTimeProvider.
Definition at line 45 of file SystemTimeKeeper.h.
|
inlineexplicit |
syncTimeProvider | The authoritative source of the time. Can be null in which case the objec relies just on millis() and the user to set the proper time using setNow(). |
backupTimeKeeper | An RTC chip which continues to keep time even when power is lost. Can be null. |
Definition at line 55 of file SystemTimeKeeper.h.
|
inline |
Return the time (seconds since Epoch) of the last valid sync() call.
Returns 0 if never synced.
Definition at line 114 of file SystemTimeKeeper.h.
|
inlineoverridevirtual |
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z).
Returns kInvalidSeconds if an error has occured.
Implements ace_time::provider::TimeProvider.
Definition at line 67 of file SystemTimeKeeper.h.
|
inline |
Return true if initialized by setNow() or sync().
Definition at line 119 of file SystemTimeKeeper.h.
|
inlineprotectedvirtual |
Return the Arduino millis().
Override for unit testing.
Definition at line 123 of file SystemTimeKeeper.h.
|
inlineoverridevirtual |
Set the time to the indicated seconds.
Calling with a value of kInvalidSeconds indicates an error condition, so the method should do nothing.
Implements ace_time::provider::TimeKeeper.
Definition at line 77 of file SystemTimeKeeper.h.
|
inline |
Similar to setNow() except that backupNow() is called only if the backupTimeKeeper is different from the syncTimeKeeper.
This prevents us from retrieving the time from the RTC, then saving it right back again, with a drift each time it is saved back.
TODO: Implement a more graceful sync() algorithm which shifts only a few milliseconds per iteration, and which guarantees that the clock never goes backwards in time.
Definition at line 96 of file SystemTimeKeeper.h.