Usage Example for Arduino-$GNRMC GPS Data Analysis

Last revision 2026/01/29

This article provides a comprehensive guide on using Arduino to analyze $GNRMC GPS data. It includes a detailed breakdown of hardware and software requirements, connection diagrams, and sample code to help users effectively parse and interpret GPS data, making it an invaluable resource for anyone interested in GPS technology and Arduino programming.

Hardware

Software

Connection Diagram

TEL0132-Connection-$GNRMC GPS Data Analysis

UNO R3 PIN GPS + BDS BeiDou Dual Module PIN
UNO R3 VCC GPS + BDS BeiDou Dual Module VCC
UNO R3 GND GPS + BDS BeiDou Dual Module GND
UNO R3 D11 GPS + BDS BeiDou Dual Module TX
UNO R3 D12 GPS + BDS BeiDou Dual Module RX

Sample Code ($GNRMC GPS Data Analysis)

#include <SoftwareSerial.h>
SoftwareSerial GpsSerial(12, 11);  //RX,TX

struct
{
  char GPS_DATA[80];
  bool GetData_Flag;      //Get GPS data flag bit
  bool ParseData_Flag;    //Parse completed flag bit 
  char UTCTime[11];       //UTC time
  char latitude[11];      //Latitude
  char N_S[2];            //N/S
  char longitude[12];     //Longitude
  char E_W[2];            //E/W
  bool Usefull_Flag;      //If the position information is valid flag bit 
} Save_Data;

const unsigned int gpsRxBufferLength = 600;
char gpsRxBuffer[gpsRxBufferLength];
unsigned int gpsRxLength = 0;

void setup()
{
  Serial.begin(115200);   //Debug Serial
  GpsSerial.begin(9600);  //Gps Serial
  
  Serial.println("DFRobot Gps");
  Serial.println("Wating...");

  Save_Data.GetData_Flag = false;
  Save_Data.ParseData_Flag = false;
  Save_Data.Usefull_Flag = false;
}

void loop()
{
  Read_Gps();         //Get GPS data 
  parse_GpsDATA();    //Analyze GPS data 
  print_GpsDATA();    //Output analyzed data 
}

void Error_Flag(int num)
{
  Serial.print("ERROR");
  Serial.println(num);
  while (1)
  {
    digitalWrite(13, HIGH);
    delay(500);
    digitalWrite(13, LOW);
    delay(500);
  }
}

void print_GpsDATA()
{
  if (Save_Data.ParseData_Flag)
  {
    Save_Data.ParseData_Flag = false;
    
    Serial.print("Save_Data.UTCTime = ");
    Serial.println(Save_Data.UTCTime);

    if(Save_Data.Usefull_Flag)
    {
      Save_Data.Usefull_Flag = false;
      Serial.print("Save_Data.latitude = ");
      Serial.println(Save_Data.latitude);
      Serial.print("Save_Data.N_S = ");
      Serial.println(Save_Data.N_S);
      Serial.print("Save_Data.longitude = ");
      Serial.println(Save_Data.longitude);
      Serial.print("Save_Data.E_W = ");
      Serial.println(Save_Data.E_W);
    }
    else
    {
      Serial.println("GPS DATA is not usefull!");
    }    
  }
}

void parse_GpsDATA()
{
  char *subString;
  char *subStringNext;
  if (Save_Data.GetData_Flag)
  {
    Save_Data.GetData_Flag = false;
    Serial.println("************************");
    Serial.println(Save_Data.GPS_DATA);
    
    for (int i = 0 ; i <= 6 ; i++)
    {
      if (i == 0)
      {
        if ((subString = strstr(Save_Data.GPS_DATA, ",")) == NULL)
          Error_Flag(1);    //Analysis error 
      }
      else
      {
        subString++;
        if ((subStringNext = strstr(subString, ",")) != NULL)
        {
          char usefullBuffer[2]; 
          switch(i)
          {
            case 1:memcpy(Save_Data.UTCTime, subString, subStringNext - subString);break;    //Get UTC time 
            case 2:memcpy(usefullBuffer, subString, subStringNext - subString);break;        //Get position status 
            case 3:memcpy(Save_Data.latitude, subString, subStringNext - subString);break;   //Get latitude information 
            case 4:memcpy(Save_Data.N_S, subString, subStringNext - subString);break;        //Get N/S
            case 5:memcpy(Save_Data.longitude, subString, subStringNext - subString);break;  //Get longitude information 
            case 6:memcpy(Save_Data.E_W, subString, subStringNext - subString);break;        //Get E/W

            default:break;
          }
          subString = subStringNext;
          Save_Data.ParseData_Flag = true;
          if(usefullBuffer[0] == 'A')
            Save_Data.Usefull_Flag = true;
          else if(usefullBuffer[0] == 'V')
            Save_Data.Usefull_Flag = false;
        }
        else
        {
          Error_Flag(2);    //Analysis error
        }
      }
    }
  }
}

void Read_Gps() 
{
  while (GpsSerial.available())
  {
    gpsRxBuffer[gpsRxLength++] = GpsSerial.read();
    if (gpsRxLength == gpsRxBufferLength)RST_GpsRxBuffer();
  }

  char* GPS_DATAHead;
  char* GPS_DATATail;
  if ((GPS_DATAHead = strstr(gpsRxBuffer, "$GPRMC,")) != NULL || (GPS_DATAHead = strstr(gpsRxBuffer, "$GNRMC,")) != NULL )
  {
    if (((GPS_DATATail = strstr(GPS_DATAHead, "\r\n")) != NULL) && (GPS_DATATail > GPS_DATAHead))
    {
      memcpy(Save_Data.GPS_DATA, GPS_DATAHead, GPS_DATATail - GPS_DATAHead);
      Save_Data.GetData_Flag = true;

      RST_GpsRxBuffer();
    }
  }
}

void RST_GpsRxBuffer(void)
{
  memset(gpsRxBuffer, 0, gpsRxBufferLength);      //Clear
  gpsRxLength = 0;

Expected Results

$GNRMC GPS Data Analysis

Was this article helpful?

TOP