How-to use a Garmin 18x with Chrony and PPS

Hi all,

You need to solder a plug to the device, found here:

Once and for all, as good guide how to configure the software for use with the 18x Garmin 1Hz or 5Hz RS-232 receiver.

1: Install the module ‘pps_ldisc’ in Debian/Ubuntu under /etc/modules-load.d/xxxxxx.conf I assume you know how to do that.

Check if the module is loaded after reboot.
If it’s working, you should see under /dev pps0 pps1 pps2 or whatever.

Now check with ‘ppsfind --help’ where it’s connected too. Typical when com1 is used it should be /ttyS0 and shows something like this:

pps0: name=ptp0 path=
pps1: name=ptp1 path=
pps2: name=serial0 path=/dev/ttyS0

So you can see it’s there, now run this and you should get timestamping from pps:
(beware, PPS can take upto 5 minutes after the GPS is started!!)

ppswatch /dev/pps2
trying PPS source "/dev/pps2"
found PPS source "/dev/pps2"
timestamp: 1710171283, sequence: 724, offset:  299981447
timestamp: 1710171283, sequence: 724, offset:  299981447
timestamp: 1710171284, sequence: 725, offset: -499998101
timestamp: 1710171284, sequence: 725, offset: -499998101

Ok now you know the GPS is working as it’s pulsating.

2: Now you need to know the speed of the GPS, it used to be 4800baud by default, but it seems they have changed this with the latest firmware.
There is no good way to find the speed, trust me I tried all.

To my knowledge today it’s 18x 9600baud and the 5Hz version 19200
So set this in your /etc/default/gpsd

DEVICES="/dev/ttyS0 /dev/pps2"

# Other options you want to pass to gpsd
GPSD_OPTIONS="-n -b -s 19200"

# Automatically hot add/remove USB GPS devices via gpsdctl

Restart GPSD and run CGPS or GPSMON, they should give you time and PPS info and you should see sat-info lines scrolling. If it doesn’t change the speed and restart GPSD until it does.

3: We need to configure Chrony to access the device. That is pretty simple:

18x 1Hz - I prefer SHM and PPS adjust offset to your own needs all the rest should be ok, the offset can be seen after 10 minutes with ‘chronyc sourcestats’ :

refclock SHM 0 refid GPS poll 4 precision 1e-3 offset 0.071 delay 0.2
refclock PPS /dev/pps2 lock GPS refid PPS poll 2 precision 1e-7 prefer

18x 5Hz:

refclock SHM 0 refid GPS precision 1e-3 poll 4 offset 0.122 delay 0.2
refclock PPS /dev/pps2 lock GPS refid PPS poll 1 precision 1e-9 rate 5 width 0.1 maxlockage 32 prefer

That is it folks!!! Happy time-sharing :rofl:

The problem is most people don’t specify the baudrate-speed and often the GPS isn’t detected because of that.
At best you start with 18x at 9600bd and 18x-5Hz at 19200bd, good chance it works out of the box.

If all of this doesn’t work, check if the firmware is at the latest version, 4.50 is the latest at the time of writing.


Ps. feel free to comment if you like.

When it comes to Linux, NEVER assume that the reader knows what they are doing. I’m trying to get a PPS link working on my machine and after days of searching, I still can’t find anything relating to what you mention, or how to even get PPS via pin 1 on the serial port.

Edit - Looks like PPS is now working without any apparent configuration, but I can’t get any NMEA output over serial.

Edit2 - Well I guess I didnt get the PPS working. ppstest keeps failing with

cannot create a PPS source from device “/dev/ttyS0” (Operation not supported)

But ppscheck does return what looks like a valid pulse.

Seconds nanoSecs Signals
1710305840.000148739 TIOCM_CD
1710305841.000126203 TIOCM_CD

I’ve double checked my connections and still get nothing. The only other thing I can think of is that the serial output from the GPS chip is not compatible with the serial input, and I’ll probably need a level shifter or something.

It is pulsing alright!!! :slight_smile:

do the following:

modprobe pps_ldisc


ldattach 18 /dev/ttyS0

then run

ppsfind --help

If it gave an ppsX: then you know it has created an pps device and attched it to the serial port.

Beware, you MUST do all this as root user, it won’t work as normal user.

When ppsfind has found it, then make it permanent and do the following:

nano /etc/modules-load.d/pps-source.conf

insert this in the file: pps_ldisc

so it loads the module at system-start. (reboot to see if it does, run just ppsfind --help after reboot)

now you can use /dev/ppsX as the pps source I described above.

to answer your questions:

NMEA requires GPSD to be installed and then feed to Chrony as I described first post. But the ppsX needs to work first else GPSD won’t start properly.

Use GPSMON it will tell you what your GPS does AFTER GPSD is running and installed as described above.

Looks to me you run in user-mode and not as root (on Unbuntu use ‘sudo -i’ to get in root-mode)


It’s not working on my setup, possible issue could be my OS of choice (Ubuntu server), or maybe the serial chipset on the motherboard. Maybe if it doesn’t detect voltage(s) on certain pin(s), it doesn’t actually “turn on” even though it’s recognized and drivers loaded in OS? I don’t know, but so far there is zero PPS recognition. I haven’t tried using a different pin (CTS? DTR?), but I’m not exactly expecting a different result.

I uninstalled everything and started fresh. From what I’ve read on a modern Linux OS, installing pps-tools should be enough to get the PPS automatically recognized and working on serial pin 1, but I get absolutely nothing. Doing dmesg | grep pps only shows that the module was loaded, but not latched onto anything. tty also find nothing other then the serial port. And modprobe for pps_ldisk always errors with not found (hence why I think maybe its OS I’m using). pps-ldisc is found and loaded.

What PPS was latching onto previously, was what gpsd latched onto which was the NMEA “serial” data, not the PPS pulse. No gpsd, nothing for PPS to latch onto. So those time stamps I had in my previous post, was actual GPS NMEA timestamps, not PPS.

Fresh install of Debian 12.5.0

modprobe: FATAL: Module pps_ldisk not found in directory /lib/modules/6.1.0-18-amd64

I can’t even get past that point in Ubuntu either.

There is a typo here, it should be pps_ldisc (with a “c” at the end, for line discipline).

Normally, when using gpsd and its client tools, such as gpsmon, one doesn’t have to muck with the line discipline separately. gpsd takes care of that, it’ll set the proper line discipline on the port and will pick up PPS when it’s available.

Try undoing all the pps_ldisc stuff, remove the pps device from the gpsd config file, restart gpsd, then see what gpsmon indicates. As @bas writes, the output you showed indicates there is a pulse visible, so it is a matter of getting the tools to pick it up.

As intermediate step, you can also run gpsmon directly against the port, without gpsd running. Another way to see that the pulse, as well as the NMEA data are available on the port.

Or you could run gpsd with debugging on, with -D x, where x > 0, and see what it tells you. If the debug level is high enough, it should report whether it can enable the line discipline/kernel PPS, and then each pulse (plus a lot of output regarding the processing of the serial data).

What typo? :rofl:

I’m word-blind, as such I can make these mistakes.

However, I did write it correctly in the last post of mine.

Corrected the typo in order not to confuse others.

Thanks for noticing it.


I should have added, that yes, I did also try pps_ldisc, but that would always come up blank, no response at all.

But, I finally got it to work! I had to play around with the serial adapter first, and it looks like I had to connect the 3 standard pins (Receive, Transmit AND Ground) to my serial port on the motherboard to get it to work, but I still had no recognized PPS signal that I could locate even after getting the serial port to work and receive data. So I just went ahead anyway and used your commands and it seemed to have worked.

$modprobe pps_ldisc
$ldattach 18 /dev/ttyS0
$ppsfind --help
pps0: name=serial0 path=/dev/ttyS0

Great. Followed the rest of the commands, rebooted to test, run ppsfind, and nothing…

Run the commands again, ppsfind finds pps, reboot, ppsfind doesn’t find anything. Rinse, repeat. It’s not keeping the settings.

In fustration I just installed gpsd to get that up and running and maybe getting PPS recognized and working, and it indeed got PPS working. Reboot after reboot, PPS and GPS working fine, finally. Install Chrony, configured Chrony, multiple reboots to test, and here’s the results after only a minute or two

MS Name/IP address         Stratum Poll Reach LastRx Last sample
#- GPS                           0   4   377    19   -100us[  -99us] +/-  100ms
#* PPS                           0   4   377    19   +269ns[ +996ns] +/-  492ns
^- ntp.home.lan                  1   6    37    32    -89us[  -89us] +/-  258us
^- ntp2.home.lan                 1   6    37    32    -99us[  -98us] +/-  233us
^- ntp3.home.lan                 2   6    37    32    -88us[  -87us] +/-  572us

So it looks like I’ll be able to free up a RPi from NTP duties and put everything on this 1 PC before it goes into a permanent location.


Yeah it works!!! :+1: :ok_hand: :rofl:

Looks like Ubuntu supports PPS on CTS pin.

root@ntp:/etc# ppscheck /dev/ttyS0
# Seconds  nanoSecs   Signals
 1710696415.000841843 TIOCM_CTS
 1710696416.000753814 TIOCM_CTS
 1710696417.000927404 TIOCM_CTS
 1710696418.000787897 TIOCM_CTS
 1710696419.000748807 TIOCM_CTS
 1710696420.000927616 TIOCM_CTS
 1710696421.000814092 TIOCM_CTS
 1710696422.000749594 TIOCM_CTS
 1710696423.000845890 TIOCM_CTS

Normally DCD pin1 DB9 is used.

As CTS and RTS are used for handshaking on the protocol.

Ubuntu doesn’t support anything by default, they maybe use a kernel that has the PPS-module installed.

CTS is typical not the pin to use, sorry.

Well PPS on CTS is supported on FreeBSD

The following capture modes are available:
0x00 Capture disabled.
0x01 Capture pulses on the CTS line.
0x02 Capture pulses on the DCD line.

ppscheck shows the status changes of the serial control lines, not the PPS signal derived from them. Use ppstest on the PPS device created when attaching the line discipline to the serial device to see whether any kernel PPS signal is generated.

Yes, but Ubuntu is not BSD, but Linux, and BSD and Linux are different in this respect.

PPSWATCH is also a good one to see the pulses:

root@server:~# ppswatch /dev/pps0 
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
timestamp: 1710086567, sequence: 6687, offset:  100014959
timestamp: 1710776390, sequence: 6688, offset:  100048769
timestamp: 1710776390, sequence: 6688, offset:  100048769
timestamp: 1710776391, sequence: 6689, offset:  100001968

1 Like

Now I have a new issue. For some reason the OS dropped the PPS signal and wouldn’t reconnect. I had to reboot the PC to get the PPS signal back. Didn’t touch anything on the physical PC, serial port, or GPS, so it wasn’t a wire that came loose or something. ppstest didn’t find the PPS signal, and even running ldattach to force reconnect didn’t find a PPS signal. Looking at the GPS, it’s PPS LED was flashing just fine, and checking with cgps and gpsmon showed that there was a lock and enough satellites as well, so I have no idea why the OS dropped the pps and wouldn’t reconnect to it without a reboot. :face_with_diagonal_mouth:

Did you set the speed of the Garmin in the config-file, like I posted in the first post?

Is your Garmin updated with the latest firmware?

I don’t use Garmin. Way overpriced for the features/performance you get.

Needless to say, it was working fine for days, but I have changed some settings around in Chrony, so it’s possible its related to that, though the changes are just me switching to different reference clock settings to see which works best. None of those changes should affect gpsd. Could be the hardware too as the PC hardware I’m running this all on is close to a decade old, but with Linux, who knows. I’m walking back changes one by one to see if it stops dropping the PPS signal, but so far no luck.

Beware if you set stuff like dpoll -2 or so, it might poll too fast and give problems.
Also maxlockage can give troubles with very fast polling.

Could be the reason it stopped doing PPS.

Yoo bad you didn’t post the lines you are using.

Shouldn’t dpoll match the actual pulse rate of the pps source?

For most GPS receivers outputting a 1Hz PPS, that would be dpoll of 0?

dpoll isn’t needed at all for PPS/NMEA reference clocks. Chrony defaults internally to averaging those reference clocks to a 4 second average, regardless of how often the updates happen via interupt, as far as I understand it.

refclock SOCK /var/run/chrony.ttyS0.sock refid GPS precision 1e-9 prefer

That is what I am currently using to provide time to Chrony, as the SOCK reference clock combines to the NMEA data and PPS together.

refclock SHM 1 lock GPS refid PPS precision 1e-9 prefer
refclock SHM 0 refid GPS precision 1e-3 offset 0.001

That is another setting I have used, including substituting SHM 1 with the line below.

refclock PPS /dev/pps0 lock GPS refid PPS precision 1e-9 prefer

All work. All return proper time to Chrony and are accepted for time keeping in Chrony.

#* GPS 0 4 377 13 -10us[ -11us] +/- 2316ns

Since pretty much all the options I’ve tried work, I do not believe its Chrony or its settings fault. The PPS is dropped by the kernal at a random time, some hours after a reboot.

[    5.610316] pps_core: LinuxPPS API ver. 1 registered
[    5.610319] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <>
[    5.611958] pps_ldisc: PPS line discipline registered
[    5.612394] pps pps0: new PPS source serial0
[    5.612401] pps pps0: source "/dev/ttyS0" added

The last line that I will see is usually

[ 5.612401] pps pps0: source dropped

I’ve tried disconnecting the GPS PPS output, but that doesn’t result in PPS disconnect on the system.

I believe its a problem with ldattach and/or the hardware itself. Unfortunetly, all the information I find on ladattach is old, as it still refers to using it in rc.local or /dev/init (with no instruction on how to use them it in either case). There is some relevant information that I can use to further dig into the problem (killing the process before attempting to ldattach again), and I have been able to ladttach after the drop, with a pps1 now showing up and having the PPS signal on it, but that does no good as gpsd is setup in the config with pps0, not pps1. Plus, I shouldn’t need to reset the PPS manually anyway…