GPS PPS signal corresponds to data time?

I have not used the Adafruit GPS, but GPS units almost always output the time after the PPS signal has been sent. They do this because the PPS signal is typically tied to the timing of the data stream coming from the satellite (or at least most GPSs have a mode where they are tied). In this case, the PPS is sent at exactly the moment the GPS satellite data stream says a UTC second starts. After that, they process the data, determine what time it actually was, and relay that data.

Some GPS have other modes where the PPS does not occur exactly at the top of a UTC second (which is helpful if you want to use the PPS signal before you have a GPS feed), but those that I have seen typically default to the PPS occurring at the top of the second.

If you need to know the time of the PPS, you need to latch an internal timer when the PPS signal occurs, then associate that with the data from the GPS when it comes in. Alternatively, keep track of the GPS data and, when the PPS is asserted, you can assume that it is now most_recent_gps_time_utc + 1 second.


I have a Dragino Lora/GPS Shield, which is based on the MT3339 chipset also used in the Adafruit Ultimate GPS Module. I did a couple of experiments with this shield in order to answer this very same questions. My conclusions are in line with the previous answers, namely:

  • The rising edge of the PPS signal is aligned with the start of a UTC second (this I already knew).
  • The time stated in an NMEA sentence is valid on the rising edge of the PPS pulse that immediately preceded that sentence.

Here is what I did:

  1. I captured both the PPS and the TX signals on a scope, as suggested in old_timer’s answer

scope trace

The yellow trace is the PPS signal. It's high for about 100 ms every second. The cyan trace is TX. This trace shows the serial data is sent in bursts, with each burst starting shortly after the falling edge of the PPS signal.

  1. I timed the serial stream on my computer

The hardware setup was:

amplified antenna → GPS module → Arduino Uno → laptop

The Arduino was used just as a serial/USB gateway (TX of GPS connected to TX of Arduino, which runs a “do nothing” program). The laptop was synchronised to within a few milliseconds of UTC via NTP. I used the following Node.js program for logging timestamped serial data:

const SerialPort = require("serialport");
var port = new SerialPort("/dev/ttyACM0", { baudRate: 9600 });

// Discard the first data chunk.
port.once("data", function() {

    // Log subsequent chunks.
    port.on("data", function(data) {
        console.log(new Date().toISOString().split(/[TZ]/)[1],
              JSON.stringify(String(data)));
    });
});

The output of the program looks like this (comments added):

20:16:44.810 "\n"     <-- end of burst
20:16:45.171 "$GP"    <-- start of burst, "GPRMC" sentence
20:16:45.175 "RMC,"   <-- 
20:16:45.179 "2016"   <-- UTC time: "201645.000",
20:16:45.183 "45.0"   <-- meaning 20:16:45.000 UTC
20:16:45.187 "00,A"   <-- 
...

where the first column is the UTC time, with millisecond resolution. This shows the program (or the serial port driver) is not fast enough to catch and timestamp individual characters, and there is some buffering going on. But it is still fast enough four our purposes. It also shows that the "GPRMC" sentence announcing the time 20:16:45.000 UTC was transmitted around 20:16:45.18, give or take a few tens of milliseconds. Note that the same announced time was repeated twice within the same burst: first in a GPGGA sentence transmitted around 20:16:45.30, then in a GPGLL sentence transmitted around 20:16:45.74.


There is no way to accurately output a message at a given time. The accuracy is given by the pulse, the message completes all the needed data (day, hours, minutes, etc.)

But the accurate time signal is the PPS signal itself

Tags:

Gps