I want to create a stratum 0 NTP clock that does not require soldering or any special hardware. It should only require a USB port and software. It should have at least 125 microsecond accuracy.
I created a Navspark firmware to print a timestamp on the serial port. It uses a string that looks like
$TS2014-06-17 @ 10:01:01(+0.234567) PM and the timestamp is the start of the transmission of the '$' character.
I also wrote a program for the Linux PC that takes the local timestamp with the GPS timestamp and sends it to NTP.
Before connecting the Navspark to the PC, I connected it to a second microcontroller. On the second microcontroller, I compared the time between the Navspark's timestamp pin going high and the UART byte '$' in the timestamp line received. From this duration, I removed the Navspark's processing time found in the "$ZZAAC" message (timestamp interrupt time as well as time spent in
gnss_uart_tx_send) as well as 86 microseconds for the UART transmission time at 115.2kbaud.
In an ideal world, this would be a flat line at 0 microseconds.
mean: -0.2 microseconds std dev: 0.6 microseconds min: -2 microseconds max: 2 microseconds
This is pretty good, considering that 1 bit is almost 9 microseconds wide at 115.2kbaud.
Finally, I hooked it up to a PC. The USB/UART bridge is the main source of error in this setup.
I used the ntp-shm program (from the "How?" section above). I got a result of:
The green line is the PC's clock running fast (between 19.2 ppm and 19.8 ppm fast) and the red mass is the offset between the local and GPS clocks. The 90th percentile of NTP offsets is +/-47 microseconds. So this is better than the 125 microsecond accuracy of the USB/UART bridge. You can see my AC turning off and on in the green line. The times on the graph are in UTC and I'm in UTC-5.
Bonus NTP graph
Histogram of clock offsets