GPS based NTP time server

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
User avatar
MostlyHarmless
Posts: 166
Joined: Thu Nov 21, 2019 6:25 pm
Location: Pennsylvania, USA

GPS based NTP time server

Post by MostlyHarmless » Thu Jan 09, 2020 7:00 pm

In addition to the ntpclient project I am also researching in the direction of building a "cheap" local NTP server, based on the ESP32 chip and a few other components.

One reason being that commercial, GPS based NTP servers still cost upwards of $300. That looks wrong to me. The last components I bought online were:
  • ESP32 board: $6.50
  • DS3231 time module: $5.50
  • NEO-6M GPS module: $15.00
In the end I will need a custom PCB (breadboard will do for now) and an OLED (for the deluxe edition) ... still going to be below $50 for the finished NTP server.

The trigger reason still is that I once had a big power outage (yeah, we do get Hurricanes to wreak havoc on the local infrastructure every once in a while in the northern Philadelphia suburbs). I was able to get through with a generator and power was restored after a couple hours. What didn't get restored was my Internet connection. Now all the systems didn't agree on time and since nothing came out of stratum 16 ... things didn't work well. Half my infrastructure was paralyzed because there was no authoritative time source (watch out for authentication services that demand time sync).

Lesson learned: It is cool to have local, independent infrastructure. As long as it is as independent as you think it is. Depending on NTP will not fail immediately, but who tests that stuff by cutting the internet connection for hours or days?

Anyhow, so the plan is to build a cheap NTP server. For now the idea is
  • Keep a DS3231 in sync with NEO-6M PPS to the accuracy of +/- 10us by manipulating its aging register (see below).
  • Keep the RTC of the ESP32 in sync with the DS3231 using adjtime().
  • Serve NTP on port 123 based on the RTC.
The aging register of the DS3231 is an interesting thing. It controls a capacitor array that can add/subtract crystal load capacitance in steps of about 0.1ppm. The DS3231 itself is only rated to +/- 2ppm, but using this one can adjust it to be much better, for a limited time. This will be enough to keep time accurate even if the GPS lock is lost for a few minutes.

So I created a new DS3231 driver that allows getting the time, using a PPS pin (the DS3231 can produce that) to really know when that second happens, and then created a new MicroPython function time_pulse2_us(). Similar to the existing time_pulse_us() it measures a pulse. But this one takes two pins and two levels, then returns the time difference in microseconds between one pin reaching the requested level to the other pin following on its requested level. When I now measure the rising edge of the GPS module against the falling edge of the DS3231 module, I know how far the two are apart in microseconds. Adjust the aging register to slew the DS3231, rinse, repeat ...

Unfortunately the C code can't measure anything below 6us. It might be possible to get more accuracy by restricting the use of IO pins so they have to be on the same IO register ... but I really don't want to get there at this point. 10us is close enough, especially considering that the ESP32 won't respond to a udp request on some asyncio based server fast enough to make it worth the effort.

There is no code I can share at this moment. What I want at this point is some input. What else should I consider? What have I missed? Is this of interest to anyone?


Regards, Jan


User avatar
MostlyHarmless
Posts: 166
Joined: Thu Nov 21, 2019 6:25 pm
Location: Pennsylvania, USA

Re: GPS based NTP time server

Post by MostlyHarmless » Thu Jan 09, 2020 7:25 pm

jedie wrote:
Thu Jan 09, 2020 7:18 pm
Great idea. But whats about ready to use products like https://www.adafruit.com/product/3133
Looks like engineers think alike ;)

Note that that board isn't a ready to use NTP server. It is the GPS module and the DS3231 synced to it in one breakout board. You will still need something running an NTP server in MicroPython to make that work.

Post Reply