AceTime
0.5.2
Date and time classes for Arduino that support timezones from the TZ Database, and a system clock that can synchronize 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 <SystemClock.h>
Public Member Functions | |
SystemClock (TimeProvider *syncTimeProvider, TimeKeeper *backupTimeKeeper) | |
void | setup () |
void | keepAlive () |
Call this (or getNow() every 65.535 seconds or faster to keep the internal counter in sync with millis(). | |
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 | SystemClockSyncCoroutine |
class | SystemClockSyncLoop |
Additional Inherited Members | |
![]() | |
static const acetime_t | kInvalidSeconds = LocalTime::kInvalidSeconds |
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, keepAlive() must be called more frequently than every 65.536 seconds. The easiest way to do this is to call it from the global loop() method.
There are 2 ways to perform syncing from the syncTimeProvider:
1) Create an instance of SystemClockSyncCoroutine and register it with the CoroutineSchedule so that it runs periodically. The SystemClockSyncCoroutine::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 SystemClockSyncLoop::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 50 of file SystemClock.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 60 of file SystemClock.h.
|
inline |
Return the time (seconds since Epoch) of the last valid sync() call.
Returns 0 if never synced.
Definition at line 128 of file SystemClock.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::clock::TimeProvider.
Definition at line 80 of file SystemClock.h.
|
inline |
Return true if initialized by setNow() or sync().
Definition at line 133 of file SystemClock.h.
|
inlineprotectedvirtual |
Return the Arduino millis().
Override for unit testing.
Definition at line 137 of file SystemClock.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::clock::TimeKeeper.
Definition at line 90 of file SystemClock.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 110 of file SystemClock.h.