AceTime  0.5
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.
SystemClockSyncLoop.h
1 /*
2  * MIT License
3  * Copyright (c) 2018 Brian T. Park
4  */
5 
6 #ifndef ACE_TIME_SYSTEM_CLOCK_SYNC_LOOP_H
7 #define ACE_TIME_SYSTEM_CLOCK_SYNC_LOOP_H
8 
9 #include <stdint.h>
10 #include "SystemClock.h"
11 
12 namespace ace_time {
13 namespace clock {
14 
28  public:
38  explicit SystemClockSyncLoop(SystemClock& systemClock,
39  uint16_t syncPeriodSeconds = 3600,
40  uint16_t initialSyncPeriodSeconds = 5):
41  mSystemClock(systemClock),
42  mSyncPeriodSeconds(syncPeriodSeconds),
43  mCurrentSyncPeriodSeconds(initialSyncPeriodSeconds) {}
44 
49  void loop() {
50  if (mSystemClock.mSyncTimeProvider == nullptr) return;
51 
52  unsigned long nowMillis = millis();
53  unsigned long timeSinceLastSync = nowMillis - mLastSyncMillis;
54 
55  if (timeSinceLastSync >= mCurrentSyncPeriodSeconds * 1000UL
56  || mSystemClock.getNow() == 0) {
57  acetime_t nowSeconds = mSystemClock.mSyncTimeProvider->getNow();
58 
59  if (nowSeconds == 0) {
60  // retry with exponential backoff
61  if (mCurrentSyncPeriodSeconds >= mSyncPeriodSeconds / 2) {
62  mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
63  } else {
64  mCurrentSyncPeriodSeconds *= 2;
65  }
66  } else {
67  mSystemClock.sync(nowSeconds);
68  mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
69  }
70 
71  mLastSyncMillis = nowMillis;
72  }
73  }
74 
79  uint16_t getSecondsSinceLastSync() const {
80  unsigned long elapsedMillis = millis() - mLastSyncMillis;
81  return elapsedMillis / 1000;
82  }
83 
84  private:
85  // disable copy constructor and assignment operator
87  SystemClockSyncLoop& operator=(const SystemClockSyncLoop&) = delete;
88 
89  SystemClock& mSystemClock;
90  uint16_t const mSyncPeriodSeconds;
91 
92  unsigned long mLastSyncMillis = 0; // should be the same type as millis()
93  uint16_t mCurrentSyncPeriodSeconds;
94 };
95 
96 }
97 }
98 
99 #endif
uint16_t getSecondsSinceLastSync() const
Return the number of seconds since last sync.
acetime_t getNow() const override
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z).
Definition: SystemClock.h:80
A TimeKeeper that uses the Arduino millis() function to advance the time returned to the user...
Definition: SystemClock.h:50
A class that that syncs the SystemClock with its mSyncTimeProvider.
void loop()
Call this from the global loop() method.
void sync(acetime_t epochSeconds)
Similar to setNow() except that backupNow() is called only if the backupTimeKeeper is different from ...
Definition: SystemClock.h:109
virtual acetime_t getNow() const =0
Return the number of seconds since the AceTime epoch (2000-01-01T00:00:00Z).
SystemClockSyncLoop(SystemClock &systemClock, uint16_t syncPeriodSeconds=3600, uint16_t initialSyncPeriodSeconds=5)
Constructor.