I currently have an Adafruit Ultimate GPS connected to an Arduino that outputing GPS data (nmea sentences) once per second. There is also a pin on the GPS outputting 1 PPS signal.

My question is whether the pulse of the PPS suppose to match the time that the GPS data is coming in i.e are they are coming in at the same time?

Also does PPS pulse come in at the beginning of a UTC second or is it random and simply once a second?

  • \$\begingroup\$ I have one of these and I believe the PPS signal is pulled high at the start of each UTC second. The 10Hz maximum update rate would mean that only some of the sentences can occur at the same time as the PPS signal, but each sentence contains the UTC time, so you could check. I'll look for my module and make an answer when I can say for sure. \$\endgroup\$
    – Alex
    Commented Aug 25, 2016 at 20:49
  • \$\begingroup\$ @Alex Ok let me know what you find out please! \$\endgroup\$
    – Lightsout
    Commented Aug 25, 2016 at 20:59
  • \$\begingroup\$ You should be able to sync data out with PPS pulse and then compute processing latency of the UART. THe Raw PPS pulse is enabled when a fix is locked with an algorithm to compensate for range (altitude & azimuth) but not variations in ionosphere delays. I believe +/-10us is possible. \$\endgroup\$ Commented Aug 25, 2016 at 21:04
  • \$\begingroup\$ This should be in the gps receivers documentation also find out if it is the rising edge or falling edge of the pulse that you care about for that receiver, some you can change the width of the pulse, etc. \$\endgroup\$
    – old_timer
    Commented Aug 26, 2016 at 0:05
  • \$\begingroup\$ Okay I see the documentation is not good, no answers there. \$\endgroup\$
    – old_timer
    Commented Aug 26, 2016 at 0:08

6 Answers 6


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.

  • 1
    \$\begingroup\$ In contrast, Trimble explicitly states that in one of their systems the serial information precedes (vs follows) the pulse to which it applies: trimble.com/OEM_ReceiverHelp/V4.44/en/… \$\endgroup\$ Commented Oct 2, 2020 at 19:17
  • \$\begingroup\$ It's important to keep in mind that a GPS receiver isn't actually giving you time information from the satellites but rather is giving you information from its own internal clock/position estimate which is disciplined by the satellites. \$\endgroup\$ Commented Oct 2, 2020 at 19:19
  • \$\begingroup\$ This is backwards from the default configuration of every Trimble, UBlox, or ST GNSS receiver I've used. The time is sent in a serial message like NMEA or UBX and then that time is effective on the PPS pulse. Certainly all these receivers are extremely configurable, but the defaults I've observed are this way. \$\endgroup\$
    – 2bluesc
    Commented Aug 30, 2023 at 18:27

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],

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


As far as I can tell, the PPS pin is pulled high for 100 milliseconds at the start of each UTC second (assuming GPS lock). By default, the GPS outputs position information at 1Hz, and the time given in the NMEA sentences indicates that they also are specified at the start of each UTC second.

The serial data is not sent at the exact instant the PPS pin goes high, but you need to wait a few milliseconds to get the full set of NMEA sentences anyway. Using the default sentence settings and baud rate, I got an average of 348 bytes/s, which with a baud rate of 9600 (9600 bits/second) would take 290 milliseconds to send. So, as Cort says, each rising edge of the PPS pin occurs at "most_recent_gps_time_utc + 1 second".

The GPS gathers satellite data while sending a PPS pulse at UTC second X. It does the necessary calculations, then outputs the NMEA sentences for the position at second X, therefore the GPS data for second X is always received a few hundred milliseconds after the PPS pulse for second X.


The manual for the receiver used on that Adafruit board is pretty bad. I randomly selected a trimble based one on sparkfun and at least for that module it was a bit better. first and foremost for the trimble one you select positive edge or negative edge, so you need to know from the one you are using which edge is the correct edge (if it is a short pulse, not a 50% duty cycle, from a scope it is hopefully obvious the leading edge of the short pulse is likely the edge you want).

The only other clue we get from the trimble manual (again not the one you have is):

Once time is acquired, on the next PPS add 1 to the whole second to read the correct time.

Which for that unit means the time you get from the nmea string and then on the next pulse you add one second. I would not assume that this is true for all of them but it makes sense. It implies that for this one the pulse is related to the string that is coming out or about to. by then it is too late of course.


Of course no reason why you couldnt have found this information yourself, another brand unit says that Each message is output within a few hundred ms after the 1PPS pulse is output and tells the time of the pulse that just occurred. So basically the same as the trimble add one second to the time you just read when you get a pulse. This other brand is a rising edge doesnt sound like you have control over that.

You also need to understand how your signal is recived by hardware, for example if they are using an optoisolator or some other form of isolation it may invert the signal so it may go out the receiver one way but enter your chip the other. With your arduino it is hardwired no isolation you get what you get.

A scope should make all of this obvious, put both the serial tx and the 1pps on the scope ideally you see the 1pps leading edge and then after that see the burst of serial messages. That one picture should tell the whole story.


My small contribution here. To double check this, I wrote a bit of code (available here: https://github.com/jerabaul29/interrupt_GPS_synchronization/tree/master/PPS_clock_signal ) that basically:

  • measures the time (micros) when PPS rises with an interrupt pin
  • dump all GPS NMEA sentences as they arrive together with corresponding receiving time (micros again)
  • measures the time (micro again) when 'new second' messages arrive from the computer.

The results are following, and correspond to what the other answers have been describing:

2020-04-08 11:46:39.000017
interrupt pin 2 triggered 2717740 elapsed 999792
2020-04-08 11:46:39.007220
interrupt pin 3 triggered 2720380 elapsed 999796
2020-04-08 11:46:39.011312
delay 2 to 3 is 2640
2020-04-08 11:46:39.014655
2020-04-08 11:46:39.477875
micros = 3195544
2020-04-08 11:46:39.478235
2020-04-08 11:46:39.555399
micros = 3271192
2020-04-08 11:46:39.555585
start new second

This is one more hint that, similar to what the other answers suggest:

  • first the pin 2 (in my case, PPS) rises
  • then very soon after the pin 3 (driven by another board that follows the 'new second' message from the computer) rises
  • then, the NMEA sentences arrive.

This is one more hint that for each given second, one first observes the rising PPS, and then after a while (due to processing / finite serial speed) the NMEA sentences for this UTC second are received.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.