summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--driver_nmea.c126
-rw-r--r--gpsd.h-tail4
-rw-r--r--gpsd.xml12
-rw-r--r--packet.c9
-rw-r--r--packet_states.h1
-rw-r--r--test/daemon/sounder.log248
-rw-r--r--test/daemon/sounder.log.chk366
-rw-r--r--www/NMEA.txt1
9 files changed, 736 insertions, 35 deletions
diff --git a/NEWS b/NEWS
index 026a0f19..d226a479 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,9 @@
-* Thu 13 Jan 2012 Eric S. Raymond <esr@snark.thyrsus.com> - 3.5dev
+* Fri 09 Mar 2012 Eric S. Raymond <esr@snark.thyrsus.com> - 3.5dev
Use pselect when it's available to cut down on wakeups and improve
signal handling. New PPS message exporting clock drift. The AIVDM
driver now handles up to 16 interleaved 24A and 24B pair-halves.
+ The NMEA driver interprets depth-sounder returns from SDDBT and
+ reports them as negative altitudes.
* Thu 12 Jan 2012 Eric S. Raymond <esr@snark.thyrsus.com> - 3.4
Don't barf when chrpath is not available, fall back to static linking;
diff --git a/driver_nmea.c b/driver_nmea.c
index 48047279..e8b8d53b 100644
--- a/driver_nmea.c
+++ b/driver_nmea.c
@@ -813,6 +813,53 @@ static gps_mask_t processHDT(int c UNUSED, char *field[],
return mask;
}
+static gps_mask_t processDBT(int c UNUSED, char *field[],
+ struct gps_device_t *session)
+{
+ /*
+ * $SDDBT,7.7,f,2.3,M,1.3,F*05
+ * 1) Depth below sounder in feet
+ * 2) Fixed value 'f' indicating feet
+ * 3) Depth below sounder in meters
+ * 4) Fixed value 'M' indicating meters
+ * 5) Depth below sounder in fathoms
+ * 6) Fixed value 'F' indicating fathoms
+ * 7) Checksum.
+ *
+ * In real-world sensors, sometimes not all three conversions are reported.
+ */
+ gps_mask_t mask;
+ mask = ONLINE_SET;
+
+ if (field[3][0] != '\0') {
+ session->newdata.altitude = -safe_atof(field[3]);
+ mask |= (ALTITUDE_SET);
+ } else if (field[1][0] != '\0') {
+ session->newdata.altitude = -safe_atof(field[1]) / METERS_TO_FEET;
+ mask |= (ALTITUDE_SET);
+ } else if (field[5][0] != '\0') {
+ session->newdata.altitude = -safe_atof(field[5]) / METERS_TO_FATHOMS;
+ mask |= (ALTITUDE_SET);
+ }
+
+ if ((mask & ALTITUDE_SET) != 0) {
+ if (session->newdata.mode < MODE_3D) {
+ session->newdata.mode = MODE_3D;
+ mask |= MODE_SET;
+ }
+ }
+
+ /*
+ * Hack: We report depth below keep as negative altitude because there's
+ * no better place to put it. Should work in practice as nobody is
+ * likely to be operating a depth sounder at varying altitudes.
+ */
+ gpsd_report(LOG_RAW, "mode %d, depth %lf.\n",
+ session->newdata.mode,
+ session->newdata.altitude);
+ return mask;
+}
+
#ifdef TNT_ENABLE
static gps_mask_t processTNTHTM(int c UNUSED, char *field[],
struct gps_device_t *session)
@@ -1024,13 +1071,14 @@ gps_mask_t nmea_parse(char *sentence, struct gps_device_t * session)
{
char *name;
int nf; /* minimum number of fields required to parse */
+ bool cycle_continue; /* cycle continuer? */
nmea_decoder decoder;
} nmea_phrase[] = {
/*@ -nullassign @*/
- {"PGRMC", 0, NULL}, /* ignore Garmin Sensor Config */
- {"PGRME", 7, processPGRME},
- {"PGRMI", 0, NULL}, /* ignore Garmin Sensor Init */
- {"PGRMO", 0, NULL}, /* ignore Garmin Sentence Enable */
+ {"PGRMC", 0, false, NULL}, /* ignore Garmin Sensor Config */
+ {"PGRME", 7, false, processPGRME},
+ {"PGRMI", 0, false, NULL}, /* ignore Garmin Sensor Init */
+ {"PGRMO", 0, false, NULL}, /* ignore Garmin Sentence Enable */
/*
* Basic sentences must come after the PG* ones, otherwise
* Garmins can get stuck in a loop that looks like this:
@@ -1040,29 +1088,32 @@ gps_mask_t nmea_parse(char *sentence, struct gps_device_t * session)
* 2. PGRMC is sent to reconfigure to Garmin binary mode.
* If successful, the GPS echoes the phrase.
*
- * 3. nmea_parse() sees the echo as RMC because the talker ID is
- * ignored, and fails to recognize the echo as PGRMC and ignore it.
+ * 3. nmea_parse() sees the echo as RMC because the talker
+ * ID is ignored, and fails to recognize the echo as
+ * PGRMC and ignore it.
*
- * 4. The mode is changed back to NMEA, resulting in an infinite loop.
+ * 4. The mode is changed back to NMEA, resulting in an
+ * infinite loop.
*/
- {"RMC", 8, processGPRMC},
- {"GGA", 13, processGPGGA},
- {"GST", 8, processGPGST},
- {"GLL", 7, processGPGLL},
- {"GSA", 17, processGPGSA},
- {"GSV", 0, processGPGSV},
- {"VTG", 0, NULL}, /* ignore Velocity Track made Good */
- {"ZDA", 4, processGPZDA},
- {"GBS", 7, processGPGBS},
- {"HDT", 1, processHDT},
+ {"RMC", 8, false, processGPRMC},
+ {"GGA", 13, false, processGPGGA},
+ {"GST", 8, false, processGPGST},
+ {"GLL", 7, false, processGPGLL},
+ {"GSA", 17, false, processGPGSA},
+ {"GSV", 0, false, processGPGSV},
+ {"VTG", 0, false, NULL}, /* ignore Velocity Track made Good */
+ {"ZDA", 4, false, processGPZDA},
+ {"GBS", 7, false, processGPGBS},
+ {"HDT", 1, false, processHDT},
+ {"DBT", 7, true, processDBT},
#ifdef TNT_ENABLE
- {"PTNTHTM", 9, processTNTHTM},
+ {"PTNTHTM", 9, false, processTNTHTM},
#endif /* TNT_ENABLE */
#ifdef ASHTECH_ENABLE
- {"PASHR", 3, processPASHR}, /* general handler for Ashtech */
+ {"PASHR", 3, false, processPASHR}, /* general handler for Ashtech */
#endif /* ASHTECH_ENABLE */
#ifdef OCEANSERVER_ENABLE
- {"OHPR", 18, processOHPR},
+ {"OHPR", 18, false, processOHPR},
#endif /* OCEANSERVER_ENABLE */
/*@ +nullassign @*/
};
@@ -1141,6 +1192,8 @@ gps_mask_t nmea_parse(char *sentence, struct gps_device_t * session)
(void)strlcpy(session->gpsdata.tag,
nmea_phrase[i].name,
MAXTAGLEN);
+ if (nmea_phrase[i].cycle_continue)
+ session->driver.nmea.cycle_continue = true;
/*
* Must force this to be nz, as we're going to rely on a zero
* value to mean "no previous tag" later.
@@ -1192,7 +1245,7 @@ gps_mask_t nmea_parse(char *sentence, struct gps_device_t * session)
*/
if (session->driver.nmea.latch_frac_time) {
gpsd_report(LOG_PROG,
- "%s reporting cycle started on %.2f.\n",
+ "%s sentence timestamped %.2f.\n",
session->driver.nmea.field[0],
session->driver.nmea.this_frac_time);
if (!GPS_TIME_EQUAL
@@ -1206,25 +1259,42 @@ gps_mask_t nmea_parse(char *sentence, struct gps_device_t * session)
/*
* Have we seen a previously timestamped NMEA tag?
* If so, designate as end-of-cycle marker.
+ * But not if there are continuation sentences;
+ * those get sorted after the last timestamped sentence
*/
if (lasttag > 0
- && (session->driver.nmea.cycle_enders & (1 << lasttag)) ==
- 0) {
+ && (session->driver.nmea.cycle_enders & (1 << lasttag)) == 0
+ && !session->driver.nmea.cycle_continue) {
session->driver.nmea.cycle_enders |= (1 << lasttag);
gpsd_report(LOG_PROG,
"tagged %s as a cycle ender.\n",
nmea_phrase[lasttag - 1].name);
}
}
- /* here's where we check for end-of-cycle */
- if (session->driver.nmea.cycle_enders & (1 << thistag)) {
+ } else {
+ /* extend the cycle to an un-timestamped sentence? */
+ if ((session->driver.nmea.lasttag & session->driver.nmea.cycle_enders) != 0)
+ gpsd_report(LOG_PROG,
+ "%s is just after a cycle ender.\n",
+ session->driver.nmea.field[0]);
+ if (session->driver.nmea.cycle_continue) {
gpsd_report(LOG_PROG,
- "%s ends a reporting cycle.\n",
+ "%s extends the reporting cycle.\n",
session->driver.nmea.field[0]);
- retval |= REPORT_IS;
+ session->driver.nmea.cycle_enders &=~ (1 << session->driver.nmea.lasttag);
+ session->driver.nmea.cycle_enders |= (1 << thistag);
}
- session->driver.nmea.lasttag = thistag;
}
+ /* here's where we check for end-of-cycle */
+ if ((session->driver.nmea.latch_frac_time || session->driver.nmea.cycle_continue)
+ && session->driver.nmea.cycle_enders & (1 << thistag)) {
+ gpsd_report(LOG_PROG,
+ "%s ends a reporting cycle.\n",
+ session->driver.nmea.field[0]);
+ retval |= REPORT_IS;
+ }
+ if (session->driver.nmea.latch_frac_time)
+ session->driver.nmea.lasttag = thistag;
/* we might have a reliable end-of-cycle */
if (session->driver.nmea.cycle_enders != 0)
diff --git a/gpsd.h-tail b/gpsd.h-tail
index b5bf5229..6c36816c 100644
--- a/gpsd.h-tail
+++ b/gpsd.h-tail
@@ -26,7 +26,8 @@ typedef unsigned int speed_t;
* 3.5: POLL subobject name changes: fixes -> tpv, skyview -> sky.
* DEVICE::activated becomes ISO8601 rather thab real.
* 3.6 VERSION, WATCH, and DEVICES from slave gpsds get "remote" attribute.
- * 3.7 PPS message added to repertoire.
+ * 3.7 PPS message added to repertoire. SDDBT water depth reported as
+ * negative altitude with Mode 3 set.
*/
#define GPSD_PROTO_MAJOR_VERSION 3 /* bump on incompatible changes */
#define GPSD_PROTO_MINOR_VERSION 7 /* bump on compatible changes */
@@ -467,6 +468,7 @@ struct gps_device_t {
bool latch_frac_time;
unsigned int lasttag;
unsigned int cycle_enders;
+ bool cycle_continue;
#ifdef GPSCLOCK_ENABLE
bool ignore_trailing_edge;
#endif /* GPSCLOCK_ENABLE */
diff --git a/gpsd.xml b/gpsd.xml
index b44bd944..06bd1a25 100644
--- a/gpsd.xml
+++ b/gpsd.xml
@@ -859,11 +859,13 @@ several documents that collect publicly disclosed information about
the protocol.</para>
<para><application>gpsd</application> parses the following NMEA
-sentences: RMC, GGA, GLL, GSA, GSV, VTG, ZDA, GBS, HDT. It recognizes these
-with either the normal GP talker-ID prefix, or with the GN prefix used
-by GLONASS, or with the II prefix emitted by Seahawk Autohelm marine
-navigation systems, or with the IN prefix emitted by some Garmin
-units, or with the EC prefix emitted by ECDIS units. It recognizes
+sentences:
+RMC, GGA, GLL, GSA, GSV, VTG, ZDA, GBS, HDT, DBT.
+It recognizes these with either the normal GP talker-ID prefix, or
+with the GN prefix used by GLONASS, or with the II prefix emitted by
+Seahawk Autohelm marine navigation systems, or with the IN prefix
+emitted by some Garmin units, or with the EC prefix emitted by ECDIS
+units, or with the SD prefix emitted by depth sounders. It recognizes
some vendor extensions: the PGRME emitted by some Garmin GPS models,
the OHPR emitted by Oceanserver digital compasses, the PTNTHTM emitted
by True North digital compasses, and the PASHR sentences emitted by
diff --git a/packet.c b/packet.c
index fdc56c0c..938549da 100644
--- a/packet.c
+++ b/packet.c
@@ -96,6 +96,7 @@ PERMISSIONS
* II -- Integrated Instrumentation (Raytheon's SeaTalk system).
* IN -- Integrated Navigation (Garmin uses this).
* EC -- Electronic Chart Display & Information System (ECDIS)
+ * SD -- Depth Sounder
* P -- Vendor-specific sentence
*
*/
@@ -327,6 +328,8 @@ static void nextstate(struct gps_packet_t *lexer, unsigned char c)
lexer->state = SIRF_ACK_LEAD_1;
else if (c == 'E') /* ECDIS */
lexer->state = ECDIS_LEAD_1;
+ else if (c == 'S')
+ lexer->state = SOUNDER_LEAD_1;
#ifdef OCEANSERVER_ENABLE
else if (c == 'C')
lexer->state = NMEA_LEADER_END;
@@ -503,6 +506,12 @@ static void nextstate(struct gps_packet_t *lexer, unsigned char c)
else
lexer->state = GROUND_STATE;
break;
+ case SOUNDER_LEAD_1:
+ if (c == 'D') /* Depth-sounder leader accepted */
+ lexer->state = NMEA_LEADER_END;
+ else
+ lexer->state = GROUND_STATE;
+ break;
#ifdef TRIPMATE_ENABLE
case ASTRAL_1:
if (c == 'S') {
diff --git a/packet_states.h b/packet_states.h
index 800fb4e1..79a134e8 100644
--- a/packet_states.h
+++ b/packet_states.h
@@ -26,6 +26,7 @@
SEATALK_LEAD_1, /* SeaTalk/Garmin packet leader 'I' */
ECDIS_LEAD_1, /* ECDIS packet leader 'E' */
+ SOUNDER_LEAD_1, /* Depth sounder packet leader 'S' */
#endif /* NMEA_ENABLE */
DLE_LEADER, /* we've seen the TSIP/EverMore leader (DLE) */
diff --git a/test/daemon/sounder.log b/test/daemon/sounder.log
new file mode 100644
index 00000000..16364402
--- /dev/null
+++ b/test/daemon/sounder.log
@@ -0,0 +1,248 @@
+# Name: Generic depth sounder
+# Description: Generic depth sounder returning NMEA SDDBT
+# Submitted-by: John Hawley <johnhawley@blueyonder.co.uk>
+# Date: 2012-01-19
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.881,N,00125.169,E,164326,A,D*52
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+$ECGLL,5119.881,N,00125.169,E,164328,A,D*5C
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+$ECGLL,5119.881,N,00125.169,E,164330,A,D*55
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+$ECGLL,5119.881,N,00125.169,E,164332,A,D*57
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+$ECGLL,5119.881,N,00125.169,E,164334,A,D*51
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.881,N,00125.169,E,164336,A,D*53
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+$ECGLL,5119.881,N,00125.169,E,164338,A,D*5D
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+$ECGLL,5119.881,N,00125.169,E,164340,A,D*52
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.881,N,00125.169,E,164342,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164344,A,D*56
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164346,A,D*54
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164348,A,D*5A
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164350,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164352,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164354,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164356,A,D*55
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.881,N,00125.169,E,164358,A,D*5B
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+$ECGLL,5119.881,N,00125.169,E,164400,A,D*51
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.881,N,00125.169,E,164402,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164404,A,D*55
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164406,A,D*57
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164408,A,D*59
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164410,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164412,A,D*52
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164414,A,D*54
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164416,A,D*56
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164418,A,D*58
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164420,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164422,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164424,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164426,A,D*55
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164428,A,D*5B
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164430,A,D*52
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164432,A,D*50
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.881,N,00125.169,E,164434,A,D*56
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164436,A,D*54
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+$ECGLL,5119.881,N,00125.169,E,164438,A,D*5A
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+$ECGLL,5119.881,N,00125.169,E,164440,A,D*55
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.881,N,00125.169,E,164442,A,D*57
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164444,A,D*51
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164446,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164448,A,D*5D
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164450,A,D*54
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164452,A,D*56
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164454,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164456,A,D*52
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+$ECGLL,5119.881,N,00125.169,E,164458,A,D*5C
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164500,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164502,A,D*52
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164504,A,D*54
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164506,A,D*56
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164508,A,D*58
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164510,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164512,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164514,A,D*55
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164516,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164518,A,D*59
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164520,A,D*52
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164522,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164524,A,D*56
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164526,A,D*54
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164528,A,D*5A
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164530,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164532,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164534,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164536,A,D*55
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.881,N,00125.169,E,164538,A,D*5B
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164540,A,D*54
+$SDDBT,8.1,f,2.5,M,1.4,F*0D
+$ECGLL,5119.881,N,00125.169,E,164542,A,D*56
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164544,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164546,A,D*52
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164548,A,D*5C
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164550,A,D*55
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164552,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164554,A,D*51
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+$ECGLL,5119.881,N,00125.169,E,164556,A,D*53
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+$ECGLL,5119.881,N,00125.169,E,164558,A,D*5D
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164600,A,D*53
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164602,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164604,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164606,A,D*55
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164608,A,D*5B
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164610,A,D*52
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164612,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164614,A,D*56
+$SDDBT,8.1,f,2.5,M,1.4,F*0D
+$ECGLL,5119.881,N,00125.169,E,164616,A,D*54
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.169,E,164618,A,D*5A
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164620,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.169,E,164622,A,D*53
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+$ECGLL,5119.881,N,00125.169,E,164624,A,D*55
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+$ECGLL,5119.881,N,00125.169,E,164626,A,D*57
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.881,N,00125.169,E,164628,A,D*59
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.168,E,164630,A,D*51
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.881,N,00125.168,E,164632,A,D*53
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.168,E,164634,A,D*55
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+$ECGLL,5119.881,N,00125.168,E,164636,A,D*57
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.168,E,164638,A,D*59
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.168,E,164640,A,D*56
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.168,E,164642,A,D*54
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.168,E,164644,A,D*52
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.168,E,164646,A,D*50
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.881,N,00125.168,E,164648,A,D*5E
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.168,E,164650,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.168,E,164652,A,D*55
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.168,E,164654,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.168,E,164656,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.168,E,164658,A,D*5F
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.881,N,00125.168,E,164700,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.881,N,00125.168,E,164702,A,D*51
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+$ECGLL,5119.881,N,00125.168,E,164704,A,D*57
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.882,N,00125.168,E,164706,A,D*56
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.882,N,00125.168,E,164708,A,D*58
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.882,N,00125.168,E,164710,A,D*51
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+$ECGLL,5119.882,N,00125.168,E,164712,A,D*53
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.882,N,00125.168,E,164714,A,D*55
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.882,N,00125.168,E,164716,A,D*57
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.882,N,00125.168,E,164718,A,D*59
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+$ECGLL,5119.882,N,00125.168,E,164720,A,D*52
+$SDDBT,8.0,f,2.4,M,1.3,F*0A
+$ECGLL,5119.882,N,00125.168,E,164722,A,D*50
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.882,N,00125.168,E,164724,A,D*56
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+$ECGLL,5119.882,N,00125.168,E,164726,A,D*54
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+$ECGLL,5119.882,N,00125.168,E,164728,A,D*5A
diff --git a/test/daemon/sounder.log.chk b/test/daemon/sounder.log.chk
new file mode 100644
index 00000000..9d86b41f
--- /dev/null
+++ b/test/daemon/sounder.log.chk
@@ -0,0 +1,366 @@
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164326,A,D*52
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164328,A,D*5C
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164330,A,D*55
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164332,A,D*57
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164334,A,D*51
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164336,A,D*53
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164338,A,D*5D
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164340,A,D*52
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164342,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164344,A,D*56
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164346,A,D*54
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164348,A,D*5A
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164350,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164352,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164354,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164356,A,D*55
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164358,A,D*5B
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164400,A,D*51
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164402,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164404,A,D*55
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164406,A,D*57
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164408,A,D*59
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164410,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164412,A,D*52
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164414,A,D*54
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164416,A,D*56
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164418,A,D*58
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164420,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164422,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164424,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164426,A,D*55
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164428,A,D*5B
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164430,A,D*52
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164432,A,D*50
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164434,A,D*56
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164436,A,D*54
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164438,A,D*5A
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164440,A,D*55
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164442,A,D*57
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164444,A,D*51
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164446,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164448,A,D*5D
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164450,A,D*54
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164452,A,D*56
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164454,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164456,A,D*52
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164458,A,D*5C
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164500,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164502,A,D*52
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164504,A,D*54
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164506,A,D*56
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164508,A,D*58
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164510,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164512,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164514,A,D*55
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164516,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164518,A,D*59
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164520,A,D*52
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164522,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164524,A,D*56
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164526,A,D*54
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164528,A,D*5A
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164530,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164532,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164534,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164536,A,D*55
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164538,A,D*5B
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164540,A,D*54
+$SDDBT,8.1,f,2.5,M,1.4,F*0D
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.500}
+$ECGLL,5119.881,N,00125.169,E,164542,A,D*56
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164544,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164546,A,D*52
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164548,A,D*5C
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164550,A,D*55
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164552,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164554,A,D*51
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164556,A,D*53
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164558,A,D*5D
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164600,A,D*53
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164602,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164604,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164606,A,D*55
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164608,A,D*5B
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164610,A,D*52
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164612,A,D*50
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164614,A,D*56
+$SDDBT,8.1,f,2.5,M,1.4,F*0D
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.500}
+$ECGLL,5119.881,N,00125.169,E,164616,A,D*54
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164618,A,D*5A
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164620,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164622,A,D*53
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164624,A,D*55
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.400}
+$ECGLL,5119.881,N,00125.169,E,164626,A,D*57
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.169,E,164628,A,D*59
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419483333,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164630,A,D*51
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164632,A,D*53
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164634,A,D*55
+$SDDBT,7.9,f,2.4,M,1.3,F*0C
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.400}
+$ECGLL,5119.881,N,00125.168,E,164636,A,D*57
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164638,A,D*59
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164640,A,D*56
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164642,A,D*54
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164644,A,D*52
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164646,A,D*50
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164648,A,D*5E
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164650,A,D*57
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164652,A,D*55
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164654,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164656,A,D*51
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164658,A,D*5F
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164700,A,D*53
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.881,N,00125.168,E,164702,A,D*51
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.400}
+$ECGLL,5119.881,N,00125.168,E,164704,A,D*57
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331350000,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.882,N,00125.168,E,164706,A,D*56
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331366667,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.882,N,00125.168,E,164708,A,D*58
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331366667,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.882,N,00125.168,E,164710,A,D*51
+$SDDBT,7.8,f,2.4,M,1.3,F*0D
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331366667,"lon":1.419466667,"alt":-2.400}
+$ECGLL,5119.882,N,00125.168,E,164712,A,D*53
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331366667,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.882,N,00125.168,E,164714,A,D*55
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331366667,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.882,N,00125.168,E,164716,A,D*57
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331366667,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.882,N,00125.168,E,164718,A,D*59
+$SDDBT,7.5,f,2.3,M,1.3,F*07
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331366667,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.882,N,00125.168,E,164720,A,D*52
+$SDDBT,8.0,f,2.4,M,1.3,F*0A
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331366667,"lon":1.419466667,"alt":-2.400}
+$ECGLL,5119.882,N,00125.168,E,164722,A,D*50
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331366667,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.882,N,00125.168,E,164724,A,D*56
+$SDDBT,7.7,f,2.3,M,1.3,F*05
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331366667,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.882,N,00125.168,E,164726,A,D*54
+$SDDBT,7.6,f,2.3,M,1.3,F*04
+{"class":"TPV","tag":"DBT","mode":3,"lat":51.331366667,"lon":1.419466667,"alt":-2.300}
+$ECGLL,5119.882,N,00125.168,E,164728,A,D*5A
diff --git a/www/NMEA.txt b/www/NMEA.txt
index d09a8861..73014765 100644
--- a/www/NMEA.txt
+++ b/www/NMEA.txt
@@ -705,6 +705,7 @@ Field Number:
7. Checksum
In real-world sensors, sometimes not all three conversions are reported.
+So you night see something like $SDDBT,,f,22.5,M,,F*cs
=== DCN - Decca Position ===