Problem with char array not saving data

Hi all,

I have written a program that parses data from a GPS chip (G.top010) and is supposed to save the parsed data to two char arrays for further use. The intent is that once the array is populated the first time that it is only repopulated by new data from the GPS when the parser determines that there is new data.

The program has no problem reading the data from the GPS chip, or in parsing it into the NMEA sentences that I am interesting in further extracting the data from.The problem that I am having is that sometimes the GPGGAMaster array does not have anything in it. This problem happens randomly and I can only print data from the array about 50 percent of the time.

Here is the code:

//--------------- Test Code Related Globals -----------------------------------------

#include <SoftwareSerial.h>
const int rxpinSS =2;
const int txpinSS =3;
SoftwareSerial serial_gps(rxpinSS, txpinSS); // RX, 

unsigned long previousMillis = 0;
unsigned long previousMillisTestDisplay = 0;

//---- GPS Related Globals ----------------------------------------------------------

  char GPGGAMaster[43];
  char GPRMCMaster[61];
  

void setup()
{
  Serial.begin(9600);
  serial_gps.begin(9600);
}

void loop()
{

  ParseGPS();

  if (millis() - previousMillisTestDisplay >= 2000) { //displays message before going into execution
      

      Serial.print("GPGGA: ");
      Serial.println(GPGGAMaster);
      Serial.print("GPRMC: ");
      Serial.println(GPRMCMaster);
      //Serial.print("GPGGA Size: ");
      //Serial.println(sizeof(GPGGAMaster));
      //Serial.print("GPRMC Size: ");
      //Serial.println(sizeof(GPRMCMaster));
      Serial.println("--------------");
     
      previousMillisTestDisplay = millis();
   }
}

//------------------This code parses the data from the GPS into the format we need-------------------------------  

//----------------------------------------------- Software Serial Function for testing ----------------------------------------------
void ParseGPS()
{
  char serialDataHolder;
  char StartMarker = '

This is a snippet of the output stream that demonstrates the problem (that GPGGAMaster array sometimes does not seem to have anything in it):

GPGGA: 
GPRMC: ,221544.000,A,2956.4606,N,09006.4730,W,0.14,140.55,160520,,,
--------------
GPGGA: 
GPRMC: ,221546.000,A,2956.4606,N,09006.4729,W,0.20,140.55,160520,,,
--------------
GPGGA: ,221548.000,2956.4605,N,09006.4730,W,2,7,1
GPRMC: ,221547.000,A,2956.4605,N,09006.4729,W,0.22,140.55,160520,,,
--------------
GPGGA: ,221550.000,2956.4603,N,09006.4731,W,2,7,1
GPRMC: ,221549.000,A,2956.4604,N,09006.4730,W,0.38,140.55,160520,,,
--------------
GPGGA: ,221552.000,2956.4602,N,09006.4732,W,2,7,1
GPRMC: ,221551.000,A,2956.4602,N,09006.4732,W,0.19,140.55,160520,,,
--------------
GPGGA: 
GPRMC: ,221554.000,A,2956.4603,N,09006.4734,W,0.36,140.55,160520,,,
--------------
GPGGA: 
GPRMC: ,221556.000,A,2956.4604,N,09006.4736,W,0.26,140.55,160520,,,

The following modification to the code shows that there is data that should be getting saved in the GPGGAMaster array:

        if(serial_gps.available() >= 42){
            Serial.print("GPGGA Bytes Avail: ");
            Serial.println(serial_gps.available());
            for (int x=0; x<42; x++){         
                char a = serial_gps.read();
                Serial.print(a);
                GPGGAMaster[x]= a;
                //GPGGAMaster[x]= serial_gps.read();
            }
            Serial.println("---------------");
            GPGGAMaster[43] = '\0';
        }

This is the output after the change:

GPGGA Bytes Avail: 42
,223429.000,2956.4602,N,09006.4765,W,2,5,1 
***************
GPGGA Bytes Avail: 42
,223430.000,2956.4602,N,09006.4764,W,2,5,1 
***************
GPGGA: 
GPRMC: ,223430.000,A,2956.4602,N,09006.4764,W,0.39,95.59,160520,,,D
--------------
GPGGA Bytes Avail: 42
,223431.000,2956.4602,N,09006.4763,W,2,5,1 
***************
GPGGA Bytes Avail: 42
,223432.000,2956.4602,N,09006.4762,W,2,5,1 
***************
GPGGA: ,223432.000,2956.4602,N,09006.4762,W,2,5,1
GPRMC: ,223431.000,A,2956.4602,N,09006.4763,W,0.34,95.59,160520,,,D
--------------
GPGGA Bytes Avail: 42
,223433.000,2956.4602,N,09006.4761,W,2,5,1 
***************
GPGGA Bytes Avail: 42
,223434.000,2956.4602,N,09006.4760,W,2,5,1 
***************
GPGGA: 
GPRMC: ,223434.000,A,2956.4602,N,09006.4760,W,0.37,95.59,160520,,,D
--------------

Sorry the post is so long but I hope that it is enough information for someone to tell me what I am doing wrong. The problem occurs on an Uno. Thank you to anyone that can help.;
 char GPGGAsecondMarker = ‘G’;
 char GPRMCsecondMarker = ‘M’;
 char endMarker = ‘*’;
 boolean GPGGAtest = false;
 boolean GPRMCtest = false;
 boolean dataDone = true;
 static int ndx = 0;
 
 while (serial_gps.available() > 0 && dataDone == true) //stays in this state as long as there is data in the buffer or until a NMEA sentence is parsed
 {
   serialDataHolder = serial_gps.read();

if (serialDataHolder == StartMarker) //goes through the available data until it locates the ’


This is a snippet of the output stream that demonstrates the problem (that GPGGAMaster array sometimes does not seem to have anything in it):

§DISCOURSE_HOISTED_CODE_1§


The following modification to the code shows that there is data that should be getting saved in the GPGGAMaster array:

§DISCOURSE_HOISTED_CODE_2§


This is the output after the change:

§DISCOURSE_HOISTED_CODE_3§


Sorry the post is so long but I hope that it is enough information for someone to tell me what I am doing wrong. The problem occurs on an Uno. Thank you to anyone that can help. that represents the start of each NMEA sentence
    {
      char ab[6]={'b'}; //initialize array to check which marker is detected with characters that will not cause false positives
      ab[5]='\0';

      if(serial_gps.available() < 5) //checks to make sure there are at least 5 bytes to read and causes a slight delay for more char to load if not enough
      {
        delay(10);
      } 
      
      for (int x=0; x<5; x++) //reads 5 characters from the buffer to check what data stream it is
      {         
        ab[x] = serial_gps.read();
      }
      
      if (ab[2] == 'G' && ab[3] == 'G' && ab[4] == 'A') //if GPGGA is detected, set GPGGA test variable to true so the GPGGA array reader will run
      {   
        GPGGAtest = true;
      }
      if (ab[2] == 'R' && ab[3] == 'M' && ab[4] == 'C') //if GPRMC is detected, set GPRMC test variable to true so the GPRMC array reader will run
      {   
        GPRMCtest = true;
      }
    //Serial.println(ab);
    
    }  

        
    if(GPGGAtest == true){//reads the GPGGA data into correct arrays
  
        dataDone = false; //this is set to false so that the while loop above exits once the data is stored

        int timeoutCount = 0;

        while(serial_gps.available() < 42 && timeoutCount < 100){ //gives time for the entire NMEA sentence to be in the buffer before reading it
            timeoutCount++;
            delay(1);
        }
      
        if(serial_gps.available() >= 42){ //reads the data from the GPS buffer into the array for the GPGGA sentence 
            for (int x=0; x<42; x++){         
                GPGGAMaster[x]= serial_gps.read();
            }
            GPGGAMaster[43] = '\0';
        }
    }
        
    if(GPRMCtest == true){
        dataDone = false; //this is set to false so that the while loop above exits once the data is stored

        int timeoutCount = 0;

        while(serial_gps.available() < 60 && timeoutCount < 100){ //gives time for the entire NMEA sentence to be in the buffer before reading it
            timeoutCount++;
            delay(1);
        }

        if(serial_gps.available() >= 60){ //reads the data from the GPS buffer into the array for the GPRMC sentence 
            for (int x=0; x<60; x++){         
                GPRMCMaster[x]= serial_gps.read();
            }
            GPRMCMaster[61] = '\0'; 
        }
    }
  }  
}

This is a snippet of the output stream that demonstrates the problem (that GPGGAMaster array sometimes does not seem to have anything in it):

§_DISCOURSE_HOISTED_CODE_1_§

The following modification to the code shows that there is data that should be getting saved in the GPGGAMaster array:

§_DISCOURSE_HOISTED_CODE_2_§

This is the output after the change:

§_DISCOURSE_HOISTED_CODE_3_§

Sorry the post is so long but I hope that it is enough information for someone to tell me what I am doing wrong. The problem occurs on an Uno. Thank you to anyone that can help.

You declare these arrays

char GPGGAMaster[43];
char GPRMCMaster[61];

but then do this

        GPGGAMaster[43] = '\0';
//...
        GPRMCMaster[61] = '\0';

You are writing out of bounds. If your message is 42 bytes, those go into indices 0..41 and the final nul goes into index 42.

You're absolutely right. That seems to solve the problem. I knew it was something simple that I was just not seeing. Thank you!

You don't seem to be setting GPGGAtest or GPRMCtest to 'false' inside the while() loop. Once one of each message is received you will try to parse the arriving stream both ways. This is probably causing some timeouts which you ignore, going on to store the data even though it hasn't arrived yet.

Are you sure you don't want to use any of the existing GPS parsing libraries?