Around 12 months ago I had a play with some u-blox NEO GNSS modules and had a proof of concept working using a Raspberry Pi and a 7M based module over TTL as a time source for an NTP server. I can’t recall the exact sites I was looking at when researching and messing about with them but most of them were similar to this one. It was a relatively straightforward way to get extremely accurate NTP from the GPS locked + PPS signals and serve the rest of the network at home.
A few days ago I pulled the 8M based module (RS232 NaviSys GM-8013R) out of the parts bin and connected it up in such a way that it was drawing +5V and GND from the a x86-64 PC’s USB port, and feeding the TX/RX/PPS (DCD) signals back through the same PC’s serial port (with no ground connected to the RS232 port). As a proof of concept it worked very well, and in the next day or two I’m intending to grab a few breakout DB9 and USB connectors to wire it up a bit more solidly and with an extended cable so I can place the antenna in a better position. Ultimately I’m intending to put the module in a weatherproof case outside, and run the cable back inside to connect to the USB and DB9 serial connectors of a server which will provide self hosted NTP.
I have very little electronics knowledge and was wondering if I’m going to run into issues if I power the module from an external USB supply or whether I should stick to drawing USB power from the same PC so that both connectors are referencing a common ground. I’m also wondering if I should be adding one or more fuses somewhere (whether or not I power it externally), or tying/not tying the grounds together.
Has anyone gone down the self hosted NTP route, or can provide some insight into the electronics side of what I’m doing? I don’t particularly want to have another machine (i.e., a Pi) doing just NTP when I can add it to an existing server, nor do I want to use a USB based GNSS module as their timing accuracy is poor. The USB power + RS232 signal approach seems too good to be true… what I have I missed?
Cheers,
Belfry
Update 26/2: I pondered it overnight and will add an optocoupler between the RS232 side, tie the RS232 signal ground to the supply ground, and power the whole lot from a 5V wall wart (with a fuse in line). Hopefully in a week or so after the goodies arrive and I have everything connected up, I can report back with the NTP accuracy stats. The Pi version last year was excellent, so I’m hoping for similar results with this more permanent implementation!
I unexpectedly had some free time this afternoon to tidy up my initial thought bubble and think it through a bit more thoroughly.
I’ve got 10m of two core cabling (+5V and GND) and 10m of four core cabling (TX/RX for GPS data, PPS pulse tied to the DCD pin, and GND - currently not connected as it’s the same as the USB ground) running to the unit. The power and signal grounds are tied together at the GNSS module end (a horribly fiddly JST connector), and the power cables and signal cables break off separately so I have the option to power via a separate PSU (probably USB wall wart or repurposed plug pack from something else) and run the signal cables in a different direction to the rest of my homelab gear. The lone white cable to the top is power on/off and comes out to a jumper on its own in case I need it at some stage, but it’s otherwise not used. It’s not connected as the NaviSys datasheet says I can leave it floating, and I have no need to remotely turn the module on or off.
It’s currently connected to a [sacrificial] Pentium 4, selected solely in case something went wrong with my wiring and the magic smoke came out! GNSS fix was virtually instantaneous, even indoors. I briefly had it plugged into a Windows 7 machine to run the u-blox software and get some diagnostic data out which showed it was quite happily seeing both GPS and GLONASS satellites from a poor location indoors. The software side was very simple and here’s a very rough sequence of steps to retrace my steps, rather than a full and comprehensive step by step instruction set:
install gpsd gpsd-clients pps-tools chrony
cat /dev/ttyS0 (to check I was getting GPS NMEA data)
edit /etc/default/gpsd to add DEVICES=“dev/ttyS0” and GPSD_OPTIONS=“-n” (because we want gpsd to immediately start and not wait for a client to connect)
restart gpsd service
cgps (to check GPS data was coming in via gpsd and that the GPS had a fix)
ppscheck /dev/ttyS0 (to see if the PPS data was being sent/detected by gpsd)
edit /etc/chrony/chrony.conf to add “refclock SHM 0 refid GPS” and “refclock SOCK /var/run/ttyS0.sock refid PPS” lines (add GPS and PPS sources to chrony)
restart chrony service
restart gpsd service
It looks as if I may need to fiddle with the GPS offset to bring it back into tolerance, but the PPS reference is incredibly accurate straight out of the gate. It’s interesting to see the difference in the random public NTP servers chronyd is referencing vs. GPS vs. PPS sources (note the units of measurements, milliseconds vs. microseconds, vs nanoseconds).
Will refine the hardware side of things over the coming weeks as I have time to come back to it and after my optocoupler arrives. Straight out of the gate 0.000000002 seconds slow and being down to nanosecond level measurements is pretty accurate in my mind!
What you’re doing is very impressive and way beyond me too @Belfry .
For perspective, i recently set up a Home Assistant Glow to log household power consumption. To supply it with power i bought a USB power bank from Myer, and a solar blanket from BCF.
So, suuuper consumer end of the spectrum over here.
Could you run NTP in a container on your home network? How inaccurate would that be? As a protocol, it’s perpetually correcting it’s time in relation to it’s upstream authority isn’t it?
Unrelated - but whoa, thank you for the top tip on the Glow. At a glance that unit may solve a very real problem I have - I currently have a slightly janky method of pulling data from the solar inverter and its integrated energy meter to feed into the HA energy dashboard. Solar data works great, but the consumption data never has worked reliably via any interface I’ve tried. This data is the final piece of the puzzle to use the “excess” solar to turn heating/cooling and other appliances on/off based on presence, environmental variables, and energy use, so I will definitely go down this rabbit hole, thank you!
I’m still learning about all of this, but my limited understanding is that at this sort of level even running it in a VM can cause timing problems. Additionally, the general consensus is to avoid USB because the latency and jitter introduced by USB polling are enough to make things less accurate than just using a public NTP server. I’m doing a new build (well, new to me - second hand parts) 1U Proxmox server to replace a few odds and ends like Pis and other low end computers running for services such as Home Assistant and SearXNG. I really wanted to stick with RS232 and PPS specifically as that’s really the “gold standard”. I’m hoping that the new Proxmox server will be able to reliably run a basic high priority VM with nothing other than GPSD+chrony on it and RS232 hardware passed through Proxmox for the PPS signal. I’m still waiting for the RAM for the new machine (and waiting for the optocoupler so I don’t accidentally fry the new machine) and then I’ll replicate the same setup with RS232 passthrough and maxed out CPU Units (priority) in Proxmox. If that doesn’t work well, I might use one of the newly retired smaller machines for my first foray into an RTOS and play with the time stuff that way.
As an aside, after my post I set DHCP option 42 in the router and can see chrony’s status listing all the clients on my LAN using the new locally hosted PPS NTP time source, which is quite neat.
I have a decades old external GPS sensor which has a magnetic base and USB. It was made for use in automobiles where it sticks on the magnetic roofs.
I used to use it in a Robinson R22 helicopter with a laptop to plot WiFi apps on a Google Map from the air flying around Lismore to Ballina with one of my 12dB panel antennas screwed to the base of the craft.
This way I could see which house had a WiFi AP and which didn’t.
Ahh the old WiFi war flying days, the stories I have!
Anyway … while following your thread I had my misgivings about the superiority of serial comms vs USB as I know both fairly well having engineered them in my embedded designs.
Because this is the modern age where we have running water, fire and AI everywhere I’ve used one of my tools to provide a more nuanced comment
tp@ubuntu:~$ ollama run --verbose qwen2.5-coder:32b
>>> does USB polling the external GPS sensor make a NTP server less accurate than using serial comms ?
The accuracy of an NTP (Network Time Protocol) server can indeed be
influenced by how it receives time data from an external GPS sensor, but
whether USB polling is inherently less accurate than using serial
communications depends on several factors.
### Factors to Consider:
1. **Latency:**
- **USB Polling:** When a GPS sensor is polled over USB, there might
be some latency introduced due to the polling interval and the time taken
for data transfer from the USB device to the host system.
- **Serial Communications:** Serial communication can often have less
overhead compared to USB in terms of setup and data transfer. However,
this also depends on the specific implementation and baud rate used.
2. **Polling Interval:**
- If the polling interval is too long (e.g., every second), it could
introduce a noticeable delay in updating the time from the GPS sensor.
- Serial communication can be configured to send data continuously or
at a very short polling interval, which might reduce this latency.
3. **Data Transfer Overhead:**
- USB can handle high data transfer rates and is generally robust.
However, it requires drivers and possibly additional system resources for
handling the USB protocol.
- Serial communications involve less overhead but are typically slower
than USB unless using a very high baud rate.
4. **System Load and Real-Time Processing:**
- The overall performance of the NTP server can be affected by how
well the host system handles time-critical tasks. If the system is
heavily loaded, handling USB communication might introduce more delays
compared to serial communication.
5. **Protocol Overhead:**
- Both methods involve some protocol overhead for data encapsulation
and transmission. The specifics of this overhead depend on the protocols
used (e.g., NMEA over serial vs. a custom or existing protocol over USB).
### Practical Considerations:
- **Stability:** Serial communication might be simpler in some cases,
which can lead to more stable performance.
- **Ease of Implementation:** USB is often easier to set up and manage,
especially on modern systems with good driver support.
### Conclusion:
In general, using serial communications could potentially offer lower
latency and overhead compared to USB polling, but the actual impact on
NTP accuracy would depend on the specific setup and configuration. If the
USB polling interval is short enough and the system can handle the USB
data efficiently, there might not be a significant difference in accuracy
between the two methods.
If high precision is critical, it's often best to benchmark both setups
in your specific environment to determine which method provides the most
accurate timekeeping for your NTP server.
My optocoupler arrived this morning, but unfortunately it didn’t pass through all the pins, and one of the ones it didn’t support was the PPS pin I really needed!
I bit the bullet and hooked the cabling up to the new Proxmox server in the same configuration as the test P4 machine. The Proxmox server is running a single VM (Debian 12) with the serial port passed through and a dedicated NIC passed through via IOMMU (Using this guide).
After a ton of fiddling with configs on both the host and VM, I can’t get close to the same outcome via a VM as I had on my test setup. We’re talking microseconds (millionths of a second) via a VM versus nanoseconds (billionths of a second) on the bare metal P4. It’s still very good - compare with milliseconds via NTP (thousands of a second) - but this does demonstrate just how sensitive to latency things are when down this far in the weeds!
I’ll continue to have a play and possibly move it to an LXC container later today to see how the latency compares with a full VM. I suspect that I’m going to have to move the GNSS sensor back to bare metal hardware if I want to keep that nanosecond level of precision.
That’s amazing! I was quite impressed about 20 years ago when I saw someone “warstanding” with a 24dBi grid pack antenna on top of a hill and panning it across the city. You definitely win with “warflying”
I could get time synchronised within approximately ±8000ns using an LXC container, compared to tens to hundreds of microseconds on a VM. For the sake of comparison I installed gpsd/pps etc. directly within the Proxmox shell and configured chrony to use those sources, and had similar results to the bare metal P4 setup yesterday. The overhead being introduced by LXC or running in a VM was too much to overcome, despite me giving it the best chance of success (setserial low_latency to prioritise interrupts, hardware passthroughs, maxing out cpu governors etc.). Hardware for all tests was a Xeon E3-1220v2, 8GB RAM, 4x 256GB SSDs in a RAID10 ZFS pool.
Interesting results and fun to have a play with for a few hours, but I’ll have to ponder the way forward from here. Perhaps it’ll all go back into the parts bin, perhaps I’ll repurpose something else (e.g., an older embedded system) to do dedicated NTP, or perhaps I’ll tinker some more and try to reduce the latency but I suspect there’s not much more that can be done to reduce millionths of a second down to billionths of a second!
It sounds like you have exhauted all the possiblities, Belfry, but I did wonder if the linux kernel you were running under Debian was 6.12 or later which was when the PREEMPT_RT was added to make Linux a RTOS. You do still need to install linux-image-rt-amd64 to get there however.
Great suggestion! I know Proxmox can be really fussy about kernels, ships its own version of the kernel, and explicitly tells you not to use the Debian ones. I’ll see if I can shoehorn the rt one > 6.12 onto there (and upset Proxmox) to give it a go before I reinstall the machine and put it into production.
Edit: Looks like that’s a bit of a non-starter unless I go down the route of compiling it myself. Consensus on the Proxmox forums is not to use anything but the pve kernels, that among the issues I’ll have is that it will break ZFS (so I’m going to have to reinstall the machine anyway), and the latest Proxmox kernel in testing as of today is 6.11. I haven’t got the time to sink into compiling a kernel now but if an opt in package for 6.12 pops up in the next few weeks before I have to set the machine up properly, I’ll give it a go. Thanks for the idea!
Circling back to this one with an update. About a week ago I got finally got the new (second hand) Proxmox server properly set up in the rack at home and started gradually virtualising a few Raspberry Pi and “Pi like” devices onto the machine. One of my goals with this server was to optimise for low power (as in electricity, not MHz) and optimise for low temperature as it gets quite toasty in that part of the house during summer. As part of this I’ve swapped the four core E3-1220v2 (base 3.1GHz, 69W TDP) with a two core E3-1220Lv2 (2.3GHz, 17W TDP) and pegged it to the powersave cpu_governor.
I had some issues after moving an ADS-B receiver over to a VM a few days ago due to MLAT being out of sync. No doubt the VM latency and the host’s lower power optimisations have partially contributed to this. As multilateration is quite timing sensitive, it sent me back down the documentation + forum reading rabbit hole of trying to optimise latency sensitive workloads on Proxmox (e.g., IOMMU, passing through devices vs. passing through entire controllers, prioritising workloads with cpuunits, “Use tablet for pointer = no”). I didn’t end up mucking around with the kernel in the end and am using the default kernel that comes with Proxmox VE 8.4.1 (6.8.12-9-pve). Of course, once I got MLAT on the ADS-B feeder working and stable, the next logical step was to get the GPS+PPS module rigged up again and see how it performed.
On top of the above optimisations, I used setserial low_latency on the Proxmox host and my time server VM (Debian 12 with nothing but gpsd, chronyd, and setserial added), lowered the RS232 baud rate to 9600, gave it 5000 cpuunits, and set the affinity to a single core. Highly likely that all of those things were unnecessary, but I’m happy to report that the timing has stabilised at <1µs based on the PPS source and is often around ±100ns. It’s not quite “bare metal” accuracy, but far more than I would ever need for home! The wiring definitely needs a clean up and I’ll have to mount the module into a box as well as solder proper connectors on to the RS232 and USB cables. The module quite happily got a GPS fix inside the garage underneath a two story house so I’ll be mounting it inside somewhere rather than worrying about weatherproofing.
I’ll keep an eye on it for a few weeks while I’m setting up the rest of the VMs, and if it’s stable will roll it out as a DHCP option for local NTP across my network. Once the last of the VMs are set up and the wiring is tidied up, I might experiment with the cpu affinity etc. to try and determine which of those variables has the biggest impact and whether they were all necessary after all.
Playing around with the GNSS module for precision timing wasn’t really related - although having a good local time source certainly won’t hurt!
Flight tracking / feeding (pushing data to FlightRadar24, FlightAware, AirNav Radar, etc.) is actually quite simple overall and one could get started with nothing more than a cheap TV tuner. I got into it seriously a little over five years ago and it’s now become more of a jumping off point into other projects and experimentation. For example, testing low powered/embedded systems (and having a known workload to throw onto the machines), setting up multiple geographically diverse sites (and networking them together with tunneling/routing/firewalling considerations that go with that), trying out different gain settings/antennas/cables/filters (and seeing how the reception range compares). I find it easier to learn about some new tech if there’s a specific goal I’m trying to achieve at the end of it.
Getting quite off topic from the time stuff, but I am happy to discuss it further in another thread or at a meeting if there’s interest. It really is simple to get started though, and FlightAware have some great instructions and an Australia centric shopping list here.