summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Golle2021-06-07 21:14:30 +0000
committerDaniel Golle2021-06-07 22:03:02 +0000
commit8e12414a2b7a8a1e7228ff37e3cf9bd9c63a33c1 (patch)
tree151e931c6366fa2776c9b3eeddea808c91db04db
parent86ee86eef24303e0a9e21b46691b04e5edb2c713 (diff)
downloadugps-8e12414a2b7a8a1e7228ff37e3cf9bd9c63a33c1.tar.gz
nmea: parse $GPGLL sentences for position
Some GPS receivers do not send $GPGGA sentence. Parse latitude and longitude also from $GPGLL sentences. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-rw-r--r--nmea.c73
1 files changed, 49 insertions, 24 deletions
diff --git a/nmea.c b/nmea.c
index 5bf6d9a..d51d936 100644
--- a/nmea.c
+++ b/nmea.c
@@ -95,6 +95,34 @@ do_adjust_clock(struct tm *tm)
}
static void
+parse_gps_coords(char *latstr, char *vhem, char *lonstr, char *hhem)
+{
+ float minutes;
+ float degrees;
+ float lat = strtof(latstr, NULL);
+ float lon = strtof(lonstr, NULL);
+
+ degrees = floor(lat / 100.0);
+ minutes = lat - (degrees * 100.0);
+ lat = degrees + minutes / 60.0;
+
+ degrees = floor(lon / 100.0);
+ minutes = lon - (degrees * 100.0);
+ lon = degrees + minutes / 60.0;
+
+ if (*vhem == 'S')
+ lat *= -1.0;
+ if (*hhem == 'W')
+ lon *= -1.0;
+
+ snprintf(latitude, sizeof(latitude), "%f", lat);
+ snprintf(longitude, sizeof(longitude), "%f", lon);
+
+ DEBUG(3, "position: %s %s\n", latitude, longitude);
+ gps_timestamp();
+}
+
+static void
nmea_rmc_cb(void)
{
struct tm tm;
@@ -132,29 +160,7 @@ nmea_rmc_cb(void)
ERROR("lat/lng have invalid string length %zu<9, %zu<10\n",
strlen(nmea_params[3].str), strlen(nmea_params[5].str));
} else {
- float minutes;
- float degrees;
- float lat = strtof(nmea_params[3].str, NULL);
- float lon = strtof(nmea_params[5].str, NULL);
-
- degrees = floor(lat / 100.0);
- minutes = lat - (degrees * 100.0);
- lat = degrees + minutes / 60.0;
-
- degrees = floor(lon / 100.0);
- minutes = lon - (degrees * 100.0);
- lon = degrees + minutes / 60.0;
-
- if (*nmea_params[4].str == 'S')
- lat *= -1.0;
- if (*nmea_params[6].str == 'W')
- lon *= -1.0;
-
- snprintf(latitude, sizeof(latitude), "%f", lat);
- snprintf(longitude, sizeof(longitude), "%f", lon);
-
- DEBUG(3, "position: %s %s\n", latitude, longitude);
- gps_timestamp();
+ parse_gps_coords(nmea_params[3].str, nmea_params[4].str, nmea_params[5].str, nmea_params[6].str);
}
}
@@ -163,7 +169,8 @@ nmea_zda_cb(void)
{
struct tm tm;
- gps_valid = 1;
+ if (!gps_valid)
+ return;
memset(&tm, 0, sizeof(tm));
tm.tm_isdst = 1;
@@ -194,6 +201,20 @@ nmea_zda_cb(void)
}
static void
+nmea_gll_cb(void)
+{
+ if (*nmea_params[6].str != 'A') {
+ gps_valid = 0;
+ DEBUG(4, "waiting for valid signal\n");
+ return;
+ }
+
+ gps_valid = 1;
+
+ parse_gps_coords(nmea_params[1].str, nmea_params[2].str, nmea_params[3].str, nmea_params[4].str);
+}
+
+static void
nmea_gga_cb(void)
{
if (!gps_valid)
@@ -231,6 +252,10 @@ static struct nmea_msg {
.cnt = 14,
.handler = nmea_gga_cb,
}, {
+ .msg = "GLL",
+ .cnt = 7,
+ .handler = nmea_gll_cb,
+ }, {
.msg = "VTG",
.cnt = 9,
.handler = nmea_vtg_cb,