AceTime  0.3
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::SystemClock Class Reference

A TimeKeeper that uses the Arduino millis() function to advance the time returned to the user. More...

#include <SystemClock.h>

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

Public Member Functions

 SystemClock (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...
 
- Public Member Functions inherited from ace_time::clock::TimeProvider
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 Public Attributes inherited from ace_time::clock::TimeProvider
static const acetime_t kInvalidSeconds = LocalTime::kInvalidSeconds
 

Detailed Description

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 SystemClockHeartbeatCoroutine or SystemClockHeartbeatLoop helper classes.

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 45 of file SystemClock.h.

Constructor & Destructor Documentation

◆ SystemClock()

ace_time::clock::SystemClock::SystemClock ( TimeProvider syncTimeProvider,
TimeKeeper backupTimeKeeper 
)
inlineexplicit
Parameters
syncTimeProviderThe 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().
backupTimeKeeperAn RTC chip which continues to keep time even when power is lost. Can be null.

Definition at line 55 of file SystemClock.h.

Member Function Documentation

◆ getLastSyncTime()

acetime_t ace_time::clock::SystemClock::getLastSyncTime ( ) const
inline

Return the time (seconds since Epoch) of the last valid sync() call.

Returns 0 if never synced.

Definition at line 114 of file SystemClock.h.

◆ getNow()

acetime_t ace_time::clock::SystemClock::getNow ( ) const
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 67 of file SystemClock.h.

◆ isInit()

bool ace_time::clock::SystemClock::isInit ( ) const
inline

Return true if initialized by setNow() or sync().

Definition at line 119 of file SystemClock.h.

◆ millis()

virtual unsigned long ace_time::clock::SystemClock::millis ( ) const
inlineprotectedvirtual

Return the Arduino millis().

Override for unit testing.

Definition at line 123 of file SystemClock.h.

◆ setNow()

void ace_time::clock::SystemClock::setNow ( acetime_t  epochSeconds)
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 77 of file SystemClock.h.

◆ sync()

void ace_time::clock::SystemClock::sync ( acetime_t  epochSeconds)
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 SystemClock.h.


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