New version of build() with more sentences
move addChecksum() to NMEA_build.cpp
This commit is contained in:
parent
0b0996bbb0
commit
4b6e181770
|
|
@ -159,27 +159,6 @@ bool Adafruit_GPS::isEmpty(char *pStart) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************/
|
|
||||||
/*!
|
|
||||||
@brief Add *CS where CS is the two character hex checksum for all but
|
|
||||||
the first character in the string. The checksum is the result of an
|
|
||||||
exclusive or of all the characters in the string. Also useful if you
|
|
||||||
are creating new PMTK strings for controlling a GPS module and need a
|
|
||||||
checksum added.
|
|
||||||
@param buff Pointer to the string, which must be long enough
|
|
||||||
@return none
|
|
||||||
*/
|
|
||||||
/**************************************************************************/
|
|
||||||
void Adafruit_GPS::addChecksum(char *buff) {
|
|
||||||
char cs = 0;
|
|
||||||
int i = 1;
|
|
||||||
while (buff[i]) {
|
|
||||||
cs ^= buff[i];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
sprintf(buff, "%s*%02X", buff, cs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/*!
|
/*!
|
||||||
@brief Parse a part of an NMEA string for time
|
@brief Parse a part of an NMEA string for time
|
||||||
|
|
|
||||||
|
|
@ -44,11 +44,17 @@
|
||||||
extension to building proprietary sentences like $PMTK220,100*2F.
|
extension to building proprietary sentences like $PMTK220,100*2F.
|
||||||
|
|
||||||
build() will not work properly in an environment that does not support
|
build() will not work properly in an environment that does not support
|
||||||
the %f floating point formatter in sprintf(), and will return NULL.
|
the %f floating point formatter in sprintf(), and will return NULL.
|
||||||
|
Floating point arguments to sprintf() are explicitly cast to double to
|
||||||
|
avoid warnings in some compilers.
|
||||||
|
|
||||||
build() adds Carriage Return and Line Feed to sentences to conform to
|
build() adds Carriage Return and Line Feed to sentences to conform to
|
||||||
NMEA-183, so send your output with a print, not a println.
|
NMEA-183, so send your output with a print, not a println.
|
||||||
|
|
||||||
|
The resulting sentence may be corrupted if the input data is corrupt.
|
||||||
|
In particular, the sentence will be truncated if any of the character
|
||||||
|
data is 0, e.g. if lat is not set to 'N' or 'S'.
|
||||||
|
|
||||||
Some of the data in these test sentences may be arbitrary, e.g. for the
|
Some of the data in these test sentences may be arbitrary, e.g. for the
|
||||||
TXT sentence which has a more complicated protocol for multiple lines
|
TXT sentence which has a more complicated protocol for multiple lines
|
||||||
sent as a message set. Also, the data in the class variables are presumed
|
sent as a message set. Also, the data in the class variables are presumed
|
||||||
|
|
@ -66,7 +72,7 @@
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
char *Adafruit_GPS::build(char *nmea, const char *thisSource,
|
char *Adafruit_GPS::build(char *nmea, const char *thisSource,
|
||||||
const char *thisSentence, char ref) {
|
const char *thisSentence, char ref) {
|
||||||
sprintf(nmea, "%6.2f", 123.45); // fail if sprintf() doesn't handle floats
|
sprintf(nmea, "%6.2f", (double)123.45); // fail if sprintf() doesn't handle floats
|
||||||
if (strcmp(nmea, "123.45"))
|
if (strcmp(nmea, "123.45"))
|
||||||
return NULL;
|
return NULL;
|
||||||
*nmea = '$';
|
*nmea = '$';
|
||||||
|
|
@ -82,8 +88,7 @@ char *Adafruit_GPS::build(char *nmea, const char *thisSource,
|
||||||
// pruning excess code easier. Otherwise, keep them alphabetical for ease of
|
// pruning excess code easier. Otherwise, keep them alphabetical for ease of
|
||||||
// reading.
|
// reading.
|
||||||
|
|
||||||
if (!strcmp(thisSentence,
|
if (!strcmp(thisSentence, "GGA")) { //************************************GGA
|
||||||
"GGA")) { //********************************************GGA
|
|
||||||
// GGA Global Positioning System Fix Data. Time, Position and fix related
|
// GGA Global Positioning System Fix Data. Time, Position and fix related
|
||||||
// data for a GPS receiver
|
// data for a GPS receiver
|
||||||
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||||
|
|
@ -107,12 +112,11 @@ char *Adafruit_GPS::build(char *nmea, const char *thisSource,
|
||||||
// 14) Differential reference station ID, 0000-1023
|
// 14) Differential reference station ID, 0000-1023
|
||||||
// 15) Checksum
|
// 15) Checksum
|
||||||
sprintf(p, "%09.2f,%09.4f,%c,%010.4f,%c,%d,%02d,%f,%f,M,%f,M,,",
|
sprintf(p, "%09.2f,%09.4f,%c,%010.4f,%c,%d,%02d,%f,%f,M,%f,M,,",
|
||||||
hour * 10000L + minute * 100L + seconds + milliseconds / 1000.,
|
(double)hour * 10000L + minute * 100L + seconds + milliseconds / 1000.,
|
||||||
(double)latitude, lat, (double)longitude, lon, fixquality,
|
(double)latitude, lat, (double)longitude, lon, fixquality, satellites,
|
||||||
satellites, (double)HDOP, (double)altitude, (double)geoidheight);
|
(double)HDOP, (double)altitude, (double)geoidheight);
|
||||||
|
|
||||||
} else if (!strcmp(thisSentence,
|
} else if (!strcmp(thisSentence, "GLL")) { //*****************************GLL
|
||||||
"GLL")) { //********************************************GLL
|
|
||||||
// GLL Geographic Position – Latitude/Longitude
|
// GLL Geographic Position – Latitude/Longitude
|
||||||
// 1 2 3 4 5 6 7
|
// 1 2 3 4 5 6 7
|
||||||
// | | | | | | |
|
// | | | | | | |
|
||||||
|
|
@ -125,11 +129,10 @@ char *Adafruit_GPS::build(char *nmea, const char *thisSource,
|
||||||
// 6) Status A - Data Valid, V - Data Invalid
|
// 6) Status A - Data Valid, V - Data Invalid
|
||||||
// 7) Checksum
|
// 7) Checksum
|
||||||
sprintf(p, "%09.4f,%c,%010.4f,%c,%09.2f,A", (double)latitude, lat,
|
sprintf(p, "%09.4f,%c,%010.4f,%c,%09.2f,A", (double)latitude, lat,
|
||||||
(double)longitude, lon,
|
(double)longitude, lon, (double)hour * 10000L + minute * 100L +
|
||||||
hour * 10000L + minute * 100L + seconds + milliseconds / 1000.);
|
seconds + milliseconds / 1000.);
|
||||||
|
|
||||||
} else if (!strcmp(thisSentence,
|
} else if (!strcmp(thisSentence, "GSA")) { //*****************************GSA
|
||||||
"GSA")) { //********************************************
|
|
||||||
// GSA GPS DOP and active satellites
|
// GSA GPS DOP and active satellites
|
||||||
// 1 2 3 14 15 16 17 18
|
// 1 2 3 14 15 16 17 18
|
||||||
// | | | | | | | |
|
// | | | | | | | |
|
||||||
|
|
@ -146,8 +149,7 @@ char *Adafruit_GPS::build(char *nmea, const char *thisSource,
|
||||||
// 18) Checksum
|
// 18) Checksum
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
} else if (!strcmp(thisSentence,
|
} else if (!strcmp(thisSentence, "RMC")) { //*****************************RMC
|
||||||
"RMC")) { //********************************************RMC
|
|
||||||
// RMC Recommended Minimum Navigation Information
|
// RMC Recommended Minimum Navigation Information
|
||||||
// 12
|
// 12
|
||||||
// 1 2 3 4 5 6 7 8 9 10 11 |
|
// 1 2 3 4 5 6 7 8 9 10 11 |
|
||||||
|
|
@ -166,13 +168,255 @@ char *Adafruit_GPS::build(char *nmea, const char *thisSource,
|
||||||
// 11) E or W
|
// 11) E or W
|
||||||
// 12) Checksum
|
// 12) Checksum
|
||||||
sprintf(p, "%09.2f,A,%09.4f,%c,%010.4f,%c,%f,%f,%06d,%f,%c",
|
sprintf(p, "%09.2f,A,%09.4f,%c,%010.4f,%c,%f,%f,%06d,%f,%c",
|
||||||
hour * 10000L + minute * 100L + seconds + milliseconds / 1000.,
|
(double)hour * 10000L + minute * 100L + seconds + milliseconds / 1000.,
|
||||||
(double)latitude, lat, (double)longitude, lon, (double)speed,
|
(double)latitude, lat, (double)longitude, lon, (double)speed,
|
||||||
(double)angle, day * 10000 + month * 100 + year,
|
(double)angle, day * 10000 + month * 100 + year, (double)magvariation, mag);
|
||||||
(double)magvariation, mag);
|
|
||||||
|
|
||||||
} else if (!strcmp(thisSentence,
|
} else if (!strcmp(thisSentence, "APB")) { //*****************************APB
|
||||||
"TXT")) { //********************************************TXT
|
// APB Autopilot Sentence "B"
|
||||||
|
// 13 15
|
||||||
|
// 1 2 3 4 5 6 7 8 9 10 11 12 | 14 |
|
||||||
|
// | | | | | | | | | | | | | | |
|
||||||
|
//$--APB,A,A,x.x,a,N,A,A,x.x,a,c--c,x.x,a,x.x,a*hh
|
||||||
|
// 1) Status
|
||||||
|
// V = LORAN-C Blink or SNR warning
|
||||||
|
// A = general warning flag or other navigation systems when a reliable
|
||||||
|
// fix is not available
|
||||||
|
// 2) Status
|
||||||
|
// V = Loran-C Cycle Lock warning flag
|
||||||
|
// A = OK or not used
|
||||||
|
// 3) Cross Track Error Magnitude
|
||||||
|
// 4) Direction to steer, L or R
|
||||||
|
// 5) Cross Track Units, N = Nautical Miles
|
||||||
|
// 6) Status
|
||||||
|
// A = Arrival Circle Entered
|
||||||
|
// 7) Status
|
||||||
|
// A = Perpendicular passed at waypoint
|
||||||
|
// 8) Bearing origin to destination
|
||||||
|
// 9) M = Magnetic, T = True
|
||||||
|
// 10) Destination Waypoint ID
|
||||||
|
// 11) Bearing, present position to Destination
|
||||||
|
// 12) M = Magnetic, T = True
|
||||||
|
// 13) Heading to steer to destination waypoint
|
||||||
|
// 14) M = Magnetic, T = True
|
||||||
|
// 15) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "DBK")) { //*****************************DBT
|
||||||
|
// DBK Depth Below Keel
|
||||||
|
// 1 2 3 4 5 6 7
|
||||||
|
// | | | | | | |
|
||||||
|
//$--DBK,x.x,f,x.x,M,x.x,F*hh
|
||||||
|
// 1) Depth, feet
|
||||||
|
// 2) f = feet
|
||||||
|
// 3) Depth, meters
|
||||||
|
// 4) M = meters
|
||||||
|
// 5) Depth, Fathoms
|
||||||
|
// 6) F = Fathoms
|
||||||
|
// 7) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "DBS")) { //*****************************DBT
|
||||||
|
// DBS Depth Below Surface
|
||||||
|
// 1 2 3 4 5 6 7
|
||||||
|
// | | | | | | |
|
||||||
|
//$--DBS,x.x,f,x.x,M,x.x,F*hh
|
||||||
|
// 1) Depth, feet
|
||||||
|
// 2) f = feet
|
||||||
|
// 3) Depth, meters
|
||||||
|
// 4) M = meters
|
||||||
|
// 5) Depth, Fathoms
|
||||||
|
// 6) F = Fathoms
|
||||||
|
// 7) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "DBT")) { //*****************************DBT
|
||||||
|
// DBT Depth Below Transducer
|
||||||
|
// 1 2 3 4 5 6 7
|
||||||
|
// | | | | | | |
|
||||||
|
//$--DBT,x.x,f,x.x,M,x.x,F*hh
|
||||||
|
// 1) Depth, feet
|
||||||
|
// 2) f = feet
|
||||||
|
// 3) Depth, meters
|
||||||
|
// 4) M = meters
|
||||||
|
// 5) Depth, Fathoms
|
||||||
|
// 6) F = Fathoms
|
||||||
|
// 7) Checksum
|
||||||
|
double d = val[NMEA_DEPTH].latest - depthToTransducer;
|
||||||
|
sprintf(p, "%f,f,%f,M,,,", d / 0.3048, d);
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "DPT")) { //*****************************DPT
|
||||||
|
// DPT Heading – Deviation & Variation
|
||||||
|
// 1 2 3
|
||||||
|
// | | |
|
||||||
|
//$--DPT,x.x,x.x*hh
|
||||||
|
// 1) Depth, meters
|
||||||
|
// 2) Offset from transducer;
|
||||||
|
// positive means distance from transducer to water line,
|
||||||
|
// negative means distance from transducer to keel
|
||||||
|
// 3) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "GSV")) { //*****************************GSV
|
||||||
|
// GSV Satellites in view
|
||||||
|
// 1 2 3 4 5 6 7 n
|
||||||
|
// | | | | | | | |
|
||||||
|
//$--GSV,x,x,x,x,x,x,x,...*hh
|
||||||
|
// 1) total number of messages
|
||||||
|
// 2) message number
|
||||||
|
// 3) satellites in view
|
||||||
|
// 4) satellite number
|
||||||
|
// 5) elevation in degrees
|
||||||
|
// 6) azimuth in degrees to true
|
||||||
|
// 7) SNR in dB
|
||||||
|
// more satellite infos like 4)-7)
|
||||||
|
// n) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "HDG")) { //*****************************HDG
|
||||||
|
// HDG Heading – Deviation & Variation
|
||||||
|
// 1 2 3 4 5 6
|
||||||
|
// | | | | | |
|
||||||
|
//$--HDG,x.x,x.x,a,x.x,a*hh
|
||||||
|
// 1) Magnetic Sensor heading in degrees
|
||||||
|
// 2) Magnetic Deviation, degrees
|
||||||
|
// 3) Magnetic Deviation direction, E = Easterly, W = Westerly
|
||||||
|
// 4) Magnetic Variation degrees
|
||||||
|
// 5) Magnetic Variation direction, E = Easterly, W = Westerly
|
||||||
|
// 6) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "HDM")) { //*****************************HDM
|
||||||
|
// HDM Heading – Magnetic
|
||||||
|
// 1 2 3
|
||||||
|
// | | |
|
||||||
|
//$--HDM,x.x,M*hh
|
||||||
|
// 1) Heading Degrees, magnetic
|
||||||
|
// 2) M = magnetic
|
||||||
|
// 3) Checksum
|
||||||
|
sprintf(p, "%f,M", (double)val[NMEA_HDG].latest);
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "HDT")) { //*****************************HDT
|
||||||
|
// HDT Heading – True
|
||||||
|
// 1 2 3
|
||||||
|
// | | |
|
||||||
|
//$--HDT,x.x,T*hh
|
||||||
|
// 1) Heading Degrees, true
|
||||||
|
// 2) T = True
|
||||||
|
// 3) Checksum
|
||||||
|
// starts with $II for integrated instrumentation
|
||||||
|
sprintf(p, "%f,T", (double)val[NMEA_HDT].latest);
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "MDA")) { //*****************************MDA
|
||||||
|
// MDA Meteorological Composite
|
||||||
|
// 1 2 3 4 5 6 7 8 9 10 11 12
|
||||||
|
// | | | | | | | | | | | |
|
||||||
|
//$__MDA,x.x,I,x.x,B,x.x,C,x.x,C,x.x, ,x.x,C,,T,,M,,N,,M*hh
|
||||||
|
//$IIMDA,,I,,B,,C,21.8,C,,,,C,,T,,M,,N,,M*0F // sent by RayMarine i70s
|
||||||
|
// Speed/Depth/Wind
|
||||||
|
// 1) Barometric Pressure
|
||||||
|
// 2) inches of Hg
|
||||||
|
// 3) Barometric Pressure
|
||||||
|
// 4) bar
|
||||||
|
// 5) Atmospheric Temperature
|
||||||
|
// 6) C or F
|
||||||
|
// 7) Water Temperature
|
||||||
|
// 8) C or F
|
||||||
|
// 9) Relative Humidity
|
||||||
|
// 10)
|
||||||
|
// 11) Dew Point
|
||||||
|
// 12) C or F
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "MTW")) { //*****************************MTW
|
||||||
|
// MTW Water Temperature
|
||||||
|
// 1 2 3
|
||||||
|
// | | |
|
||||||
|
//$IIMTW,x.x,C*hh
|
||||||
|
//$IIMTW,21.8,C*18 // sent by RayMarine i70s Speed/Depth/Wind
|
||||||
|
// 1) Degrees
|
||||||
|
// 2) Unit of Measurement, Celcius
|
||||||
|
// 3) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "MWD")) { //*****************************MWD
|
||||||
|
// MWD Wind Direction & Speed
|
||||||
|
// Format unknown
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "MWV")) { //*****************************MWV
|
||||||
|
// MWV Wind Speed and Angle assuming values for True
|
||||||
|
// 1 2 3 4 5 6
|
||||||
|
// | | | | | |
|
||||||
|
//$IIMWV,x.x,a,x.x,a,a*hh
|
||||||
|
//$WIMWV,276.94,R,0,N,A*03 // sent by RayMarine i70s Speed/Depth/Wind
|
||||||
|
// 1) Wind Angle, 0 to 360 degrees
|
||||||
|
// 2) Reference, R = Relative, T = True
|
||||||
|
// 3) Wind Speed
|
||||||
|
// 4) Wind Speed Units, K/M/N kilometers/miles/knots
|
||||||
|
// 5) Status, A = Data Valid
|
||||||
|
// 6) Checksum
|
||||||
|
if (ref == 'R')
|
||||||
|
sprintf(p, "%f,%c,%f,N,A", (double)val[NMEA_AWA].latest, ref,
|
||||||
|
(double)val[NMEA_AWS].latest);
|
||||||
|
else
|
||||||
|
sprintf(p, "%f,%c,%f,N,A", (double)val[NMEA_TWA].latest, 'T',
|
||||||
|
(double)val[NMEA_TWS].latest);
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "RMB")) { //*****************************RMB
|
||||||
|
// RMB Recommended Minimum Navigation Information
|
||||||
|
// 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||||
|
// | | | | | | | | | | | | | |
|
||||||
|
//$--RMB,A,x.x,a,c--c,c--c,llll.ll,a,yyyyy.yy,a,x.x,x.x,x.x,A*hh
|
||||||
|
// 1) Status, V = Navigation receiver warning
|
||||||
|
// 2) Cross Track error - nautical miles
|
||||||
|
// 3) Direction to Steer, Left or Right
|
||||||
|
// 4) TO Waypoint ID
|
||||||
|
// 5) FROM Waypoint ID
|
||||||
|
// 6) Destination Waypoint Latitude 7) N or S
|
||||||
|
// 8) Destination Waypoint Longitude 9) E or W
|
||||||
|
// 10) Range to destination in nautical miles
|
||||||
|
// 11) Bearing to destination in degrees True
|
||||||
|
// 12) Destination closing velocity in knots
|
||||||
|
// 13) Arrival Status, A = Arrival Circle Entered 14) Checksum
|
||||||
|
sprintf(p, ",,,,,,,,,,,%f,A", (double)val[NMEA_VMGWP].latest);
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "ROT")) { //*****************************ROT
|
||||||
|
// ROT Rate Of Turn
|
||||||
|
// 1 2 3
|
||||||
|
// | | |
|
||||||
|
//$--ROT,x.x,A*hh
|
||||||
|
// 1) Rate Of Turn, degrees per minute, "-" means bow turns to port
|
||||||
|
// 2) Status, A means data is valid
|
||||||
|
// 3) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "RPM")) { //*****************************RPM
|
||||||
|
// RPM Revolutions
|
||||||
|
// 1 2 3 4 5 6
|
||||||
|
// | | | | | |
|
||||||
|
//$--RPM,a,x,x.x,x.x,A*hh
|
||||||
|
// 1) Source; S = Shaft, E = Engine
|
||||||
|
// 2) Engine or shaft number
|
||||||
|
// 3) Speed, Revolutions per minute
|
||||||
|
// 4) Propeller pitch, % of maximum, "-" means astern
|
||||||
|
// 5) Status, A means data is valid
|
||||||
|
// 6) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "RSA")) { //*****************************RSA
|
||||||
|
// RSA Rudder Sensor Angle
|
||||||
|
// 1 2 3 4 5
|
||||||
|
// | | | | |
|
||||||
|
//$--RSA,x.x,A,x.x,A*hh
|
||||||
|
// 1) Starboard (or single) rudder sensor, "-" means Turn To Port
|
||||||
|
// 2) Status, A means data is valid
|
||||||
|
// 3) Port rudder sensor
|
||||||
|
// 4) Status, A means data is valid
|
||||||
|
// 5) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "TXT")) { //*****************************TXT
|
||||||
// as mentioned in https://github.com/adafruit/Adafruit_GPS/issues/95
|
// as mentioned in https://github.com/adafruit/Adafruit_GPS/issues/95
|
||||||
// TXT Text Transmission
|
// TXT Text Transmission
|
||||||
// 1 2 3 4 5
|
// 1 2 3 4 5
|
||||||
|
|
@ -185,6 +429,136 @@ char *Adafruit_GPS::build(char *nmea, const char *thisSource,
|
||||||
// 5) Checksum
|
// 5) Checksum
|
||||||
sprintf(p, "01,01,23,This is the text of the sample message");
|
sprintf(p, "01,01,23,This is the text of the sample message");
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "VDR")) { //*****************************VDR
|
||||||
|
// VDR Set and Drift
|
||||||
|
// 1 2 3 4 5 6 7
|
||||||
|
// | | | | | | |
|
||||||
|
//$--VDR,x.x,T,x.x,M,x.x,N*hh
|
||||||
|
// 1) Degress True
|
||||||
|
// 2) T = True
|
||||||
|
// 3) Degrees Magnetic
|
||||||
|
// 4) M = Magnetic
|
||||||
|
// 5) Knots (speed of current)
|
||||||
|
// 6) N = Knots
|
||||||
|
// 7) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "VHW")) { //*****************************VHW
|
||||||
|
// VHW Water Speed and Heading
|
||||||
|
// 1 2 3 4 5 6 7 8 9
|
||||||
|
// | | | | | | | | |
|
||||||
|
//$--VHW,x.x,T,x.x,M,x.x,N,x.x,K*hh
|
||||||
|
//$IIVHW,,T,,M,0,N,0,K*55 // sent by RayMarine i70s Speed/Depth/Wind
|
||||||
|
// 1) Degrees True
|
||||||
|
// 2) T = True
|
||||||
|
// 3) Degrees Magnetic
|
||||||
|
// 4) M = Magnetic
|
||||||
|
// 5) Knots (speed of vessel relative to the water) [66]
|
||||||
|
// 6) N = Knots
|
||||||
|
// 7) Kilometers (speed of vessel relative to the water)
|
||||||
|
// 8) K = Kilometres
|
||||||
|
// 9) Checksum
|
||||||
|
sprintf(p, "%f,T,%f,M,%f,N,%f,K", (double)val[NMEA_HDT].latest,
|
||||||
|
(double)val[NMEA_HDG].latest, (double)val[NMEA_VTW].latest,
|
||||||
|
(double)val[NMEA_VTW].latest * 1.829);
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "VLW")) { //*****************************VLW
|
||||||
|
// VLW Distance Traveled through Water
|
||||||
|
// 1 2 3 4 5
|
||||||
|
// | | | | |
|
||||||
|
//$--VLW,x.x,N,x.x,N*hh
|
||||||
|
//$IIVLW,0,N,0,N,,N,,N*4D // sent by RayMarine i70s Speed/Depth/Wind
|
||||||
|
// not sure what the last two are?
|
||||||
|
// 1) Total cumulative distance
|
||||||
|
// 2) N = Nautical Miles
|
||||||
|
// 3) Distance since Reset
|
||||||
|
// 4) N = Nautical Miles
|
||||||
|
// 5) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "VPW")) { //*****************************VPW
|
||||||
|
// not supported by iNavX
|
||||||
|
// VPW Speed – Measured Parallel to Wind
|
||||||
|
// 1 2 3 4 5
|
||||||
|
// | | | | |
|
||||||
|
//$--VPW,x.x,N,x.x,M*hh
|
||||||
|
// 1) Speed, "-" means downwind
|
||||||
|
// 2) N = Knots
|
||||||
|
// 3) Speed, "-" means downwind
|
||||||
|
// 4) M = Meters per second
|
||||||
|
// 5) Checksum
|
||||||
|
sprintf(p, "%f,N,,", (double)val[NMEA_VMG].latest);
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "VTG")) { //*****************************VTG
|
||||||
|
// VTG Track Made Good and Ground Speed
|
||||||
|
// 1 2 3 4 5 6 7 8 9
|
||||||
|
// | | | | | | | | |
|
||||||
|
//$--VTG,x.x,T,x.x,M,x.x,N,x.x,K*hh
|
||||||
|
// 1) Track Degrees 2) T = True
|
||||||
|
// 3) Track Degrees 4) M = Magnetic
|
||||||
|
// 5) Speed Knots 6) N = Knots
|
||||||
|
// 7) Speed Kilometers Per Hour 8) K = Kilometres Per Hour
|
||||||
|
// 9) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "VWR")) { //*****************************VWR
|
||||||
|
// VWR Relative Wind Speed and Angle
|
||||||
|
// 1 2 3 4 5 6 7 8 9
|
||||||
|
// | | | | | | | | |
|
||||||
|
//$--VWR,x.x,a,x.x,N,x.x,M,x.x,K*hh
|
||||||
|
//$WIVWR,83.1,L,0,N,0,M,0,K*6D // sent by RayMarine i70s
|
||||||
|
// Speed/Depth/Wind
|
||||||
|
// 1) Wind direction magnitude in degrees
|
||||||
|
// 2) Wind direction Left/Right of bow
|
||||||
|
// 3) Speed
|
||||||
|
// 4) N = Knots
|
||||||
|
// 5) Speed
|
||||||
|
// 6) M = Meters Per Second
|
||||||
|
// 7) Speed
|
||||||
|
// 8) K = Kilometers Per Hour
|
||||||
|
// 9) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "WCV")) { //*****************************WCV
|
||||||
|
// WCV Waypoint Closure Velocity
|
||||||
|
// 1 2 3 4
|
||||||
|
// | | | |
|
||||||
|
//$--WCV,x.x,N,c--c*hh
|
||||||
|
// 1) Velocity 2) N = knots 3) Waypoint ID 4) Checksum
|
||||||
|
sprintf(p, "%f,N,home", (double)val[NMEA_VMG].latest);
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "XTE")) { //*****************************XTE
|
||||||
|
// XTE Cross-Track Error – Measured
|
||||||
|
// 1 2 3 4 5 6
|
||||||
|
// | | | | | |
|
||||||
|
//$--XTE,A,A,x.x,a,N,*hh
|
||||||
|
// 1) Status
|
||||||
|
// V = LORAN-C blink or SNR warning
|
||||||
|
// A = general warning flag or other navigation systems when a reliable
|
||||||
|
// fix is not available
|
||||||
|
// 2) Status
|
||||||
|
// V = Loran-C cycle lock warning flag
|
||||||
|
// A = OK or not used
|
||||||
|
// 3) Cross track error magnitude
|
||||||
|
// 4) Direction to steer, L or R
|
||||||
|
// 5) Cross track units. N = Nautical Miles
|
||||||
|
// 6) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
} else if (!strcmp(thisSentence, "ZDA")) { //*****************************ZDA
|
||||||
|
// ZDA Time & Date – UTC, Day, Month, Year and Local Time Zone
|
||||||
|
// 1 2 3 4 5 6 7
|
||||||
|
// | | | | | | |
|
||||||
|
//$--ZDA,hhmmss.ss,xx,xx,xxxx,xx,xx*hh
|
||||||
|
// 1) Local zone minutes description, same sign as local hours
|
||||||
|
// 2) Local zone description, 00 to +/- 13 hours
|
||||||
|
// 3) Year
|
||||||
|
// 4) Month, 01 to 12
|
||||||
|
// 5) Day, 01 to 31
|
||||||
|
// 6) Time (UTC)
|
||||||
|
// 7) Checksum
|
||||||
|
return NULL;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return NULL; // didn't find a match for the build request
|
return NULL; // didn't find a match for the build request
|
||||||
}
|
}
|
||||||
|
|
@ -196,3 +570,24 @@ char *Adafruit_GPS::build(char *nmea, const char *thisSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // NMEA_EXTENSIONS
|
#endif // NMEA_EXTENSIONS
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
/*!
|
||||||
|
@brief Add *CS where CS is the two character hex checksum for all but
|
||||||
|
the first character in the string. The checksum is the result of an
|
||||||
|
exclusive or of all the characters in the string. Also useful if you
|
||||||
|
are creating new PMTK strings for controlling a GPS module and need a
|
||||||
|
checksum added.
|
||||||
|
@param buff Pointer to the string, which must be long enough
|
||||||
|
@return none
|
||||||
|
*/
|
||||||
|
/**************************************************************************/
|
||||||
|
void Adafruit_GPS::addChecksum(char *buff) {
|
||||||
|
char cs = 0;
|
||||||
|
int i = 1;
|
||||||
|
while (buff[i]) {
|
||||||
|
cs ^= buff[i];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
sprintf(buff, "%s*%02X", buff, cs);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue