Get more stability at no costs

No.

As someone else said elsewhere recently, “he obviously isn’t even bothering to take anything I’ve stated into consideration.”

No, because as I said multiple times now, SHM1 coming from gpsd combines PPS and serial stream into one, so no need for chronyd (or ntpd for that matter) to do that a second time on top of what gpsd already did (unless one does not trust gpsd to do it right…).

Repeating myself: No, not with SHM1, as gpsd already did that, and is providing the combined result with SHM1.

Yes, it does.

Not sure anymore where I got it originally a long, long time ago, some documentation, looking at the code, … Certainly long experience doing it that way.

But interesting that you aren’t even just willing to give it a try, make a new experience, just reject it outright…

Not repeating myself for the nth time on the further statements in your post.

Well, chronyd docs are chronyd docs, not gpsd docs.

I am stopping here, though, because this discussion is going nowhere, see the quote above.

Where? As GPSD pages state it doesn’t.
Where does it do that?

Nobody states that, not even the GPSD pages, not the Chrony pages…except you.

I do know that you can rely on PPS when your clock is ok. But it has to be good.
When other sources give time. Then Chrony can work it out.

So why does Chrony offer LOCK when it’s not needed.

I want to know. Yet you explain nothing, only claim a lot. Please show it, I want to learn.

Reading all this I have a couple of things to add from the peanut gallery…

My understanding is that on Linux ldattach would only be used when using PPS on GPIO, if PPS is on your DCD pin then gpsd will pick it up. Its worked that way for me (second half of my post here):

In FreeBSD, gpsd will pick up PPS on either the DCD pin (by default) or the CTS pin (if specified). Again, works for me as documented here:

I think the reference to “receivers with a loose/sloppy timing between PPS and serial data” is a reference to the Garmin 18x LVC:

As far as needing only one or two SHMs when using PPS and gpsd - the way I have read the documentation is the same as @Bas, but I haven’t done any testing because the preferred method is SOCK and I have been able to get that to work in both Linux and FreeBSD.

This is how I interpret these statistics:
The Garmin 18x PPS does not have an accuracy of 1ns.
Clock RMS offset is 1046 ns
Clock last offset was 432 ns
Garmin’s Std Dev of the pps measurements is 12000 ns (12 us) - this is very noisy, in my opinion PPS through a COM port should achieve 1000 ns (1 us) stddev

But this is my reference point with its own quicks I’m trying to sort out:

Attaching a line discipline (of which there are others besides PPS) only applies to serial devices. As such, ldattach will refuse to operate on PPS devices because they don’t have the properties needed for attaching a line discipline.

Yes, and to do so in “kernel mode”, it will attach the PPS kernel discipline to the port.

Yes. For kernel PPS, gpsd will defer to the PPS functionality provided by the kernel via the PPS API. I.e., whatever pin the kernel will accept the PPS signal on is what gpsd will use, without even “knowing” what pin has been used. As discussed elsewhere in this forum, Linux device drivers typically only use DCD out of the box, while BSD can use another pin as well, and its configurable in that respect (as far as I understood/remember - I don’t have own first-hand experience, though, to confirm myself).

In user-mode PPS, gpsd itself will also accept some other pins besides DCD, I think CTS as well, plus at least RI.

The curious thing to me is to see how vigourously he defends his firmly set view based on typically notoriously badly maintained documentation, and his own interpretation of it, rather than just doing the simple and quick test I suggested to definitely settle the matter based on gpsd’s actual behavior, rather than some possibly incomplete, outdated, perhaps even wrong documentation, and anyone’s individual interpretation of that documentation. I never asked to believe me or my claims just as such, but suggested a way for anyone actually interested in understanding this matter to easily see the actual behavior for themselves.

1 Like

Without reconfiguring chronyd, one could also just take a look at the output of the ntpshmom tool that ships with gpsd. Among some other information, the main feature is to carry the system time at which an event was seen, e.g., PPS pulse or serial message, and potentially the time that gpsd assumes to be the time the event was supposed to happen. E.g., the implicit assumption with PPS is that it refers to the top of the second, though without context, it is unclear which second it refers to (the part about “numbering the seconds”).

I.e., if SHM1 were to carry the PPS information only, one of those timestamps should be missing in the shared memory segment.

However, both are filled, and apart from the numbers being slightly different between them, there is no difference in the amount of info that gpsd shares in the two memory segments (two timestamps, plus some other info).

But how can there be no difference if one of the two shared memory segments were to carry less information than the other?

Btw, as gpsd always fills the shared memory segments, even when chronyd picks up the data via pipe, one can see the above in action even when the shared memory segments are not actually used.

$ sudo ntpshmmon -o
ntpshmmon: version 3.24.1~dev
#      Name     Offset            Clock                 Real                 L Prc
sample NTP0          0.260461043  1764919374.260155485  1764919373.999694442 0 -20
sample NTP1          0.000385616  1764919375.000385616  1764919375.000000000 0 -10
sample NTP0          0.211922346  1764919375.211616971  1764919374.999694625 0 -20
sample NTP1          0.001359135  1764919376.001359135  1764919376.000000000 0 -10
sample NTP0          0.244132322  1764919376.243827130  1764919375.999694808 0 -20
sample NTP1          0.001098283  1764919377.001098283  1764919377.000000000 0 -10
sample NTP0          0.227135941  1764919377.226830932  1764919376.999694991 0 -20
^C

EDIT: Just to be clear: My statements about gpsd combining PPS and serial data for SHM1 apply when gpsd itself picks up those pieces from the same serial port. When the PPS signal is separate from the serial port, e.g., when a PPS device is explicitly passed to gpsd, such combining in my understanding does not happen as gpsd cannot be sure about the relationship between the serial data and the PPS signal. Unlike when gpsd itself attaches the line discipline to the serial device and thus knows that the PPS signal relates to the serial data.

I have found a document that helps understanding PPS a bit better.
Also how accurate it can be, beware the most expensive receiver they used is well over 1500 euro second hand and it’s no longer in production.
But I can’t upload the document in here.

Google for: DOI 10.1007/s10291-014-0375-7

But it sheds light on how and when PPS pulses are send to the computer, funny, it even sends them without a satellite in sight.

Also this document shows high precission PPS.

There are many more of these type testing. Therefor I do believe it can be that low as a 10ns.
Or I do not understand what they test :rofl:

You are right, I removed the kernel module and the PPS port in GPSD and it nicely does it.
Thank you.

At the time I had many problems with the Garmin, as it runs at 9600 baud while I did not gave the baud parameter.
Today I do, but I never removed the kernel-module as it worked.

This means I have to test the 5Hz and U-blox all over again, without the kernel driver.
Oh well, keeps me off the streets.

What you probably mean is that you removed the manual/explicit loading of the module. However, as it is still needed for the PPS functionality, the kernel will automatically load it at the latest once gpsd tries to attach the PPS discipline to the serial port. So while it was not “wrong”/doesn’t hurt to manually load the module, it wasn’t needed, thus complicating the setup, and obfuscating what is really going on.

I have put it back in and it makes no difference.
Seems indeed that the kernel loads it when needed.

I just didn’t had to insert it in the gpsd.conf, as then it created a second pps1 doing the same as pps0

1 Like

https://www.researchgate.net/profile/Quan-Zhang-51/publication/271952715_Quality_evaluation_of_the_pulse_per_second_PPS_signals_from_commercial_GNSS_receivers/links/559bb50908aee2c16df0178a/Quality-evaluation-of-the-pulse-per-second-PPS-signals-from-commercial-GNSS-receivers.pdf

Yes, both N8UR’s report and the Chinese paper conclude that the PPS pin of the receiver can achieve 10 ns accuracy. I would expect that.

N8UR used a custom “multi-TICC" device with a HP 5071A cesium standard
The Wuhan engineers used “FPGA Board” device with a Microchip Technology Chip Scale Atomic Clock SA.45

In my experience that 10 ns accuracy is degraded between the receiver and the CPU.

Different paths have different levels of degradation…

PPS over USB is the worst “practical” path I’ve seen - its used as an example in the Ubuntu documentation - PPS is degraded over USB from 10 ns to 41000 ns std dev


(by the way - the above example shows how gpsd will automatically create the PPS, no need to create it twice)

GPSD with user level PPS is the next step change improvement, where the PPS degrades from 10 ns to 5000 ns

GPSD with kernel level PPS is the next improvement, where PPS degrades from 10 ns to 1000 ns

Following that my opinion is that hardware timestamping the PPS to synchronize a PHC, and using that PHC instead of SHM or SOCK would result in the PPS degrading from 10 ns to 100 ns.

Well I just tested the U-box and when running the default kernel without setserial and high priority.
The offset is 153ms on the GPS signal.

KPPS is always called by GPSD when you offer PPS on DCD and it does timestamping as far as I can see.

But after I install setserial and make it lowlatency, install the RT-kernel and set prio high…I’m amazed as the GPS signal is lowered in offset to 80ms, so almost chopped by 50%!

So switching kernels makes a lot difference on timing, as well as setserial.

And during install of Chrony and GPSd systemd is in error for GPSD, the line reads AFTER Chrony is started, this is wrong for SHM and you mus change it to BEFORE and rem the Reuires=gpsd.socket. Else the GPS won’t start after a reboot.

nano /lib/systemd/system/gpsd.service
[Unit]
Description=GPS (Global Positioning System) Daemon
#Requires=gpsd.socket
# Needed with chrony SOCK refclock
Before=chronyd.service

[Service]
CPUSchedulingPolicy=rr
CPUSchedulingPriority=40
IOSchedulingClass=realtime
Nice=-10
Type=forking
EnvironmentFile=-/etc/default/gpsd
ExecStart=/usr/sbin/gpsd $GPSD_OPTIONS $OPTIONS $DEVICES

[Install]
WantedBy=multi-user.target
Also=gpsd.socket

I got the U-blox RS-232 PPS down to offset about 2ns
But better then the Garmin, but then, it’s located on a different space.

It’s just for testing.

I let this run for an hour, then going to do the same with the Garmin 5Hz.

As for standard deviation, my indoor location isn’t good for that, but I did see 4000ns with the U-blox already, but also 40us, but we have a very clouded day totday.
So I don’t expect PPS too low at the moment.

1 Like

Here is the data of the u-blox RS-232 device…on a dedicated Chrony-only machine.

After this, I’m going to connect the Garmin 5Hz and see how it behaves on the same location, indoors, but still.

1 Like

When I personally evaluate the statistics, to me - offset alone is meaningless - relative offsets are a little more useful - RMS offset and std dev are more useful.

If you consider two devices
One with an offset of 0.005 ns and a std dev of 10,000,000 ns
Second with an offset of 10,000,000 ns and a std dev of 0.005 ns

The second device by far is superior - this is why Chrony provides the offset directive in the config file, and why ublox provides customizable configurations of both antenna and user delays.

I also see 500-5000 ns std dev on my LEA-M8Ts (indoor) - haven’t fully wrapped my head around why the large range, but I’m working on it - theory is its a combination of PC bus timing issues, antenna quality, and solving for time+position every second instead of just time.

Haven’t used the Garmin or Quescan/ublox ubx-m10050-kb pucks in a while, but believe me - I’m curious how they perform. Head-to-head comparison is planned. But its hard to do a comparison when identical devices aren’t behaving the same way…

Looks like you’ve got 6,208 ns of stddev on the ublox navigational puck - that looks as expected

The 2 second update interval seems very low to me - is that something you configured?

With refclocks in chrony I would expect a 16 second update interval

The RMS offset is just under 1,000 ns - I would expect that you can see this drop under 500 ns if your PC is stable and given enough runtime

Root dispersion is 49,468 ns - for a 2 second update interval this is very high - I would expect that changing the update interval from 2 seconds to 16 seconds, and letting the PC settle undisturbed for 12 hrs, you’ll start is see root dispersion between 10,000 and 20,000 ns - depending on when you take the snapshot within the 16 second interval

On the Garmin vs the ublox - it would be interesting to compare the TDOP values when installed in the same location - I would expect the ublox running in multi-constellation mode to have a lower/better TDOP, and better metrics in chrony - but it will also come down to the quality of the antenna as well - I know my Garmin puck is more hefty than the Quescan - and that could be because the Garmin has a better antenna…

This is what I’m seeing on the LEA-M8T with a puck antenna

The Garmin 5Hz is playing up again, won’t give data.
Had this before, have to check it.

The update of 2 seonds is quite simple, just set the poll to 1 for both SHM lines.

Don’t worry about root. It’s a very tiny CPU.

Without GPS, just via internet:

root@advantech:~# chronyc tracking
Reference ID    : C1BFD278 (mineco.fgov.be)
Stratum         : 2
Ref time (UTC)  : Fri Dec 05 16:51:51 2025
System time     : 0.000055030 seconds slow of NTP time
Last offset     : -0.000031851 seconds
RMS offset      : 0.000095537 seconds
Frequency       : 9.688 ppm slow
Residual freq   : -0.027 ppm
Skew            : 1.271 ppm
Root delay      : 0.009990483 seconds
Root dispersion : 0.000389490 seconds
Update interval : 32.2 seconds
Leap status     : Normal

The update interfall is set by the fastest-polling device, with GPS typical poll 1 or 2, depends on the GPS.
For SHM you can poll every 2 seconds.

The Garmin 1Hz on my normal timeserver…but in second I move the puck to same location as the u-blox

Edit: It was already in the best location…it got worse at the u-blox test location.

1 Like

Holy moly!

Man, this is great, seems you are right…as what you predicted happened.

I changed to the poll for GPS and PPS to 3 from 1.

The deviation dropped a lot, and as I type still dropping.

I presume this has to do with GPS buffers that fill but doesn’t need to be emptied that fast?

Beware I do not have clear-sky and the puck is inside behind a stone wall.

Why don’t the docs mention this? As so many say you need to poll faster for better accuracy.

Ouch!
The positional error in all 3 dimensions is +/- 72 meters!
TDOP is barely hanging on at 0.96

using 10 of 12 GPS birds is good
SBAS is off - not sure if that’s because the Garmin can’t see any of the WAAS birds on that side of the pond, or intentional - either way I think its good

Greetings JO21oc68!
73

Yeah I’m at 50m’s above sealevel.

Just checked, we have no WAAS in Europe.

73’s,

ON5HB :rofl:

1 Like

Amazing…

Yes this works, thank you so much!

1 Like

I’ve never used the 5Hz model - but you might want to double check you have the right baud rate, its different than the “regular” 18x LVC

At 5hz, if the baud rate is too low it cant spit all the sentences out fast enough

Might want to try without specifying a poll and see what Chrony automagically does

Optimal polling intervals are something I don’t fully understand. From reading nearly all of David Mill’s material I could get my hands on, all I can say is the optimal polling is determined by the allan variation/deviation/intercept - it’s a balance between short and long term noise and I think the concept/math is more frequency domain than time domain - which for me isn’t very intuitive

For example - when running the .20 NMEA driver with PPS in ntpd, it will dynamically change the polling interval, as stability increased, polling interval increased. In Chrony, I haven’t been able to figure out how to do that - it looks like you can’t, it’s a static polling interval. Why is this?!?!?

https://www.ntp.org/reflib/

Everything in there is good, some is repetitive - highlights just from “Confessions of an Internet Timekeeper”:


N8UR describes it this way:

A little bit of an understatement there - I could tell from the cgps readout
Your 2D error isn’t too bad, but the Alt error… that’s where you could use improvement
The way I understand it is not all SVs contribute equally to the position solution - in order to accurately solve for altitude, the SVs near the horizon have more of an influnce than the SVs directly overhead. So if the walls are Stone and either attenuate or reflect/multipath the signals, you’re not going to get a good altitude solution. Ideally you want your DOPs under 1 - and your TDOP is, but it can be improved even more by getting the VDOP under 1 if you can. - But this is where the Garmin is at a disadvantage - it’s antenna isn’t designed to be user serviceable.

By the way, 72m of 3D error equates to roughly 240 ns of inaccuracy (speed of light / distance)

I guess it depends on the docs and the authors. The optimal solution isn’t intuitive…

You’re welcome!