AceTime  0.5.2
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 "TimeKeeper.h"
12 
13 extern "C" unsigned long millis();
14 
15 namespace ace_time {
16 namespace clock {
17 
50 class SystemClock: public TimeKeeper {
51  public:
52 
60  explicit SystemClock(
61  TimeProvider* syncTimeProvider /* nullable */,
62  TimeKeeper* backupTimeKeeper /* nullable */):
63  mSyncTimeProvider(syncTimeProvider),
64  mBackupTimeKeeper(backupTimeKeeper) {}
65 
66  void setup() {
67  if (mBackupTimeKeeper != nullptr) {
68  setNow(mBackupTimeKeeper->getNow());
69  }
70  }
71 
76  void keepAlive() {
77  getNow();
78  }
79 
80  acetime_t getNow() const override {
81  if (!mIsInit) return kInvalidSeconds;
82 
83  while ((uint16_t) ((uint16_t) millis() - mPrevMillis) >= 1000) {
84  mPrevMillis += 1000;
85  mEpochSeconds += 1;
86  }
87  return mEpochSeconds;
88  }
89 
90  void setNow(acetime_t epochSeconds) override {
91  if (epochSeconds == kInvalidSeconds) return;
92 
93  mEpochSeconds = epochSeconds;
94  mPrevMillis = millis();
95  mIsInit = true;
96  mLastSyncTime = epochSeconds;
97  backupNow(epochSeconds);
98  }
99 
110  void sync(acetime_t epochSeconds) {
111  if (epochSeconds == kInvalidSeconds) return;
112  if (mEpochSeconds == epochSeconds) return;
113 
114  mEpochSeconds = epochSeconds;
115  mPrevMillis = millis();
116  mIsInit = true;
117  mLastSyncTime = epochSeconds;
118 
119  if (mBackupTimeKeeper != mSyncTimeProvider) {
120  backupNow(epochSeconds);
121  }
122  }
123 
128  acetime_t getLastSyncTime() const {
129  return mLastSyncTime;
130  }
131 
133  bool isInit() const { return mIsInit; }
134 
135  protected:
137  virtual unsigned long millis() const { return ::millis(); }
138 
139  private:
140  friend class SystemClockSyncCoroutine;
141  friend class SystemClockSyncLoop;
142 
148  void backupNow(acetime_t nowSeconds) {
149  if (mBackupTimeKeeper != nullptr) {
150  mBackupTimeKeeper->setNow(nowSeconds);
151  }
152  }
153 
154  const TimeProvider* const mSyncTimeProvider;
155  TimeKeeper* const mBackupTimeKeeper;
156 
157  mutable acetime_t mEpochSeconds = 0; // time presented to the user
158  mutable uint16_t mPrevMillis = 0; // lower 16-bits of millis()
159  bool mIsInit = false; // true if setNow() or sync() was successful
160  acetime_t mLastSyncTime = 0; // time when last synced
161 };
162 
163 }
164 }
165 
166 #endif
A coroutine that syncs the SystemClock with its mSyncTimeProvider.
acetime_t getNow() const override
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z).
Definition: SystemClock.h:80
void setNow(acetime_t epochSeconds) override
Set the time to the indicated seconds.
Definition: SystemClock.h:90
bool isInit() const
Return true if initialized by setNow() or sync().
Definition: SystemClock.h:133
Base class for objects that provide a source of time whose time cannot be changed by the end-user...
Definition: TimeProvider.h:20
A TimeKeeper that uses the Arduino millis() function to advance the time returned to the user...
Definition: SystemClock.h:50
virtual void setNow(acetime_t epochSeconds)=0
Set the time to the indicated seconds.
A TimeProvider whose time can be set by the end-user.
Definition: TimeKeeper.h:19
SystemClock(TimeProvider *syncTimeProvider, TimeKeeper *backupTimeKeeper)
Definition: SystemClock.h:60
A class that that syncs the SystemClock with its mSyncTimeProvider.
void sync(acetime_t epochSeconds)
Similar to setNow() except that backupNow() is called only if the backupTimeKeeper is different from ...
Definition: SystemClock.h:110
void keepAlive()
Call this (or getNow() every 65.535 seconds or faster to keep the internal counter in sync with milli...
Definition: SystemClock.h:76
virtual acetime_t getNow() const =0
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z).
virtual unsigned long millis() const
Return the Arduino millis().
Definition: SystemClock.h:137
acetime_t getLastSyncTime() const
Return the time (seconds since Epoch) of the last valid sync() call.
Definition: SystemClock.h:128