So there is another post in the community forum that is almost identical to this one, but that post simply didn’t go anywhere. I debated about adding to that older post or creating a new topic. Obviously, I opted for starting a new topic. I hope this was the correct choice in this situation.
So my basic question is this: I have a SparkFun GPS Breakout - NEO-M9N, SMA that is locked on and has a clean GNSS fix. The Blue PPS LED is blinking away as expected. Is there any way to provide this 1PPS signal to the USB-C port such that Linux/FreeBSD can read and use this 1PPS signal to discipline the GNSS time source?
The issue I have currently is the machine I need to tie this all into doesn’t have a native RS-232 (UART), so the only way of adding one would be through a USB to Serial adapter / Cable. This means even if I pull the 1PPS signal off the SparkFun board via the breakout pins, I would have to inject it over a Serial to USB device, thus losing the native analog accuracy of the RS-232 anyway. I might as well try and find a solution to pull the signal out of the USB-C connector already attached between the host and the NEO-M9N.
Any thoughts or help would be appreciated. I also have a RedBoard Plus that I picked up to see if that would be better for accessing the UBlox UART / 1PPS signal, but so far, I’ve not hooked that up or used it for anything yet.
P.S. I am very new to Arduino and SparkFun boards / Ublox GPS modules but have a strong Unix/Linux background, electronics, and tinkering.
On RS232 one could push the 1PPS onto one of the “spare” pins, like DCD or DTR, and then the driver for the UART on the host could pick that out of the register for NTP alignment purposes.
The uBlox USB doesn’t pass this data.
One could perhaps use an FTDI or SiLab USB-to-CMOS Serial with full modem type signalling, and wire to the DCD or RING pins there, and read that from the host, but there’s a lot of interaction there given USB has a single half-duplex connection, and transactions into the 10’s of milli-seconds. The USB supporting a message relating to “Receive Modem Line and Error State changes”
One something like a RPi, you can get GNSS Hat’s that can physically connect to the MPU’s GPIO’s, and presumably generate an interrupt.
… can read and use this 1PPS signal to discipline the GNSS time source?
That honestly seems entirely backward, you’re trying to discipline the computer’s time bases, either the RTC, or synchronous clock for the MCU
The other method of time-transfer is to use EXTINT / TIMEMARK / EVENTIN to get the GNSS to time-stamp a signal that the MCU generates, and you can check the pacing of that within the receiver’s time-line
I have done some experimenting with PPS over a USB UART chip. The pin traditionally used on a an RS232 port is DCD, and there are a number of USB UART chips that expose this pin. gpsd, for example, will pick this up automatically if a PPS pulse is being sent to it, and pass it along to pps0 (or whichever) which can then be used in chrony or ntpsec.
While this will technically work for timekeeping purposes, don’t expect much performance out of it. The jitter and inconsistent latency of USB results in a pretty unstable clock, in my experience it consistently performed worse than the NTP pool. It will probably perform a little bit better than working through gpsd for the time string sent as NMEA or ubx, but not much.
Thank you for the reply, this is good information. I plan on taking your advice and looking into the USB to CMOS Serial adapter to just see what kind of precision I can achieve with this. A little experimentation is all it should take to see if this might yield acceptable results or not. If it doesn’t, I’m no worse off.
So in terms of my statement: “can I read and use this 1PPS signal to discipline the GNSS time source?”
I thought this would be a correct way to describe this setup. As I understand it, the 1PPS signal simply provides an accurate measurement of the length of a second. However, this alone is not all that is needed. You also have to know exactly what “time” it is. With both of these pieces of information, you can both know what time it is and how to maintain that exact time by tracking the precise length of a second. This will minimize drift from that precise time calculation.
However, this is of course the most basic of explanations, and I have a lot more to learn and understand. Though I am doing this for a project at work, and at some point, I have to trust the software and hardware will all function the way it’s supposed to. I need to learn enough to set it up and to evaluate its working the way it’s supposed to with enough precision to meet the customer’s requirements. Unfortunately, there is simply too much here to learn to become an expert for the purposes of this project.
The time-nuts mailing list is a good resource for this topic, the chrony mailing list is as well.
One note about the 1PPS signal: it doesn’t define the length of a second, only the start of a second. The length of a second is tracked by your system’s local oscillator, and doesn’t need to be tremendously accurate, because there should always be another timepulse marking the start of the next second. Ultimately, this is why you want the timepulse to be coming in on an interface that is an interrupt. Interrupt inputs inform the system at a very low level that something has happened, providing less opportunity for jitter and latency to from from the system itself. If the interrupt comes from USB, it can’t be trusted in the same way.
The rest of your understanding is correct: the GNSS receiver provides the calendar date and “wall clock” time that is matched with the timepulse.
One thing to watch out for is that the NEO-M9N NMEA GGA + RMC messages, plus the UBX binary UBX-NAV-PVT and UBX-NAV-CLOCK messages, give you the time of the previous PPS pulse. For the time of the next PPS pulse, you need the UBX-TIM-TP (Time Pulse Time Data) message.
I do appreciate your response, and it certainly helps to answer what I was asking.
I read through the Kloppenborg site, and it provided a lot of great details. I set up a Raspberry Pi 4 last night connecting the NEO-M9N and can confirm there is no 1PPS signal natively on the USB output just as you and @clive1 suggested. I took the 1PPS signal and connected it to the GPIO 18 pin and everything worked great.
This of course all works because I have someplace to send the 1PPS signal that can be picked up by the Raspberry Pi. If I could use a Raspberry Pi on this project I would be done and moving on to the rest of this project. I really wish the end client would have allowed for more research into the device that was going to be used for the host machine on this project. We could have used a server that has GPIO or a native UART and be done with this part of the project.
I just read your other update, and thank you again your description helps. The details are extremely important here, and understanding the 1PPS signal is for the purpose of designating the start of a second and not the length is a very important distinction.
This is another one of those instances that points out why something has been designed and implemented a particular way (e.g. using Serial or RS232 as a posed to digital in the USB stream). Simply moving this from an RS232s analog signal to a digital stream isn’t the correct approach for all of the reasons you and @clive1 have pointed out. RS232 over USB is a great solution but we have to recognize its limitations where they exist.
Now I just have to figure out how to bring this signal into this machine without a native UART.
Interesting, so this is something else I didn’t realize.
Do you know if NTP has the ability to preference one over the other or is this a case where I should limit the sentences that are available to NTP? I will need to read about this and I greatly appreciate the heads up.
If you’re using something like gpsd to do the clock syncing, then (I assume) it knows that the NMEA data is arriving ‘late’ and compensates. But if you’re doing the syncing manually, then this is stuff you need to be aware of. For NMEA and/or UBX-NAV-PVT, you need to add 1 second when you sync on the next top-of-second pulse edge. UBX-TIM-TP has the second included, but the time is provided as Time-Of-Week plus week number, not hours-minutes-seconds…
In the context you’re describing the GNSS is disciplining YOU, the GNSS receiver is disciplining it’s 1PPS signal, both in frequency, and top-of-second alignment vs UTC/GPS.
As Paul points out UBX-TIM-TP on the uBlox parts is sent late to the message stream, and describes where the leading edge is going to fall in the immediate future. This is an estimate based on the receiver’s understanding of it’s local clock perfomance, and it’s resolution with regard to placement. The timing modules can also provide a pico-second estimate of how far this edge is from ideal it will be given say the synchronous clock it’s working from is 48 MHz (or whatever)
Yes, and I’d suppose this is why it’s not prevalent and won’t be. Even with some QoS hacks I don’t think USB is going to be the equivalent of a wired RS232-UART on a PC. A GPS mounted to a RPi could at least get the 1PPS to a GPIO and resolve that. For MCU like an STM32 you can free run timers, and latch counts via an external pulse, depending of the frequencies getting deep sub-microsecond should be possible.