AceTime  1.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.
SystemClock.h
1 /*
2  * MIT License
3  * Copyright (c) 2018 Brian T. Park
4  */
5 
6 #ifndef ACE_TIME_SYSTEM_CLOCK_H
7 #define ACE_TIME_SYSTEM_CLOCK_H
8 
9 #include <stdint.h>
10 #include "../common/TimingStats.h"
11 #include "Clock.h"
12 
13 extern "C" unsigned long millis();
14 class SystemClockLoopTest;
15 class SystemClockLoopTest_syncNow;
16 class SystemClockCoroutineTest;
17 
18 namespace ace_time {
19 namespace clock {
20 
53 class SystemClock: public Clock {
54  public:
55 
57  void setup() {
58  if (mBackupClock != nullptr) {
59  setNow(mBackupClock->getNow());
60  }
61  }
62 
63  acetime_t getNow() const override {
64  if (!mIsInit) return kInvalidSeconds;
65 
66  while ((uint16_t) ((uint16_t) clockMillis() - mPrevMillis) >= 1000) {
67  mPrevMillis += 1000;
68  mEpochSeconds += 1;
69  }
70  return mEpochSeconds;
71  }
72 
73  void setNow(acetime_t epochSeconds) override {
74  syncNow(epochSeconds);
75 
76  // Also set the reference clock if possible.
77  if (mReferenceClock != nullptr) {
78  mReferenceClock->setNow(epochSeconds);
79  }
80  }
81 
83  void forceSync() {
84  acetime_t nowSeconds = mReferenceClock->getNow();
85  setNow(nowSeconds);
86  }
87 
92  acetime_t getLastSyncTime() const {
93  return mLastSyncTime;
94  }
95 
97  bool isInit() const { return mIsInit; }
98 
99  protected:
100  friend class ::SystemClockLoopTest;
101  friend class ::SystemClockCoroutineTest;
102  friend class ::SystemClockLoopTest_syncNow;
103 
104  // disable copy constructor and assignment operator
105  SystemClock(const SystemClock&) = delete;
106  SystemClock& operator=(const SystemClock&) = delete;
107 
116  explicit SystemClock(
117  Clock* referenceClock /* nullable */,
118  Clock* backupClock /* nullable */):
119  mReferenceClock(referenceClock),
120  mBackupClock(backupClock) {}
121 
126  virtual unsigned long clockMillis() const { return ::millis(); }
127 
132  void keepAlive() {
133  getNow();
134  }
135 
140  void backupNow(acetime_t nowSeconds) {
141  if (mBackupClock != nullptr) {
142  mBackupClock->setNow(nowSeconds);
143  }
144  }
145 
156  void syncNow(acetime_t epochSeconds) {
157  if (epochSeconds == kInvalidSeconds) return;
158  mLastSyncTime = epochSeconds;
159  if (mEpochSeconds == epochSeconds) return;
160 
161  mEpochSeconds = epochSeconds;
162  mPrevMillis = clockMillis();
163  mIsInit = true;
164 
165  if (mBackupClock != mReferenceClock) {
166  backupNow(epochSeconds);
167  }
168  }
169 
170  Clock* const mReferenceClock;
171  Clock* const mBackupClock;
172 
173  mutable acetime_t mEpochSeconds = kInvalidSeconds;
174  acetime_t mLastSyncTime = kInvalidSeconds; // time when last synced
175  mutable uint16_t mPrevMillis = 0; // lower 16-bits of clockMillis()
176  bool mIsInit = false; // true if setNow() or syncNow() was successful
177 };
178 
179 }
180 }
181 
182 #endif
void backupNow(acetime_t nowSeconds)
Write the nowSeconds to the backupClock (which can be an RTC that has non-volatile memory...
Definition: SystemClock.h:140
acetime_t getNow() const override
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z).
Definition: SystemClock.h:63
void setNow(acetime_t epochSeconds) override
Set the time to the indicated seconds.
Definition: SystemClock.h:73
bool isInit() const
Return true if initialized by setNow() or syncNow().
Definition: SystemClock.h:97
A Clock that uses the Arduino millis() function to advance the time returned to the user...
Definition: SystemClock.h:53
void forceSync()
Force a sync with the mReferenceClock.
Definition: SystemClock.h:83
void keepAlive()
Call this (or getNow() every 65.535 seconds or faster to keep the internal counter in sync with milli...
Definition: SystemClock.h:132
virtual unsigned long clockMillis() const
Return the Arduino millis().
Definition: SystemClock.h:126
virtual void setNow(acetime_t)
Set the time to the indicated seconds.
Definition: Clock.h:56
SystemClock(Clock *referenceClock, Clock *backupClock)
Constructor.
Definition: SystemClock.h:116
void setup()
Attempt to retrieve the time from the backupClock if it exists.
Definition: SystemClock.h:57
Base class for objects that provide and store time.
Definition: Clock.h:20
acetime_t getLastSyncTime() const
Return the time (seconds since Epoch) of the last valid sync() call.
Definition: SystemClock.h:92
virtual acetime_t getNow() const =0
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z).
void syncNow(acetime_t epochSeconds)
Similar to setNow() except that backupNow() is called only if the backupClock is different from the r...
Definition: SystemClock.h:156