nmea gps library - without any serial

Dependents:   HARP2 HARP3 20180621_FT813

Fork of GPS_parser by Tyler Weaver

NMEA GPS Serial Output parser.

Routine taken from NMEA Software Standard (NMEA 0183) http://www.winsystems.com/software/nmea.pdf

Only handles GGA and RMC Messages

Revision:
7:01a8379370e4
Parent:
6:4ed12067a314
Child:
8:59acef1c795b
--- a/GPS_parser.cpp	Wed Dec 12 17:53:50 2012 +0000
+++ b/GPS_parser.cpp	Thu Dec 13 04:57:10 2012 +0000
@@ -8,7 +8,7 @@
     ns = ' ';
     ew = ' ';
     lock = 0;
-    satelites = 0;
+    satellites = 0;
     hdop = 0.0;
     msl_altitude = 0.0;
     msl_units = ' ';
@@ -21,17 +21,9 @@
     dec_longitude = 0.0;
     dec_latitude = 0.0;
 
-    gll_status = ' ';
+    altitude_ft = 0.0;
 
-    course_t = 0.0; // ground speed true
-    course_t_unit = ' ';
-    course_m = 0.0; // magnetic
-    course_m_unit = ' ';
-    speed_k_unit = ' ';
-    speed_km = 0.0; // speek km/hr
-    speed_km_unit = ' ';
-
-    altitude_ft = 0.0;
+    current = NULL;
 }
 
 float GPS_Parser::nmea_to_dec(float deg_coord, char nsew)
@@ -46,31 +38,6 @@
     return decimal;
 }
 
-int GPS_Parser::sample(char *msg)
-{
-    int line_parsed = 0;
-
-    // Check if it is a GPGGA msg (matches both locked and non-locked msg)
-    if (sscanf(msg, "$GPGGA,%f,%f,%c,%f,%c,%d,%d,%f,%f,%c", &utc_time, &nmea_latitude, &ns, &nmea_longitude, &ew, &lock, &satelites, &hdop, &msl_altitude, &msl_units) >= 1) {
-        line_parsed = GGA;
-    }
-    // Check if it is a GPRMC msg
-    else if (sscanf(msg, "$GPRMC,%f,%f,%c,%f,%c,%f,%f,%d", &utc_time, &nmea_latitude, &ns, &nmea_longitude, &ew, &speed_k, &course_d, &date) >= 1) {
-        line_parsed = RMC;
-    }
-
-    if(satelites == 0) {
-        lock = 0;
-    }
-    if (!lock) {
-        return NO_LOCK;
-    } else if (line_parsed) {
-        return line_parsed;
-    } else {
-        return NOT_PARSED;
-    }
-}
-
 
 // INTERNAL FUNCTINS ////////////////////////////////////////////////////////////
 float GPS_Parser::trunc(float v)
@@ -95,12 +62,12 @@
         return msl_altitude;
 }
 
-int GPS_Parser::get_satelites()
+int GPS_Parser::get_satellites()
 {
     if (!lock)
         return 0;
     else
-        return satelites;
+        return satellites;
 }
 
 float GPS_Parser::get_nmea_longitude()
@@ -137,20 +104,12 @@
         return dec_latitude;
 }
 
-float GPS_Parser::get_course_t()
+float GPS_Parser::get_course_d()
 {
     if (!lock)
         return 0.0;
     else
-        return course_t;
-}
-
-float GPS_Parser::get_course_m()
-{
-    if (!lock)
-        return 0.0;
-    else
-        return course_m;
+        return course_d;
 }
 
 float GPS_Parser::get_speed_k()
@@ -161,14 +120,6 @@
         return speed_k;
 }
 
-float GPS_Parser::get_speed_km()
-{
-    if (!lock)
-        return 0.0;
-    else
-        return speed_km;
-}
-
 float GPS_Parser::get_altitude_ft()
 {
     if (!lock)
@@ -242,3 +193,90 @@
     return calc_dist_to_mi(pointLat, pontLong)*1609.344;
 }
 
+char *GPS_Parser::my_token(char *source,char token)
+{
+    char *start;
+    /* The source string is real only for the first call. Subsequent calls
+                are made with the source string pointer as NULL
+                */
+    if(source != NULL) {
+        /* If the string is empty return NULL */
+        if(strlen(source) == 0)
+            return NULL;
+        strcpy(stat_string,source);
+        /* Current is our 'current' position within the string */
+        current = stat_string;
+    }
+    start = current;
+
+    while (true) {
+        /* If we're at the end of the string, return NULL */
+        if((*current == '\0') && (current == start))
+            return NULL;
+        /* If we're at the end now, but weren't when we started, we need
+        to return the pointer for the last field before the end of string
+        */
+        if(*current == '\0')
+            return start;
+        /* If we've located our specified token (comma) in the string
+                                                load its location in the copy with an end of string marker
+                                                so that it can be handled correctly by the calling program.
+                                */
+        if(*current == token) {
+            *current = '\0';
+            current++;
+            return start;
+        } else {
+            current++;
+        }
+    }
+}
+
+int GPS_Parser::parse(char *string)
+{
+    int field_count;
+    field_count = 0;
+    /* NMEA 0183 fields are delimited by commas. The my_token function returns
+    pointers to the fields.
+                */
+    /* Get the first field pointer */
+    field[0] = my_token(string,',');
+    field_count++;
+
+    while (true) {
+        /* Contiue retrieving fields until there are no more (NULL) */
+        field[field_count] = my_token(NULL,',');
+        if(field[field_count] == NULL)
+            break;
+        field_count++;
+    }
+    /* If we got at least ONE field */
+    if(field_count) {
+        /* Check the first field for the valid NMEA 0183 headers */
+        if(strcmp(field[0],"$GPGGA") == 0) {
+            /* Retrieve the values from the remaining fields */
+            utc_time = atof(field[1]);
+            nmea_latitude = atof(field[2]);
+            ns = *(field[3]);
+            nmea_longitude = atof(field[4]);
+            ew = *(field[5]);
+            lock = atoi(field[6]);
+            satellites = atoi(field[7]);
+            hdop = atof(field[8]);
+            msl_altitude = atof(field[9]);
+            msl_units = *(field[10]);
+        }
+        if(strcmp(field[0],"$GPRMC") == 0) {
+            /* Retrieve the data from the remaining fields */
+            utc_time = atof(field[1]);
+            nmea_latitude = atof(field[3]);
+            ns = *(field[4]);
+            nmea_longitude = atof(field[5]);
+            ew = *(field[6]);
+            speed_k = atof(field[7]);
+            course_d = atof(field[8]);
+            date = atol(field[9]);
+        }
+    }
+    return field_count;
+}
\ No newline at end of file