AceTime  1.7.1
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.
Public Member Functions | Protected Member Functions | Friends | List of all members
ace_time::clock::SystemClockLoop Class Reference

A subclass of SystemClock that sync with its mReferenceClock using the non-blocking Clock API of the referenceClock. More...

#include <SystemClockLoop.h>

Inheritance diagram for ace_time::clock::SystemClockLoop:
Inheritance graph
[legend]
Collaboration diagram for ace_time::clock::SystemClockLoop:
Collaboration graph
[legend]

Public Member Functions

 SystemClockLoop (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...
 
- Public Member Functions inherited from ace_time::clock::SystemClock
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().
 
- Public Member Functions inherited from ace_time::clock::Clock
 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

 SystemClockLoop ()
 Empty constructor used for testing.
 
 SystemClockLoop (const SystemClockLoop &)=delete
 
SystemClockLoopoperator= (const SystemClockLoop &)=delete
 
- Protected Member Functions inherited from ace_time::clock::SystemClock
 SystemClock (const SystemClock &)=delete
 
SystemClockoperator= (const SystemClock &)=delete
 
 SystemClock (Clock *referenceClock, Clock *backupClock)
 Constructor. More...
 
 SystemClock ()
 Empty constructor primarily for tests. More...
 
void initSystemClock (Clock *referenceClock, Clock *backupClock)
 Same as constructor but allows delayed initialization, e.g. More...
 
ClockgetReferenceClock () const
 Get referenceClock.
 
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(). 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.
 

Friends

class ::SystemClockLoopTest_loop
 

Additional Inherited Members

- Static Public Attributes inherited from ace_time::clock::SystemClock
static const uint8_t kSyncStatusOk = 0
 Sync was successful.
 
static const uint8_t kSyncStatusError = 1
 Sync request failed.
 
static const uint8_t kSyncStatusTimedOut = 2
 Sync request timed out.
 
static const uint8_t kSyncStatusUnknown = 128
 Sync was never done.
 
- Static Public Attributes inherited from ace_time::clock::Clock
static const acetime_t kInvalidSeconds = LocalTime::kInvalidSeconds
 Error value returned by getNow() and other methods when this object is not yet initialized.
 

Detailed Description

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.

Definition at line 40 of file SystemClockLoop.h.

Constructor & Destructor Documentation

◆ SystemClockLoop()

ace_time::clock::SystemClockLoop::SystemClockLoop ( Clock referenceClock,
Clock backupClock,
uint16_t  syncPeriodSeconds = 3600,
uint16_t  initialSyncPeriodSeconds = 5,
uint16_t  requestTimeoutMillis = 1000,
ace_common::TimingStats *  timingStats = nullptr 
)
inlineexplicit

Constructor.

Parameters
referenceClockThe 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().
backupClockAn RTC chip which continues to keep time even when power is lost. Can be null.
syncPeriodSecondsseconds between normal sync attempts (default 3600)
initialSyncPeriodSecondsseconds between sync attempts when the systemClock is not initialized (default 5), exponentially increasing (2X) at each attempt until syncPeriodSeconds is reached
requestTimeoutMillisnumber of milliseconds before the request to referenceClock times out
timingStatsinternal statistics (nullable)

Definition at line 59 of file SystemClockLoop.h.

Member Function Documentation

◆ loop()

void ace_time::clock::SystemClockLoop::loop ( )
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 81 of file SystemClockLoop.h.


The documentation for this class was generated from the following file: