AceTime
0.8
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 Clock that uses the Arduino millis() function to advance the time returned to the user. More...
#include <SystemClock.h>
Public Member Functions | |
void | setup () |
Attempt to retrieve the time from the backupClock if it exists. More... | |
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 | forceSync () |
Force a sync with the mReferenceClock. 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 syncNow(). More... | |
![]() | |
virtual | ~Clock () |
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 | |
SystemClock (const SystemClock &)=delete | |
SystemClock & | operator= (const SystemClock &)=delete |
SystemClock (Clock *referenceClock, Clock *backupClock) | |
Constructor. More... | |
virtual unsigned long | clockMillis () const |
Return the Arduino millis(). More... | |
void | keepAlive () |
Call this (or getNow() every 65.535 seconds or faster to keep the internal counter in sync with millis(). | |
void | backupNow (acetime_t nowSeconds) |
Write the nowSeconds to the backupClock (which can be an RTC that has non-volatile memory, or simply flash memory which emulates a backupClock. | |
void | syncNow (acetime_t epochSeconds) |
Similar to setNow() except that backupNow() is called only if the backupClock is different from the referenceClock. More... | |
Protected Attributes | |
Clock *const | mReferenceClock |
Clock *const | mBackupClock |
acetime_t | mEpochSeconds = kInvalidSeconds |
acetime_t | mLastSyncTime = kInvalidSeconds |
uint16_t | mPrevMillis = 0 |
bool | mIsInit = false |
Friends | |
class | ::SystemClockLoopTest |
class | ::SystemClockCoroutineTest |
class | ::SystemClockLoopTest_syncNow |
Additional Inherited Members | |
![]() | |
static const acetime_t | kInvalidSeconds = LocalTime::kInvalidSeconds |
A Clock that uses the Arduino millis() function to advance the time returned to the user.
It has 2 major features:
1) The built-in millis() is not accurate, so this class allows a periodic sync using the (presumably) more accurate referenceClock. 2) The current time can be periodically backed up into the backupClock which is expected to be an RTC chip that continues to keep time during power loss. Upon (re)start, SystemClock::setup() reads back the time from the backupClock if it exists.
There are 2 maintenance tasks which this class must perform peridicallly:
1) 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. 2) The current time can be synchronized to the referenceClock peridically. Some reference clocks can take hundreds or thousands of milliseconds to return, so it's important that the non-block methods of Clock are used to synchronize to the reference clock.
Two subclasses of SystemClock expose 2 different ways of performing these maintenance tasks.
1) Call SystemClockCoroutine::runCoroutine using the framework of the AceRoutine library in the global loop() function. 2) Call the SystemClockLoop::loop() method from the global loop() function.
Definition at line 53 of file SystemClock.h.
|
inlineexplicitprotected |
Constructor.
referenceClock | The authoritative source of the time. If this is null, object relies just on clockMillis() and the user to set the proper time using setNow(). |
backupClock | An RTC chip which continues to keep time even when power is lost. Can be null. |
Definition at line 116 of file SystemClock.h.
|
inlineprotectedvirtual |
Return the Arduino millis().
Override for unit testing. Named 'clockMillis()' to avoid conflict with Coroutine::millis().
Definition at line 126 of file SystemClock.h.
|
inline |
Force a sync with the mReferenceClock.
Definition at line 83 of file SystemClock.h.
|
inline |
Return the time (seconds since Epoch) of the last valid sync() call.
Returns kInvalidSeconds if never synced.
Definition at line 92 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.
This is a blocking call. Some clocks (e.g. NTP client) this may take many seconds. On those clocks, use the asynchronous methods (sendRequest(), isResponseReady(), and readResponse()) instead.
Implements ace_time::clock::Clock.
Definition at line 63 of file SystemClock.h.
|
inline |
Return true if initialized by setNow() or syncNow().
Definition at line 97 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. Some clocks do not support this feature, for example, NTP or GPS clocks and this method will be a no-op.
Reimplemented from ace_time::clock::Clock.
Definition at line 73 of file SystemClock.h.
|
inline |
Attempt to retrieve the time from the backupClock if it exists.
Definition at line 57 of file SystemClock.h.
|
inlineprotected |
Similar to setNow() except that backupNow() is called only if the backupClock is different from the referenceClock.
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 syncNow() algorithm which shifts only a few milliseconds per iteration, and which guarantees that the clock never goes backwards in time.
Definition at line 156 of file SystemClock.h.