This wiki was updated to MediaWiki 1.37. If you notice any issues, please report them to admin[at]

HCL:Raspberry Pi3 GPS

Jump to: navigation, search

This is a guide for setting up a Raspberry Pi3 as a local time server with a GPS module with pps output and configuring the gpsd and chrony services. It also disables the onboard bluetooth to use /dev/ttyAMA0 for the gps feed.

NOTE: There is no reason you can't use a USB gps, all that is needed is a pps output from the device to the selected gpio pin and modification of the dt overlay.

GPS Module

As long as the gps module has pps out it should work fine. For example a NEO-6M (Arduino GPS, Drone Microcontroller GPS Receiver) Compatible with 51 Microcontroller STM32 Arduino UNO R3 with IPEX Antenna High Sensitivity for Navigation Satellite Positioning for creating this HCL entry.
NEO-6M gps1.jpgNEO-6M gps2.jpg.jpg

Device Tree (DT) overlay

The GPS module PPS output needs to be activated with a Device Tree (DT) overlay. The configuration for this is located at /boot/efi/extraconfig.txt. GPIO pin 18 was chosen for its location next to the tx and rx pins for the gps.


YaST Bootloader changes

Start YaST Bootloader and modify default from;

GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 splash=silent plymouth.enable=0 console=ttyS0,115200n8"


GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 splash=silent plymouth.enable=0 console=tty1"

Now reboot the system and check for the pps and AMA0 devices are present, for example;

dmesg |egrep "ttyAMA0|pps0"
[    4.939465] 3f201000.serial: ttyAMA0 at MMIO 0x3f201000 (irq = 66, base_baud = 0) is a PL011 rev2
[   20.034296] pps pps0: new PPS source pps@12.-1
[   20.034388] pps pps0: Registered IRQ 79 as PPS source

If devices are present you can proceed to install the additional gpsd and pps-tools packages, check pps output and configure gpsd and chrony. You can install the gpsd-clients package if desired, but it pulls in considerable packages for the X clients.

zypper in gpsd pps-tools

Test the pps output is functioning;

ppstest /dev/pps0

trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1616795192.000002666, sequence: 19800 - clear  0.000000000, sequence: 0
source 0 - assert 1616795193.000001291, sequence: 19801 - clear  0.000000000, sequence: 0
source 0 - assert 1616795194.000000385, sequence: 19802 - clear  0.000000000, sequence: 0
source 0 - assert 1616795195.000001398, sequence: 19803 - clear  0.000000000, sequence: 0

If data is being seen, then all ok to proceed with further configuration.

GPSD Configuration

In the case of only using ipv4, then you will need to copy the gpsd.service and gpsd.socket to /etc/systemd/system and edit out the ipv6 ListenStream line;

Description=GPS (Global Positioning System) Daemon Sockets



Don't forget to systemctl daemon-reload after editing!
Edit /etc/sysconfig/gpsd and add the following options;

GPSD_OPTIONS="-G -n -b /dev/ttyAMA0 /dev/pps0"

Now test the gpsd service is starting and no errors seen;

systemctl start gpsd

systemctl status gpsd

● gpsd.service - GPS (Global Positioning System) Daemon
     Loaded: loaded (/etc/systemd/system/gpsd.service; disabled; vendor preset: disabled)
     Active: active (running) since ...
TriggeredBy: ● gpsd.socket
   Main PID: 697 (gpsd)
      Tasks: 3
     CGroup: /system.slice/gpsd.service
             └─697 /usr/sbin/gpsd -G -n -b /dev/ttyAMA0 /dev/pps0

Feb 08 06:00:19 host systemd[1]: Starting GPS (Global Positioning System) Daemon...
Feb 08 06:00:19 host systemd[1]: Started GPS (Global Positioning System) Daemon.

If no errors reported, enable the service to start on boot.

systemctl enable gpsd

Chronyd Configuration

Create a new file in /etc/chrony.d/ called for example gps_time.conf at a minimum you need the two gps refclock sources, allow local access and allow local sync.

# Add gps and pps as reference clock
refclock SHM 0  delay 0.5 refid NMEA
refclock PPS /dev/pps0 refid PPS

# Allow NTP client access from local network.

# Serve time even if not synchronized to a time source.
local stratum 10


Now restart chronyd and as long as no errors can proceed to test.

Check that the NMEA (a -) and PPS (a *) sources are synced via the following command;

chronyc sources -v

210 Number of sources = 6

  .-- Source mode  '^' = server, '=' = peer, '#' = local clock.
 / .- Source state '*' = current synced, '+' = combined , '-' = not combined,
| /   '?' = unreachable, 'x' = time may be in error, '~' = time too variable.
||                                                 .- 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               
#- NMEA                          0   4     3    13   +142ms[ +149ms] +/-  250ms
#* PPS                           0   4   203    12   +502ns[+7004us] +/-  155us
^- 097-091-222-080.res.spec>     1   6    37    60  -4234us[+2769us] +/-   34ms
^-               3   6    37    60    -10ms[-3351us] +/-   91ms
^-      2   6    37    60    -11ms[-4557us] +/-   85ms
^-                2   6    37    60  -3607us[+3321us] +/-   64ms

Now as a final check use the tracking and serverstats options;

chronyc tracking

Reference ID    : NNNNNNNN (PPS)
Stratum         : 1
Ref time (UTC)  : Tue Mar 30 22:16:28 2021
System time     : 0.000000199 seconds slow of NTP time
Last offset     : -0.000000152 seconds
RMS offset      : 0.000510382 seconds
Frequency       : 4.773 ppm fast
Residual freq   : -0.000 ppm
Skew            : 0.012 ppm
Root delay      : 0.000000001 seconds
Root dispersion : 0.000011117 seconds
Update interval : 16.0 seconds
Leap status     : Normal

chronyc serverstats

NTP packets received       : 37
NTP packets dropped        : 0
Command packets received   : 38
Command packets dropped    : 0
Client log records dropped : 0

Now for another reboot and check the services start and chronyc outputs are correct. Depending on the module used it can take some minutes.

Client Configuration

To add the new time server to local machines this can be done on openSUSE systems via YaST ntp-client or add to /etc/chrony.d/pool.conf;

pool <server fqdn or ip address> iburst

The same chronyc tests can be performed on the client to verify it's syncing with the Raspberry Pi3 time server;

chronyc tracking

Reference ID    : NNNNNNNN (<hostname>)

chronyc sources

210 Number of sources = 3
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
^* hostname                      1   9   377   377    +31us[  +24us] +/-  198us
^-             1   9   377    53  -5135us[-5135us] +/-   34ms
^-             1   9   377   241  -4242us[-4242us] +/-   33ms