Close

Software Design

A project log for SynchroClock

NTP Synchronized Analog Clock

liebmanliebman 09/16/2017 at 14:210 Comments

  When the ESP8266 starts, and this could be from a cold start like a power fail or a wakeup from its deep sleep mode, it attempts to connect to wifi.  If it fails, or was never configured, it creates a captive WiFi portal that allows configuration of WiFi SSID and password, current clock position, NTP server, time change information, and some advanced settings.

    After connecting to WiFI it makes an NTP request and computes both the offset and network delay.  The offset is used to adjust the RTC only the offset is greater than a threshold and if the network delay is within 1 standard deviation from the last 7 or 8 requests.  The last 8 offsets that were used to adjust the RTC are saved and used to compute the drift in parts per million of the RTC.  This is used between NTP requests to help keep the RTC, and the cock, ticking at the correct time.

    Next the current time is read from the RTC and converted to a clock position. Since most analog clocks only have a 12 hour face there are only 43200 possible unique hand positions so we represent the  position of the analog clock as an unsigned integer between 0, midnight/noon, and 43199, 11:59:59/23:59:59. The current clock position is also read from the ATTiny85 and an adjustment is computed and sent back to the ATTiny85.

   The ESP8266 then enters its lowest power sleep mode, deep sleep, where only a wakeup timer and the 512 bytes of memory that we use to store the NTP samples are powered.

   Setting the RTC within milliseconds is a challenge since it’s the time it keeps is in 1 second values.  The key is that when you write the seconds value to the RTC it synchronizes it 1Hz square wave output to that moment. The specific verbiage in the DS3231 data sheet is “The 1Hz square-wave output, if enabled, transitions high 500ms after the seconds data transfer, provided the oscillator is already running.” This makes the falling edge the start of each second.  So by using the offset from NTP and coordinating when to set the time to be where NTP says the second should start syncs the RTC within a milliseconds.

   The other RTC trick is that when we read the time for the origin timestamp of an NTP request we wait for the falling edge of the square wave first.  Since this is a second boundary the NTP timestamp will be with zero fraction value.

   One area thats still a work in progress is deciding how long to wait between NTP polls.  The longer this is the less overall power will be used and the longer the batteries will last.  Currently, and this is a work in progress, I’m using samples obtained since the previous adjustment to compute an estimated drift.  This is then used to compute how long at the estimated drift rate it would take the clock to drift by the offset threshold.

Discussions