Synchronize a Raspberry Pi to GPS

For my solodata project, I have a Raspberry Pi installed in my miata that records CAN bus, IMU, and GPS data. Raspberry Pis doesn’t have a battery-backed hardware clock, which means it won’t track time while the Pi is powered off. This causes issues because vehicles are usually left completely powered off for long durations at a time. The other issue with the Pi being installed in a vehicle, is that there’s no guarantee of an internet connection, so getting time from a network NTP server is out of the question. In my case, I already have a GPS wired up to the Pi, I just needed to get the Pi to set the current time from it.

I found this excellent guide that explains how to set up a Raspberry Pi to time sync from GPS. It uses gpsd to parse the sample data and the 1PPS from the GPS module. The PPS signal is critical for getting sub-second timing accuracy; it’s probably not needed for most applications, but I figured why not use it as well. Once gpsd is set up, then you configure NTP to use gpsd as a time source (in my case, I made it the only time source).

The guide got me through the initial setup, but I had a few problems (1) I couldn’t get gpsd to recognize the 1PPS signal, (2) NTP wouldn’t accept times from the GPS that were too far off.

Problem 1: 1PPS not received

The first problem was resolved by building and installing the latest gpsd from source. Version 3.16 is what’s available from the Raspian package manager, but version 3.23.1 is the latest at the time of writing this. Once I had the latest version installed, I could use gpsmon and see the 1PPS offset signals just like the guide explains.

gpsmon

Problem 2: NTP panicking from large time differences

The second issue I had was that NTP wouldn’t accept the gpsd time if the difference was too large. The status from NTP would look like this.

ntp-high-offset

I made sure that I had the -g option specified in my ntp.server options, but that didn’t fix it (I left this option set though).

panicgate

Next, I tried adding tinker panic 0 to the ntp.conf, but that still didn’t help (I did not leave this option set).

tinker-panic

The item that seemed to fix it is adding flag1 1 to the GPS device options in the ntp.conf.

flag1

These flag0-4 options are kind of mysterious and the documentation for each is dependent on which clock driver is in use. My best guess is that I’m using the “Generic NMEA GPS Receiver” driver, which states that flag1 is used for PPS control. Don’t ask me why that would cause NTP to not accept a large time offset, but it seems to be setting the time just fine for now.

flag1-documentation

Conclusion

Hopefully this post helps someone who’s having similar problems. I struggled to find the flag1 fix, so that’s what pushed me to write this post mostly. If I find any other weird quirks with this setup, I’ll come back and update this post to include whatever else I find.

-Dan


Load Comments