AceTime  0.5.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.
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 extern "C" unsigned long millis();
13 
14 namespace ace_time {
15 namespace clock {
16 
30  public:
40  explicit SystemClockSyncLoop(SystemClock& systemClock,
41  uint16_t syncPeriodSeconds = 3600,
42  uint16_t initialSyncPeriodSeconds = 5):
43  mSystemClock(systemClock),
44  mSyncPeriodSeconds(syncPeriodSeconds),
45  mCurrentSyncPeriodSeconds(initialSyncPeriodSeconds) {}
46 
51  void loop() {
52  if (mSystemClock.mSyncTimeProvider == nullptr) return;
53 
54  unsigned long nowMillis = millis();
55  unsigned long timeSinceLastSync = nowMillis - mLastSyncMillis;
56 
57  if (timeSinceLastSync >= mCurrentSyncPeriodSeconds * 1000UL
58  || mSystemClock.getNow() == 0) {
59  acetime_t nowSeconds = mSystemClock.mSyncTimeProvider->getNow();
60 
61  if (nowSeconds == 0) {
62  // retry with exponential backoff
63  if (mCurrentSyncPeriodSeconds >= mSyncPeriodSeconds / 2) {
64  mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
65  } else {
66  mCurrentSyncPeriodSeconds *= 2;
67  }
68  } else {
69  mSystemClock.sync(nowSeconds);
70  mCurrentSyncPeriodSeconds = mSyncPeriodSeconds;
71  }
72 
73  mLastSyncMillis = nowMillis;
74  }
75  }
76 
81  uint16_t getSecondsSinceLastSync() const {
82  unsigned long elapsedMillis = millis() - mLastSyncMillis;
83  return elapsedMillis / 1000;
84  }
85 
86  private:
87  // disable copy constructor and assignment operator
89  SystemClockSyncLoop& operator=(const SystemClockSyncLoop&) = delete;
90 
91  SystemClock& mSystemClock;
92  uint16_t const mSyncPeriodSeconds;
93 
94  unsigned long mLastSyncMillis = 0; // should be the same type as millis()
95  uint16_t mCurrentSyncPeriodSeconds;
96 };
97 
98 }
99 }
100 
101 #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:110
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.