mirror of
https://github.com/adafruit/Adafruit_GPS.git
synced 2026-10-26 22:10:17 +00:00
Merge pull request #178 from ladyada-eagleclaw/main
Support antenna status on newer CDTop GPS modules
This commit is contained in:
11 files changed
+123
-26
No files matched your search
@@ -46,8 +46,9 @@ void setup()
|
||||
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
|
||||
// Default is 1 Hz update rate
|
||||
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
|
||||
// Request updates on antenna status, comment out to keep quiet
|
||||
GPS.sendCommand(PGCMD_ANTENNA);
|
||||
// Request antenna status from old and new modules; comment out both to keep quiet
|
||||
GPS.sendCommand(F(PGCMD_ANTENNA));
|
||||
GPS.sendCommand(F(CDCMD_ANTENNA));
|
||||
// Ask for firmware version
|
||||
GPS.sendCommand(PMTK_Q_RELEASE);
|
||||
|
||||
|
||||
@@ -46,8 +46,9 @@ void setup()
|
||||
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
|
||||
// Default is 1 Hz update rate
|
||||
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);
|
||||
// Request updates on antenna status, comment out to keep quiet
|
||||
GPS.sendCommand(PGCMD_ANTENNA);
|
||||
// Request antenna status from old and new modules; comment out both to keep quiet
|
||||
GPS.sendCommand(F(PGCMD_ANTENNA));
|
||||
GPS.sendCommand(F(CDCMD_ANTENNA));
|
||||
// Ask for firmware version
|
||||
GPS.sendCommand(PMTK_Q_RELEASE);
|
||||
|
||||
|
||||
@@ -51,8 +51,9 @@ void setup()
|
||||
// For the parsing code to work nicely and have time to sort thru the data, and
|
||||
// print it out we don't suggest using anything higher than 1 Hz
|
||||
|
||||
// Request updates on antenna status, comment out to keep quiet
|
||||
GPS.sendCommand(PGCMD_ANTENNA);
|
||||
// Request antenna status from old and new modules; comment out both to keep quiet
|
||||
GPS.sendCommand(F(PGCMD_ANTENNA));
|
||||
GPS.sendCommand(F(CDCMD_ANTENNA));
|
||||
|
||||
delay(1000);
|
||||
|
||||
|
||||
@@ -72,8 +72,9 @@ void setup() {
|
||||
// For the parsing code to work nicely and have time to sort thru the data,
|
||||
// and print it out we don't suggest using anything higher than 1 Hz
|
||||
|
||||
// Request updates on antenna status, comment out to keep quiet
|
||||
GPS.sendCommand(PGCMD_ANTENNA);
|
||||
// Request antenna status from old and new modules; comment out both to keep quiet
|
||||
GPS.sendCommand(F(PGCMD_ANTENNA));
|
||||
GPS.sendCommand(F(CDCMD_ANTENNA));
|
||||
|
||||
delay(1000);
|
||||
|
||||
|
||||
@@ -39,8 +39,9 @@ void setup()
|
||||
// For the parsing code to work nicely and have time to sort thru the data, and
|
||||
// print it out we don't suggest using anything higher than 1 Hz
|
||||
|
||||
// Request updates on antenna status, comment out to keep quiet
|
||||
GPS.sendCommand(PGCMD_ANTENNA);
|
||||
// Request antenna status from old and new modules; comment out both to keep quiet
|
||||
GPS.sendCommand(F(PGCMD_ANTENNA));
|
||||
GPS.sendCommand(F(CDCMD_ANTENNA));
|
||||
|
||||
delay(1000);
|
||||
|
||||
|
||||
@@ -51,8 +51,9 @@ void setup()
|
||||
// For the parsing code to work nicely and have time to sort thru the data, and
|
||||
// print it out we don't suggest using anything higher than 1 Hz
|
||||
|
||||
// Request updates on antenna status, comment out to keep quiet
|
||||
GPS.sendCommand(PGCMD_ANTENNA);
|
||||
// Request antenna status from old and new modules; comment out both to keep quiet
|
||||
GPS.sendCommand(F(PGCMD_ANTENNA));
|
||||
GPS.sendCommand(F(CDCMD_ANTENNA));
|
||||
|
||||
delay(1000);
|
||||
// Ask for firmware version
|
||||
|
||||
@@ -127,8 +127,9 @@ void setup() {
|
||||
// Set the update rate
|
||||
GPS.sendCommand(F(PMTK_SET_NMEA_UPDATE_1HZ)); // 100 millihertz (once every 10 seconds), 1Hz or 5Hz update rate
|
||||
|
||||
// Turn off updates on antenna status, if the firmware permits it
|
||||
// Disable antenna status on old and new modules, if the firmware permits it.
|
||||
GPS.sendCommand(F(PGCMD_NOANTENNA));
|
||||
GPS.sendCommand(F(CDCMD_NOANTENNA));
|
||||
|
||||
// the nice thing about this code is you can have a timer0 interrupt go off
|
||||
// every 1 millisecond, and read data from the GPS for you. that makes the
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
#include <Adafruit_GPS.h>
|
||||
|
||||
Adafruit_GPS GPS;
|
||||
bool testsPassed = false;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
// Wait briefly for the Serial Monitor on native USB boards.
|
||||
while (!Serial && millis() < 5000) {
|
||||
delay(10);
|
||||
}
|
||||
delay(250);
|
||||
Serial.println(F("Adafruit GPS antenna status regression"));
|
||||
|
||||
char valid[][20] = {
|
||||
"$PGTOP,11,1*6D",
|
||||
"$PGTOP,11,2*6E",
|
||||
"$PGTOP,11,3*6F",
|
||||
"$PCD,11,1*66",
|
||||
"$PCD,11,2*65",
|
||||
"$PCD,11,3*64",
|
||||
};
|
||||
// PGTOP: problem, internal, external. PCD: internal, external, problem.
|
||||
const uint8_t expected[] = {1, 2, 3, 2, 3, 1};
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
GPS.antenna = 0;
|
||||
if (!GPS.parse(valid[i]) || GPS.antenna != expected[i]) {
|
||||
Serial.print(F("FAIL: antenna status for "));
|
||||
Serial.println(valid[i]);
|
||||
return;
|
||||
}
|
||||
if (i < 3) {
|
||||
if (strcmp(GPS.lastSource, "PG") || strcmp(GPS.lastSentence, "TOP")) {
|
||||
Serial.println(F("FAIL: legacy sentence identity"));
|
||||
return;
|
||||
}
|
||||
} else if (strcmp(GPS.lastSource, "P") || strcmp(GPS.lastSentence, "CD")) {
|
||||
Serial.println(F("FAIL: new sentence identity"));
|
||||
return;
|
||||
}
|
||||
Serial.print(F("PASS: "));
|
||||
Serial.println(valid[i]);
|
||||
}
|
||||
|
||||
char invalid[][22] = {
|
||||
"$PCD,11*7B",
|
||||
"$PCD,11,*57",
|
||||
"$PCD,11,4*63",
|
||||
"$PCD,9,2*5C",
|
||||
"$PCDXYZ,11,1*3D",
|
||||
"$PGTOP,11*70",
|
||||
"$PCD,11,10*56",
|
||||
"$PGTOP,11,10*5D",
|
||||
};
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
GPS.antenna = 2;
|
||||
if (GPS.parse(invalid[i]) || GPS.antenna != 2) {
|
||||
Serial.print(F("FAIL: invalid sentence changed antenna status: "));
|
||||
Serial.println(invalid[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Serial.println(F("PASS: incomplete and unrelated sentences preserve antenna status"));
|
||||
testsPassed = true;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (testsPassed) {
|
||||
Serial.println(F("PASS: antenna status regression"));
|
||||
} else {
|
||||
Serial.println(F("FAIL: antenna status regression"));
|
||||
}
|
||||
delay(2000);
|
||||
}
|
||||
+1
-1
@@ -202,7 +202,7 @@ public:
|
||||
uint8_t fixquality; ///< Fix quality (0, 1, 2 = Invalid, GPS, DGPS)
|
||||
uint8_t fixquality_3d; ///< 3D fix quality (1, 3, 3 = Nofix, 2D fix, 3D fix)
|
||||
uint8_t satellites; ///< Number of satellites in use
|
||||
uint8_t antenna; ///< Antenna that is used (from PGTOP)
|
||||
uint8_t antenna; ///< 1=problem, 2=internal, 3=external (PGTOP or PCD)
|
||||
|
||||
uint16_t LOCUS_serial; ///< Log serial number
|
||||
uint16_t LOCUS_records; ///< Log number of data record
|
||||
|
||||
@@ -109,6 +109,10 @@
|
||||
#define PGCMD_ANTENNA \
|
||||
"$PGCMD,33,1*6C" ///< request for updates on antenna status
|
||||
#define PGCMD_NOANTENNA "$PGCMD,33,0*6D" ///< don't show antenna status messages
|
||||
#define CDCMD_ANTENNA \
|
||||
"$CDCMD,33,1*7C" ///< request antenna status on newer CDTop modules
|
||||
#define CDCMD_NOANTENNA \
|
||||
"$CDCMD,33,0*7D" ///< disable antenna status on newer CDTop modules
|
||||
|
||||
#define MAXWAITSENTENCE \
|
||||
10 ///< maximum number of sentences to examine when looking for a response
|
||||
|
||||
+24
-12
@@ -26,14 +26,14 @@ const char PROGMEM Adafruit_GPS::sources[][4] = {"II", "WI", "GP", "PG", "GL",
|
||||
"GA", "GN", "P", "ZZZ"};
|
||||
#ifdef NMEA_EXTENSIONS
|
||||
const char PROGMEM Adafruit_GPS::sentences_parsed[][4] = {
|
||||
"GGA", "GLL", "GSA", "RMC", "DBT", "HDM", "HDT", "MDA", "MTW", "MWV",
|
||||
"GGA", "GLL", "GSA", "RMC", "CD", "DBT", "HDM", "HDT", "MDA", "MTW", "MWV",
|
||||
"RMB", "TOP", "TXT", "VHW", "VLW", "VPW", "VWR", "WCV", "XTE", "ZZZ"};
|
||||
const char PROGMEM Adafruit_GPS::sentences_known[][4] = {
|
||||
"APB", "DPT", "GSV", "HDG", "MWD", "ROT",
|
||||
"RPM", "RSA", "VDR", "VTG", "ZDA", "ZZZ"};
|
||||
#else // make the lists short to save flash on small boards
|
||||
const char PROGMEM Adafruit_GPS::sentences_parsed[][4] = {"GGA", "GLL", "GSA",
|
||||
"RMC", "TOP", "ZZZ"};
|
||||
const char PROGMEM Adafruit_GPS::sentences_parsed[][4] = {
|
||||
"GGA", "GLL", "GSA", "RMC", "TOP", "CD", "ZZZ"};
|
||||
const char PROGMEM Adafruit_GPS::sentences_known[][4] = {"DBT", "HDM", "HDT",
|
||||
"ZZZ"};
|
||||
#endif
|
||||
@@ -201,16 +201,27 @@ bool Adafruit_GPS::parse(char *nmea) {
|
||||
if (!isEmpty(p))
|
||||
VDOP = atof(p); // last before checksum
|
||||
|
||||
} else if (!strcmp(thisSentence, "TOP")) { //*****************************TOP
|
||||
} else if (!strcmp(thisSentence, "TOP") ||
|
||||
!strcmp_P(thisSentence, PSTR("CD"))) { // Antenna status
|
||||
if (fields < 2)
|
||||
return false;
|
||||
// See:
|
||||
// https://learn.adafruit.com/adafruit-ultimate-gps-featherwing/antenna-options
|
||||
// There is an output sentence that will tell you the status of the
|
||||
// antenna. $PGTOP,11,x where x is the status number. If x is 3 that means
|
||||
// it is using the external antenna. If x is 2 it's using the internal
|
||||
bool cdtop = !strcmp_P(thisSentence, PSTR("CD"));
|
||||
// Only PCD subtype 11 describes the antenna; other CD messages differ.
|
||||
if (cdtop && strncmp_P(nmea, PSTR("$PCD,11,"), 8))
|
||||
return false;
|
||||
p = strchr(p, ',') + 1;
|
||||
parseAntenna(p);
|
||||
if (!parseAntenna(p))
|
||||
return false;
|
||||
if (cdtop) {
|
||||
// PCD uses 1=internal, 2=external, 3=shorted. Preserve the public
|
||||
// PGTOP convention: 1=problem, 2=internal, 3=external.
|
||||
if (antenna == 1)
|
||||
antenna = 2;
|
||||
else if (antenna == 2)
|
||||
antenna = 3;
|
||||
else
|
||||
antenna = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NMEA_EXTENSIONS // Sentences not required for basic GPS functionality
|
||||
@@ -895,11 +906,12 @@ bool Adafruit_GPS::parseFix(char *p) {
|
||||
/*!
|
||||
@brief Parse a part of an NMEA string for antenna that is used
|
||||
@param p Pointer to the location of the token in the NMEA string
|
||||
@return 3=external 2=internal 1=there was an antenna short or problem
|
||||
@return True if the antenna status was recognized, false otherwise
|
||||
*/
|
||||
/**************************************************************************/
|
||||
bool Adafruit_GPS::parseAntenna(char *p) {
|
||||
if (!isEmpty(p)) {
|
||||
if (!isEmpty(p) && p[0] != '\0' &&
|
||||
(p[1] == ',' || p[1] == '*' || p[1] == '\0')) {
|
||||
if (p[0] == '3') {
|
||||
antenna = 3;
|
||||
} else if (p[0] == '2') {
|
||||
|
||||
Reference in new issue
Block a user