balena enabled GPS NTP timeserver with gpsd and chronyd.
Get yourself an GPS module that works with this setup, wire it to your RPi and deploy the application with balena.
There are multiple environmental variables in case you need to customize the setup:
You can use all B+ models, except RPi 1B+/RPi Zero as these models are extremely slow with current balenaOS releases and the image does not work with them. Consequently, you can use the RPi 2B, 3B, 3B+, 4B, 400, CM4 and balenaFin. It does not matter if you use the 32 or 64 bit versions as balena handles this nicely. This setup has been tested with RPi 2B and RPi 4B in 64 bit mode.
All 3v3 TTL-LvL GPS modules with PPS output should be working, it was tested with Watterott's CAM-M8Q-Breakout Multi GNSS Modul (GPS, QZSS, GLONASS, BeiDou, Galileo), but should also work with e.g. Adafruit Ultimate GPS Breakout - 66 channel w/10 Hz updates - Version 3.
Pinout taken from official Raspberry Pi Documentation. Please bear in mind this wiring schematic is correct for RPi 1A+/B+ and following.
You can use the balenaCloud Terminal to directly connect to the gpsTime console. There you can use:
chronyc sources -v
to see the currently used device (should be like shown below, * PSM0 means PSM0 is used, which is the correct device)
.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = current best, '+' = combined, '-' = not combined,
| / 'x' = may be in error, '~' = too variable, '?' = unusable.
|| .- xxxx [ yyyy ] +/- zzzz
|| Reachability register (octal) -. | xxxx = adjusted offset,
|| Log2(Polling interval) --. | | yyyy = measured offset,
|| \ | | zzzz = estimated error.
|| | | \
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
#? PPS0 0 3 377 9 +899ns[ +907ns] +/- 1176ns
#? GPS0 0 3 377 10 +104ms[ +104ms] +/- 100ms
#* PSM0 0 3 377 9 +899ns[ +907ns] +/- 1176ns
#? PST0 0 3 377 9 +899ns[ +899ns] +/- 1176ns
gpsmon -n
to provide you a look about all incoming GPS data
┌──────────────────────────────────────────────────────────────────────────────┐
│
└───────────────────────────────── Cooked TPV ─────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────────┐
│ GPZDA GPGGA GPRMC GPGSA GPGBS GPGSV │
└───────────────────────────────── Sentences ──────────────────────────────────┘
┌──────────────────┐┌────────────────────────────┐┌────────────────────────────┐
│PRN Az El S/N ││Time: 183727.00 ││Time: 183727.00 │
│ 1 000 2 10 ││Latitude: 0.0 N ││Latitude: 0.0 │
│ 2 000 26 22 ││Longitude: 0.0 W ││Longitude: 0.0 │
│ 3 000 35 10 ││Speed: 0.4918 ││Altitude: 0.0 │
│ 4 00 69 9 ││Course: 0.0 ││Quality: 1 Sats: 07 │
│ 6 000 55 21 ││Status: A FAA: ││HDOP: 2.04 │
│ 7 000 16 27 ││MagVar: 2.2 E ││Geoid: 46.18 │
│ 9 000 70 25 │└─────────── RMC ────────────┘└─────────── GGA ────────────┘
│ 11 000 28 16 │┌────────────────────────────┐┌────────────────────────────┐
│ 17 000 8 26 ││Mode: A3 Sats: 4 7 9 17 19 ││UTC: RMS: │
│ 19 000 20 24 ││DOP: H=2.0 V=2.2 P=3.0 ││MAJ: MIN: │
│ 22 000 13 0 ││TOFF: 0.102425538 ││ORI: LAT: │
│ 26 00 6 0 ││PPS: -0.000001842 ││LON: ALT: │
└────── GSV ───────┘└──────── GSA + PPS ─────────┘└─────────── GST ────────────┘
------------------- PPS offset: 0.000000003 ------
chronyc makestep
To make chrony "tick" the local clock on the RPi to the next time in a hard sweep, not via soft modification over time.
You can e.g. synchronize your home network devices with your gpsTime balena device and then compare their time quality with other NTP servers. On Windows 10, this works easily with
w32tm /stripchart /computer:<IPorDNS> /dataonly /samples:5
In this example I compared my locale gpsTime NTP server with the ptbtime3 (an official german timeserver). I synchronized the clock local RTC of my laptop to gpsTime and then used following commands. The first one will show how much the RPi and the local RTC will differ, the second one how much the PTB timeserver and the local RTC do. As you can see, my local RTC is slight in the past (both times are a fraction of a second in the future, indicated by the +) - however, we are well in the sub-second area:
w32tm /stripchart /computer:<IPofRPi> /dataonly /samples:5
It is 04.07.2021 18:03:43.
18:03:43, +00.0085224s
18:03:45, +00.0079209s
w32tm /stripchart /computer:ptbtime3.ptb.de /dataonly /samples:5
It is 04.07.2021 18:03:46.
18:03:46, +00.0119076s
18:03:48, +00.0123034s
Also try to use timeservers as close as possible to you and via Ethernet, not Wifi or other wireless communication standards. All these factors will influence the quality of the timesignal. This is also the reason why to build a local timeserver on GPS base: Being independent from network access and with a bit more accuracy. Also its fun ;).
A lot of this is taken from the excellent work of beta-tester's Repo, but also other websites. To give an overview to all these awesome people: