AceTimeClock
1.3.0
Clock classes for Arduino that can synchronize from an NTP server or an RTC chip
|
A subclass of SystemClock that sync with its mReferenceClock using the non-blocking Clock API of the referenceClock. More...
#include <SystemClockLoop.h>
Public Member Functions | |
SystemClockLoopTemplate (Clock *referenceClock, Clock *backupClock, uint16_t syncPeriodSeconds=3600, uint16_t initialSyncPeriodSeconds=5, uint16_t requestTimeoutMillis=1000, ace_common::TimingStats *timingStats=nullptr) | |
Constructor. More... | |
void | loop () |
Make a request to the referenceClock every syncPeriodSeconds seconds. More... | |
![]() | |
void | setup () |
Attempt to retrieve the time from the backupClock if it exists. | |
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 () |
Manually force a sync with the referenceClock if it exists. More... | |
acetime_t | getLastSyncTime () const |
Return the time (seconds since Epoch) of the last successful syncNow() call. More... | |
uint8_t | getSyncStatusCode () const |
Get sync status code. | |
int32_t | getSecondsSinceSyncAttempt () const |
Return the number of seconds since the previous sync attempt, successful or not. More... | |
int32_t | getSecondsToSyncAttempt () const |
Return the number of seconds until the next syncNow() attempt. More... | |
int16_t | getClockSkew () const |
Difference between this clock compared to reference at last sync. More... | |
bool | isInit () const |
Return true if initialized by setNow() or syncNow(). | |
![]() | |
Clock ()=default | |
Default constructor. | |
~Clock ()=default | |
We deliberately avoid using a virtual destructor. More... | |
virtual void | sendRequest () const |
Send a time request asynchronously. | |
virtual bool | isResponseReady () const |
Return true if a response is ready. | |
virtual acetime_t | readResponse () const |
Returns number of seconds since AceTime epoch (2000-01-01). More... | |
Protected Member Functions | |
SystemClockLoopTemplate () | |
Empty constructor used for testing. | |
SystemClockLoopTemplate (const SystemClockLoopTemplate &)=delete | |
SystemClockLoopTemplate & | operator= (const SystemClockLoopTemplate &)=delete |
![]() | |
SystemClockTemplate (const SystemClockTemplate &)=delete | |
SystemClockTemplate (Clock *referenceClock, Clock *backupClock) | |
Constructor. More... | |
SystemClockTemplate () | |
Empty constructor primarily for tests. More... | |
SystemClockTemplate & | operator= (const SystemClockTemplate &)=delete |
void | initSystemClock (Clock *referenceClock, Clock *backupClock) |
Same as constructor but allows delayed initialization, e.g. More... | |
Clock * | getReferenceClock () const |
Get referenceClock. | |
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(). More... | |
void | backupNow (acetime_t nowSeconds) |
Write the nowSeconds to the backupClock (which can be an RTC that has non-volatile memory). More... | |
void | syncNow (acetime_t epochSeconds) |
Set the current mEpochSeconds to the given epochSeconds. More... | |
void | setNextSyncAttemptMillis (uint32_t ms) |
Set the millis to next sync attempt. | |
void | setPrevSyncAttemptMillis (uint32_t ms) |
Set the millis of prev sync attempt. | |
void | setSyncStatusCode (uint8_t code) |
Set the status code of most recent sync attempt. | |
Additional Inherited Members | |
![]() | |
static const uint8_t | kSyncStatusOk |
Sync was successful. | |
static const uint8_t | kSyncStatusError |
Sync request failed. | |
static const uint8_t | kSyncStatusTimedOut |
Sync request timed out. | |
static const uint8_t | kSyncStatusUnknown |
Sync was never done. | |
![]() | |
static const acetime_t | kInvalidSeconds = LocalTime::kInvalidSeconds |
Error value returned by getNow() and other methods when this object is not yet initialized. | |
A subclass of SystemClock that sync with its mReferenceClock using the non-blocking Clock API of the referenceClock.
This is helpful when the referenceClock issues a network request to an NTP server. The SystemClockLoop::loop() function should be called from the global loop() function.
Syncing occurs at initialSyncPeriodSeconds interval, until the first successful sync, then subsequent syncing occurs at syncPeriodSeconds interval. Initial syncing implements an exponential backoff when the sync request fails, increasing from initialSyncPeriodSeconds to until a maximum of syncPeriodSeconds.
Initially, SystemClockLoop
used the blocking API of Clock, and SystemClockCoroutine
used the non-blocking API. That meant that SystemClockCoroutine
was better suited for referenceClocks that could block for a long time (e.g. NtpClock). at some point however, SystemClockLoop
was converted to use the non-blocking API as well, so the two classes are now functionally equivalent. I keep around the SystemClockCoroutine class because I find the code easier to understand. But for the end-users of the library, they are equivalent.
T_SCCI | the SystemClock ClockInterface |
Definition at line 48 of file SystemClockLoop.h.
|
inlineexplicit |
Constructor.
referenceClock | The authoritative source of the time. If this is null, the 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. |
syncPeriodSeconds | seconds between normal sync attempts (default 3600) |
initialSyncPeriodSeconds | seconds between sync attempts when the systemClock is not initialized (default 5), exponentially increasing (2X) at each attempt until syncPeriodSeconds is reached |
requestTimeoutMillis | number of milliseconds before the request to referenceClock times out |
timingStats | internal statistics (nullable) |
Definition at line 67 of file SystemClockLoop.h.
|
inline |
Make a request to the referenceClock every syncPeriodSeconds seconds.
Wait for the request, then set the SystemClock (the parent class) to the time returned by the referenceClock. If the referenceClock returns an error, implement a retry algorithm with an exponential backoff, until a maximum of syncPeriodSeconds interval is reached.
This method should be called from the global loop() method.
Definition at line 89 of file SystemClockLoop.h.