Sorry I don't really understand what you are asking.
I've never seen the 1PPS fail to pulse, nor have I seen it jitter. The timestamp messages don't always fall between the correct pulses, so I would expect, for example
1pps
10:00:00
1pps
10:00:01
1pps
10:00:02
1pps
Etc
But that's not what happens, sometimes the timestamps miss a pulse then happen between the next pair.
that's what I wanted to know. I just don't know what one could expect from these devices.
This GPS time thing has been bugging me. I've re-done the tests, but this time I've stripped out the other junk from the serial monitor prints. The serial monitor now only shows when the PPS signal goes low and the data from the GPS GPRMC sentence.
For most of the time it works as expected, as below:
16:20:25.160 -> PPS low
16:20:26.143 -> GPS data = $GPRMC,162025.000,
16:20:26.143 ->
16:20:26.143 -> PPS low
16:20:26.847 -> GPS data = $GPRMC,162026.000,
16:20:26.894 ->
16:20:27.177 -> PPS low
16:20:27.882 -> GPS data = $GPRMC,162027.000,
16:20:27.929 ->
16:20:27.929 ->
16:20:28.163 -> PPS low
16:20:28.869 -> GPS data = $GPRMC,162028.000,
16:20:28.869 ->
16:20:28.869 ->
16:20:29.152 -> PPS low
16:20:29.903 -> GPS data = $GPRMC,162029.000,
In case you are not familiar with the format the number immediately after $GPRMC, is the time, for example 162025 means 16:20:25. In the example above there is a PPS low followed by a GPRMC message containing the current time, which aligns with the serial monitor timestamp.
Occasionally this happens:
16:20:34.168 -> PPS low
16:20:34.872 -> GPS data = $GPRMC,162034.000,
16:20:34.918 ->
16:20:34.918 ->
16:20:35.152 -> PPS low
16:20:36.172 -> PPS low
16:20:36.218 -> Sync to GPS time
16:20:36.312 -> GPS data = $GPRMC,162035.000,
16:20:36.312 ->
16:20:36.312 ->
16:20:36.918 -> Sync to GPS time
16:20:37.012 -> GPS data = $GPRMC,162036.000,
16:20:37.012 ->
16:20:37.012 ->
16:20:37.152 -> PPS low
16:20:37.901 -> GPS data = $GPRMC,162037.000,
At 16:20:35 there is a PPS without a corresponding GPRMC sentence (which causes my local clock to sync because it now thinks it's one second ahead), then a PPS at 16:20:36 followed by the missing sentence from the previous second, which shows the time as 16:20:35 (which causes my clock to sync again, as my clock is now a second behind). At 16:20:37 there is the 16:20:36 sentence followed a bit later by the 16:20:37 sentence.
I'm now starting to wonder how I filter these out ![]()
Using 1PPS from GPS and time stamps from NTP just feels wrong!
Edit:
For search engines:
GPS receiver is GlobalTop FGPMMOPA6H
Problem GPRMC sentences sometime come late and contain the timestamp from the wrong second.
It's still strange though. Do you have any buffering of the incoming sentences going on? Or anything that could cause a delay in recognizing a sentence? It just seems really off the wall that there could be a delay in sending out the sentence of as much as a full second, but only occasionally. Well, maybe the receiver gets busy locking in on signals, or whatever, and just needs uninterrupted time to do that. It just seems better to skip a sentence than send it a second late.
Edit: I'd be happy to test this on my GPS module if you have software that will run on a Nano or Pro Mini.
The only thing I've not accounted for is the time taken to update the display, but I keep that to a minimum by only updating 1 tile each time around the loop function.
I'll write something for you. As you can see it's a custom board, there's a 4809 hiding under the display, the code is for that. Watch this space. Thank you.
Edit: what do you need? Simplest would be to output the RMC sentence to the serial monitor and also something for the 1PPS. You would have to watch it carefully to see the problem.
Edit:
Note to the spammer who created reply #66 while I was typing this reply: probably not you best attempt at spam, putting it in a topic created by a moderator ![]()
The closest I have to what you have is a Uno, which is pretty much the same as a Nano. Here is some test code for you to try:
#include <SoftwareSerial.h>
#define RXPIN 2
#define TXPIN 3
#define PPSPIN 4
#define LF 10
SoftwareSerial GPS_serial(RXPIN, TXPIN);
void setup() {
Serial.begin(115200);
GPS_serial.begin(9600);
pinMode(PPSPIN, INPUT);
}
void loop() {
rxGPSData();
//rx1PPS_H(); // Use this one if PPS is normally low and goes high for active
rx1PPS_L(); // Use this one if PPS is normally high and goes low for active
}
void rxGPSData() {
constexpr char GPRMC[] = {'G', 'P', 'R', 'M', 'C'}; // Check for RMC sentence and only.
static bool GPSDataisRMC = false;
static uint8_t GPSDataCount = 0;
char temp;
static char GPSDataBuffer[128];
static uint8_t GPSDataBufferIndex = 0;
if (GPS_serial.available() > 0) {
temp = GPS_serial.read();
if (temp == '$') {
GPSDataisRMC = true;
GPSDataCount = 0;
GPSDataBufferIndex = 0;
} else if(GPSDataisRMC && (GPSDataCount < 5)) {
if (temp == GPRMC[GPSDataCount]) {
++GPSDataCount;
} else {
GPSDataisRMC = false;
}
}
if (GPSDataisRMC) {
GPSDataBuffer[GPSDataBufferIndex] = temp;
++GPSDataBufferIndex;
if (GPSDataBufferIndex >= 128) {
GPSDataBufferIndex = 127;
GPSDataBuffer[GPSDataBufferIndex] = NULL;
}
if (temp == LF) {
Serial.print("GPS data = ");
Serial.println(GPSDataBuffer);
}
}
}
}
// PPS normally low, goes high for active
void rx1PPS_H() {
static bool PPSinLast = false;
bool PPSin = (bool)digitalRead(PPSPIN);
if(PPSin) {
if(!PPSinLast) {
PPSinLast = true;
Serial.println("PPS high");
}
} else {
PPSinLast = false;
}
}
// PPS normally high, goes low for active
void rx1PPS_L() {
static bool PPSinLast = false;
bool PPSin = (bool)digitalRead(PPSPIN);
if(!PPSin) {
if(!PPSinLast) {
PPSinLast = true;
Serial.println("PPS low");
}
} else {
PPSinLast = false;
}
}
I still get the same problem with this code, here is some of the output from the serial monitor:
10:32:58.905 -> PPS low
10:32:59.701 -> GPS data = $GPRMC,103259.000,
10:32:59.747 ->
10:32:59.886 -> PPS low
10:33:00.915 -> PPS low
10:33:00.915 -> GPS data = $GPRMC,103300.000,
10:33:00.962 ->
10:33:01.649 -> GPS data = $GPRMC,103301.000,
10:33:01.697 ->
10:33:01.884 -> PPS low
10:33:02.583 -> GPS data = $GPRMC,103302.000,
The double 'PPS low' aligns with my board reporting sync loss at 10:33:00.
Note that I have a 1PPS signal that is normally high and goes low when active, but yours might be the other way round, select the right option in the code. Mine is that way because the electronics that sends the 1PPS and the serial data from the GPS receiver in the loft to my workbench inverts the 1PPS so that is is the same way round as serial; high being idle.
If you have been reading all this you will know I have not absolutely proved that the 1PPS leading edge aligns with the boundary between seconds. The data sheet for the FGPMMOPA6H just says:
A pulse per second (1 PPS) is an electrical signal that very precisely indicates the start of a second.
Depending on the source, properly operating PPS signals have typical accuracy ranging 10ns.
1 PPS signals are used for precise timekeeping and time measurement. One increasingly common
use is in computer timekeeping, including the NTP protocol. A common use for the PPS signal is to
connect it to a PC using a low-latency, low-jitter wire connection and allow a program to synchronize
to it:
PA6H supply the high accurate 1PPS timing to synchronize to GPS time after 3D-Fix.
A power-on output 1pps is also available for customization firmware settings.
I'm getting a warning about the NULL in line 49:
"converting to non-pointer type 'char' from NULL"
I assume that doesn't matter.
I guess I'm just having a brain fart, but what is the LF that's connected to D10?
Everything I read says PPS is a 100ms pulse sent at the beginning of the second.
Oh! Null confuses me. Replace it with 0x00.
Ok, and LF isn't a pin, it's just a value. nevermind.
LF is linefeed.
I get completely normal output:
PPS high
GPS data = $GPRMC,145230.00,A,3602.41845,N,09556.72890,W,0.254,,311223,,,A*60
PPS high
GPS data = $GPRMC,145231.00,A,3602.41833,N,09556.72877,W,0.082,,311223,,,A*60
PPS high
GPS data = $GPRMC,145232.00,A,3602.41828,N,09556.72877,W,0.129,,311223,,,A*69
PPS high
GPS data = $GPRMC,145233.00,A,3602.39896,N,09556.75805,W,0.036,,311223,,,A*6F
PPS high
GPS data = $GPRMC,145234.00,A,3602.39905,N,09556.75780,W,0.013,,311223,,,A*66
PPS high
GPS data = $GPRMC,145235.00,A,3602.39902,N,09556.75768,W,0.044,,311223,,,A*64
PPS high
GPS data = $GPRMC,145236.00,A,3602.39889,N,09556.75756,W,0.066,,311223,,,A*68
PPS high
GPS data = $GPRMC,145237.00,A,3602.39869,N,09556.75744,W,0.017,,311223,,,A*62
PPS high
GPS data = $GPRMC,145238.00,A,3602.39855,N,09556.75723,W,0.043,,311223,,,A*62
PPS high
GPS data = $GPRMC,145239.00,A,3602.39848,N,09556.75726,W,0.081,,311223,,,A*64
PPS high
GPS data = $GPRMC,145240.00,A,3602.39847,N,09556.75718,W,0.059,,311223,,,A*6D
PPS high
GPS data = $GPRMC,145241.00,A,3602.39851,N,09556.75709,W,0.052,,311223,,,A*60
PPS high
GPS data = $GPRMC,145242.00,A,3602.39852,N,09556.75703,W,0.036,,311223,,,A*68
PPS high
GPS data = $GPRMC,145243.00,A,3602.39848,N,09556.75695,W,0.036,,311223,,,A*6C
PPS high
GPS data = $GPRMC,145244.00,A,3602.39841,N,09556.75687,W,0.038,,311223,,,A*6F
PPS high
GPS data = $GPRMC,145245.00,A,3602.39835,N,09556.75679,W,0.119,,311223,,,A*6E
PPS high
GPS data = $GPRMC,145246.00,A,3602.39825,N,09556.75666,W,0.015,,311223,,,A*6F
PPS high
GPS data = $GPRMC,145247.00,A,3602.39819,N,09556.75660,W,0.049,,311223,,,A*6E
PPS high
GPS data = $GPRMC,145248.00,A,3602.39815,N,09556.75654,W,0.044,,311223,,,A*67
PPS high
GPS data = $GPRMC,145249.00,A,3602.39816,N,09556.75654,W,0.041,,311223,,,A*60
PPS high
GPS data = $GPRMC,145250.00,A,3602.39815,N,09556.75656,W,0.062,,311223,,,A*68
PPS high
GPS data = $GPRMC,145251.00,A,3602.39815,N,09556.75657,W,0.033,,311223,,,A*6C
PPS high
GPS data = $GPRMC,145252.00,A,3602.39818,N,09556.75662,W,0.074,,311223,,,A*67
PPS high
GPS data = $GPRMC,145253.00,A,3602.39822,N,09556.75666,W,0.051,,311223,,,A*6C
PPS high
GPS data = $GPRMC,145254.00,A,3602.39822,N,09556.75666,W,0.030,,311223,,,A*6C
PPS high
GPS data = $GPRMC,145255.00,A,3602.39822,N,09556.75664,W,0.040,,311223,,,A*68
PPS high
GPS data = $GPRMC,145256.00,A,3602.39824,N,09556.75662,W,0.067,,311223,,,A*6E
PPS high
GPS data = $GPRMC,145257.00,A,3602.39823,N,09556.75659,W,0.030,,311223,,,A*62
PPS high
GPS data = $GPRMC,145258.00,A,3602.39824,N,09556.75658,W,0.073,,311223,,,A*6C
PPS high
GPS data = $GPRMC,145259.00,A,3602.39825,N,09556.75657,W,0.041,,311223,,,A*62
PPS high
GPS data = $GPRMC,145300.00,A,3602.39826,N,09556.75655,W,0.068,,311223,,,A*65
PPS high
GPS data = $GPRMC,145301.00,A,3602.39828,N,09556.75656,W,0.021,,311223,,,A*64
PPS high
GPS data = $GPRMC,145302.00,A,3602.39828,N,09556.75655,W,0.068,,311223,,,A*69
PPS high
GPS data = $GPRMC,145303.00,A,3602.39834,N,09556.75656,W,0.036,,311223,,,A*6D
PPS high
GPS data = $GPRMC,145304.00,A,3602.39834,N,09556.75657,W,0.018,,311223,,,A*67
PPS high
GPS data = $GPRMC,145305.00,A,3602.39836,N,09556.75658,W,0.009,,311223,,,A*6B
PPS high
GPS data = $GPRMC,145306.00,A,3602.39837,N,09556.75659,W,0.024,,311223,,,A*67
PPS high
GPS data = $GPRMC,145307.00,A,3602.39839,N,09556.75655,W,0.031,,311223,,,A*60
PPS high
GPS data = $GPRMC,145308.00,A,3602.39836,N,09556.75652,W,0.039,,311223,,,A*6F
PPS high
GPS data = $GPRMC,145309.00,A,3602.39832,N,09556.75650,W,0.016,,311223,,,A*65
PPS high
GPS data = $GPRMC,145310.00,A,3602.39831,N,09556.75649,W,0.027,,311223,,,A*64
PPS high
GPS data = $GPRMC,145311.00,A,3602.39830,N,09556.75650,W,0.027,,311223,,,A*6C
PPS high
GPS data = $GPRMC,145312.00,A,3602.39827,N,09556.75655,W,0.021,,311223,,,A*6A
PPS high
GPS data = $GPRMC,145313.00,A,3602.39827,N,09556.75657,W,0.066,,311223,,,A*6A
PPS high
GPS data = $GPRMC,145314.00,A,3602.39827,N,09556.75658,W,0.067,,311223,,,A*63
PPS high
GPS data = $GPRMC,145315.00,A,3602.39830,N,09556.75662,W,0.030,,311223,,,A*6F
PPS high
GPS data = $GPRMC,145316.00,A,3602.39829,N,09556.75663,W,0.039,,311223,,,A*6C
PPS high
GPS data = $GPRMC,145317.00,A,3602.39830,N,09556.75663,W,0.022,,311223,,,A*6F
PPS high
GPS data = $GPRMC,145318.00,A,3602.39830,N,09556.75663,W,0.020,,311223,,,A*62
PPS high
GPS data = $GPRMC,145319.00,A,3602.39829,N,09556.75664,W,0.040,,311223,,,A*6A
Let it run for a while, sometimes I get no issues for a few minutes or 10s of minutes.
Select 'Show timestamp' in the serial monitor.
Last time it happened here was 14:57:10, time now is 15:16:45
Per the timestamp, PPS occurs about 150ms into the second, and the sentence is sent at about 330 ms. And neither of them seems to be moving off that.
$10 if I order from the US, £20 in the UK!
Maybe I should start importing them and selling them here.
If I modify the code so that it just pretends to print all this stuff to the serial monitor unless it would be printing two pps pulses in a row with no intervening sentence, would that detect what you are seeing? Then I could let it run all day, and just see how many times that happens, if at all.
Detecting 2 PPS in a row would be helpful.
I think the results you are getting, along with doubts and suprise that this problem exists at all, strongly suggests that I should order a new GPS module. Sure, I've worked around the problem in software, but it really shouldn't be happening at all.
It's still running with no hint of a problem. I'll modify the code this afternoon and let it run for a long time. But I think your solution is going to be the right one. I'm not sure mine is the best module for you, but the one you have just isn't behaving right.
