GPS NMEA Library

johnwasser:

#include <SoftwareSerial.h>

//  Fault flags
extern const unsigned int GPS_fault;
extern unsigned int Faults;

SoftwareSerial GPS(2, -1);

// Parse GPS message
byte GPS_byteCount = 0;
unsigned char GPS_buff[100];
unsigned long GPS_time = 0;
String GPS_lat = "";
String GPS_long = "";
String GPS_altitude = "";
unsigned long GPS_lastgood = 0;
unsigned long GPS_lasttest = 0;

void GPS_setup(void)
{
  GPS.begin(4800);
}

void GPS_loop(void)
{
  // If any characters are available from the GPS, send them to the parser
  while (GPS.available())
  {
    GPS_parse_char(GPS.read());
  }

// Check for GPS status
  if ((millis() - GPS_lastgood > 3000))
    Faults |= GPS_fault;   
}

void GPS_log(Print &dest)
{
  // Log GPS data
  dest.print(GPS_time, DEC);
  dest.print(',');
  dest.print(GPS_lat);
  dest.print(',');
  dest.print(GPS_long);     
  dest.print(',');
  dest.print(GPS_altitude);
  dest.print(',');
  dest.print((millis() - GPS_lastgood)/1000);
}

int GPS_parse_char(byte inputChar)
{
  switch (inputChar)
  {
  case '\r':
    return GPS_check_buffer();

case '

I know this is an old post, but would you mind telling me how I could use this code with hardware serial, "Serial2", instead of the software serial?

:
    GPS_byteCount = 0;  // Start of message

default:
    GPS_buff[GPS_byteCount++] = inputChar;
    if (GPS_byteCount == 100)
    {
      GPS_byteCount = 0;  // Start of message
      return -3;  //  Buffer overrun
    }
    return 0; // Not a full message
  }
}

int GPS_check_buffer()
{
  GPS_buff[GPS_byteCount] = '\0';

unsigned char *buffp = GPS_buff;

// Check the message type
  for (int i=0; i<7; i++)
  {
    if (buffp[i] != "$GPGGA,"[i])
      return 0;
  }

// Verify the checksum before doing any more
  if (GPS_buff[GPS_byteCount-3] != '*')  // Checksum marker
    return -1;  // Bad message format

byte checksum = 0;
  for (int i=1; i<GPS_byteCount-3; i++)  // Skip '

I know this is an old post, but would you mind telling me how I could use this code with hardware serial, "Serial2", instead of the software serial?

and '*'
    checksum ^= GPS_buff[i];
  //  Test the result
  checksum -= hexval(GPS_buff[GPS_byteCount-2]) << 4;
  checksum -= hexval(GPS_buff[GPS_byteCount-1]);

if (checksum != 0) return -2; // Checksum failure

//  parse the time field
  buffp += 7;  // Skip over $GPGGA,
  GPS_time = 0;
  while (hexval(*buffp) != -1)  // for each digit
  {
    GPS_time *= 10;
    GPS_time += hexval(*buffp);
    buffp++;
  }

if (*buffp++ != '.') // Should be a decimal point
    return -1;

while (*buffp == '0')  // Skip zeros
    buffp++;

if (*buffp++ != ',') // Should be a comma
    return -1;

// Parse latitude
  GPS_lat = "";
  for (int i=0; i<20; i++)
  {
    if (*buffp == ',')
      break;
    GPS_lat += *buffp++;
    if (i == 1)
      GPS_lat += ' ';  // Separate degrees from minutes
  }
  buffp++;  // skip the comma

if (*buffp == 'S')
    GPS_lat = "-" + GPS_lat;
  else
    if (*buffp != 'N')
      return -1;

buffp++;  // Skip the N or S

if (*buffp++ != ',') // Should be a comma
    return -1;

// Parse longitude
  GPS_long = "";
  for (int i=0; i<20; i++)
  {
    if (*buffp == ',')
      break;
    GPS_long += *buffp++;
    if (i == 2)
      GPS_long += ' ';  // Separate degrees from minutes
  }
  buffp++;  // skip the comma

if (*buffp == 'W')
    GPS_long = "-" + GPS_long;
  else
    if (*buffp != 'E')
      return -1;

buffp++;  // Skip the E or W

if (*buffp++ != ',') // Should be a comma
    return -1;

if (*buffp++ == '0')
  {
    Faults |= GPS_fault;
    return -3; // No view of sattelites
  }

if (*buffp++ != ',') // Should be a comma
    return -1;

GPS_lastgood = millis();

while (*buffp++ != ',') ; // Skip number of satellites
  while (*buffp++ != ',') ; // Skip horizontal dillution
  GPS_altitude = "";
  while (*buffp != ',')
    GPS_altitude += *buffp++;

//Serial.println((char *)GPS_buff);
  Faults &= ~GPS_fault;
  return 1;  // Good fix
}

int hexval(char digit)
{
  if (digit >= '0' && digit <= '9')
    return digit - '0';

if (digit >= 'A' && digit <= 'F')
    return digit - 'A' + 10;

if (digit >= 'a' && digit <= 'f')
    return digit - 'a' + 10;

return -1;
}

I know this is an old post, but would you mind telling me how I could use this code with hardware serial, "Serial2", instead of the software serial?