GPS module intermittent data reception

Hi! Few days ago I bought neogps 7m and neogps m8n. I used NEOGPS library for my code. The issue is that i'm receiving data intermittently. "gps.avaible(gpsPort)" alternates between 0 and 1. I got the same results using the 2 modules. I even changed my microtroller. Please help

#include <NMEAGPS.h>
#include <SoftwareSerial.h>

SoftwareSerial gpsPort (4, 3); // RX, TX for GPS
NMEAGPS gps;
gps_fix fix;

void setup() {
  Serial.begin(9600);
  gpsPort.begin(9600);
  Serial.println(F("Starting GPS reception..."));
}

void loop() {
  // Read GPS data only when available
  while (gps.available(gpsPort)) {
    fix = gps.read(); // Read the latest GPS fix data

    if (fix.valid.location && fix.valid.time) {
      // Print GPS data if location and time are valid
      Serial.print(F("Latitude: "));
      Serial.print(fix.latitude(), 6);
      Serial.print(F(", Longitude: "));
      Serial.print(fix.longitude(), 6);
      Serial.print(F(", Time: "));
      Serial.print(fix.dateTime.hours);
      Serial.print(F(":"));
      Serial.print(fix.dateTime.minutes);
      Serial.print(F(":"));
      Serial.print(fix.dateTime.seconds);
      Serial.println();
    } else {
      Serial.println(F("Waiting for a valid GPS fix..."));
    }
  }
}

Welcome to the forum

You started a topic in the Uncategorised category of the forum when its description explicitly tells you not to

Your topic has been moved to a relevant category. Please be careful in future when deciding where to start new topics

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the < CODE/ > icon above the compose window) to make it easier to read and copy for examination

https://forum.arduino.cc/t/how-to-get-the-best-out-of-this-forum

Please post your full sketch, using code tags when you do. This prevents parts of it being interpreted as HTML coding and makes it easier to copy for examination

In my experience the easiest way to tidy up the code and add the code tags is as follows
Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.

Sound like normal expected behavior to me.

If your reading data from a GPS and your software keeps up with the data coming out of the GPS then their will be times when there is no data available and you need to wait for the next byte to come in from the GPS.

The thing is data it's taking like 2 seconds (from what I've been observing). I watched some YouTube tutorials and it's was not the same results

You create an instance of a SoftwareSerial object called 'gpsPort':

Software Serial

but then you use a different name for begin():
Serial begin

That looks wrong to me.

See post #2, you need to post the code as text, much easier for everyone to read.

#include <NMEAGPS.h>
#include <SoftwareSerial.h>

SoftwareSerial gpsPort (4, 3); // RX, TX for GPS
NMEAGPS gps;
gps_fix fix;

void setup() {
  Serial.begin(9600);
  gpsPort.begin(9600);
  Serial.println(F("Starting GPS reception..."));
}

void loop() {
  // Read GPS data only when available
  while (gps.available(gpsPort)) {
    fix = gps.read(); // Read the latest GPS fix data

    if (fix.valid.location && fix.valid.time) {
      // Print GPS data if location and time are valid
      Serial.print(F("Latitude: "));
      Serial.print(fix.latitude(), 6);
      Serial.print(F(", Longitude: "));
      Serial.print(fix.longitude(), 6);
      Serial.print(F(", Time: "));
      Serial.print(fix.dateTime.hours);
      Serial.print(F(":"));
      Serial.print(fix.dateTime.minutes);
      Serial.print(F(":"));
      Serial.print(fix.dateTime.seconds);
      Serial.println();
    } else {
      Serial.println(F("Waiting for a valid GPS fix..."));
    }
  }
}

You've edited the first post with a different version of the code making my comments in post #5 look incorrect.
It's a good job I included 'proof'.

Sorry ! Yes I edited the code. I'm not trying to make fun of you. The screenshot of the first code I posted was the one in my phone I just forgot to correct the mistake (I'm using my phone to post). The correct code is this one(it's the one i uploaded to my arduino using my machine).

Please do not edit the original post. It makes the thread difficult to impossible to follow.

2 Likes

You are writing an entire sentence to Serial whenever the gps serial has no data in the buffer. This causes a long delay because the Serial transmit buffer is constantly full, which in turn causes the gps receive buffer to overflow and corrupt the data.

Increase the Serial baud rate significantly greater than 9600 baud, and don’t expect the gps receive buffer to always have data, at 9600 baud each character takes about a millisecond to receive.

I changed the serial baud rate to 115200 and got the same result. It's acting as if I added a 2seconds delay at the end.

If your after a possible solution, then a good explanation of the problem you think you are seeing would help.

Are you able to give the forum a copy of the extensive Serial.Prints() your code is making which shows the problem ?

If we assume an update rate of 1 Hz from the GPS (which is the default for a NEO 7M module I looked up), you'll see a burst of activity every second, followed by a pause where nothing is transmitted until the next second.

There's 1 second.

You don't mention what board you're using, so I'm going to assume an Uno R3.

SoftwareSerial has a 64 byte Rx buffer for that platform. That's barely enough for some $GP sentences, and not enough for some. So unless you're continuously reading the incoming GPS stream while it's sending, the buffer will overflow and you'll lose the remaining sentences in the data burst.

Your code stops reading the GPS data as soon as it has a valid location and time rather than checking to see if the data stream has gone quiet for a bit. While it's printing out to Serial, it's a lead pipe certainty that the SoftwareSerial Rx buffer is overflowing so the next time you go to read it... you'll get a bit of one sentence pasted onto another.

Modify your code to wait for a lull in the GPS data stream before it prints anything to Serial and see if that gets rid of the other second's delay. 50ms ought to do it.

"As I mentioned earlier, gps.available(gpsPort) is always alternating between 0 and 1 (you said this was normal, which is okay). However, every time it prints the location and time data, there is a delay of 2 seconds. I can tell because the printed time increments by 2 seconds each time.

To check if the GPS module is receiving all data correctly, I used the following code:

 #include <SoftwareSerial.h>

SoftwareSerial gpsPort(4, 3); // RX, TX for GPS (adjust pins as needed)

void setup() { Serial.begin(9600);        // Serial monitor speed gpsPort.begin(9600);       // GPS module baud rate (default is 9600 for most modules)

Serial.println("Starting GPS data reception..."); }

void loop() { // Check if data is available from the GPS module if (gpsPort.available()) { char gpsData = gpsPort.read(); // Read one character from the GPS module Serial.print(gpsData);         // Print the character to Serial Monitor } } 

With this code, I observed that the raw data from the GPS is printed, but after a moment, it stops printing (almost as if there is a delay), then it resumes printing again.

I uploaded this code to both an Arduino Uno and an ESP32 Wroom DA, and I observed the same results on both

I considered what you said and I justed my code. This is the code. the result was not better. At some times the time diffenrence was even greater than 2second

#include <NMEAGPS.h>
#include <SoftwareSerial.h>

SoftwareSerial gpsPort(4, 3); // RX, TX for GPS (adjust pins as needed)
NMEAGPS gps;
gps_fix fix;

unsigned long lastReceivedTime = 0;   // Tracks last time data was received
const unsigned long quietTime = 50;   // 50 ms quiet time threshold

void setup() {
  Serial.begin(9600);                // Serial monitor speed
  gpsPort.begin(9600);               // GPS module baud rate
  Serial.println("Starting GPS data reception...");
}

void loop() {
  // Read and parse GPS data only when available
  while (gps.available(gpsPort)) {
    fix = gps.read();  // Read the latest GPS fix data
    lastReceivedTime = millis();  // Update last received time
  }

  // Check for a lull in data
  if (millis() - lastReceivedTime > quietTime && fix.valid.location && fix.valid.date && fix.valid.time) {
    // Print date, time, and location
    Serial.print(F("Date: "));
    Serial.print(fix.dateTime.day);
    Serial.print(F("/"));
    Serial.print(fix.dateTime.month);
    Serial.print(F("/"));
    Serial.print(fix.dateTime.year);

    Serial.print(F(" Time: "));
    Serial.print(fix.dateTime.hours);
    Serial.print(F(":"));
    Serial.print(fix.dateTime.minutes);
    Serial.print(F(":"));
    Serial.print(fix.dateTime.seconds);

    Serial.print(F(" Latitude: "));
    Serial.print(fix.latitude(), 6);  // Print latitude with 6 decimal places

    Serial.print(F(" Longitude: "));
    Serial.println(fix.longitude(), 6);  // Print longitude with 6 decimal places
  }
}

The code you have posted is not correct.

If the actual output of the GPS is pausing, then that is likely how the GPS is configured.

Perhaps show the forum the actual GPS output ?

Output at different points. You can see the time diffenrence with the new code


For one, please post program output as text, far easier for everyone to read.

Second, thats not the actual output of the GPS. As suggested correct the program in post #16 and show us (as text !!!!!!) the actual output of the GPS.

Looks like you are using the NeoGPS library, have you verified that the configuration file correctly specifies the last NMEA sentence sent by the GPS module?