Skip to content
This repository was archived by the owner on Jan 28, 2021. It is now read-only.

Commit dc9a9d5

Browse files
authored
Merge pull request #59 from sparkfun/BetterNACKHandling
Faster version polling
2 parents 5517e69 + 2075f33 commit dc9a9d5

File tree

2 files changed

+55
-43
lines changed

2 files changed

+55
-43
lines changed

src/SparkFun_Ublox_Arduino_Library.cpp

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ SFE_UBLOX_GPS::SFE_UBLOX_GPS(void)
4242
{
4343
// Constructor
4444
currentGeofenceParams.numFences = 0; // Zero the number of geofences currently in use
45+
moduleQueried.versionNumber = false;
4546
}
4647

4748
//Initialize the Serial port
@@ -575,8 +576,14 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
575576
if (msg->id == UBX_ACK_ACK && msg->payload[0] == packetCfg.cls && msg->payload[1] == packetCfg.id)
576577
{
577578
//The ack we just received matched the CLS/ID of last packetCfg sent
578-
debugPrintln((char *)"Command sent/ack'd successfully");
579-
commandAck = true;
579+
debugPrintln((char *)"UBX ACK: Command sent/ack'd successfully");
580+
commandAck = UBX_ACK_ACK;
581+
}
582+
else if (msg->id == UBX_ACK_NACK && msg->payload[0] == packetCfg.cls && msg->payload[1] == packetCfg.id)
583+
{
584+
//The ack we just received matched the CLS/ID of last packetCfg sent
585+
debugPrintln((char *)"UBX ACK: Not-Acknowledged");
586+
commandAck = UBX_ACK_NACK;
580587
}
581588
break;
582589

@@ -685,7 +692,7 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
685692
//Given a packet and payload, send everything including CRC bytes via I2C port
686693
boolean SFE_UBLOX_GPS::sendCommand(ubxPacket outgoingUBX, uint16_t maxWait)
687694
{
688-
commandAck = false; //We're about to send a command. Begin waiting for ack.
695+
commandAck = UBX_ACK_NONE; //We're about to send a command. Begin waiting for ack.
689696
calcChecksum(&outgoingUBX); //Sets checksum A and B bytes of the packet
690697

691698
if (_printDebug == true)
@@ -878,16 +885,24 @@ void SFE_UBLOX_GPS::printPacket(ubxPacket *packet)
878885
//Poll the module until and ack is received
879886
boolean SFE_UBLOX_GPS::waitForResponse(uint8_t requestedClass, uint8_t requestedID, uint16_t maxTime)
880887
{
881-
commandAck = false; //Reset flag
882-
packetCfg.valid = false; //This will go true when we receive a response to the packet we sent
888+
commandAck = UBX_ACK_NONE; //Reset flag
889+
packetCfg.valid = false; //This will go true when we receive a response to the packet we sent
890+
packetAck.valid = false;
883891

884892
unsigned long startTime = millis();
885893
while (millis() - startTime < maxTime)
886894
{
887895
if (checkUblox() == true) //See if new data is available. Process bytes as they come in.
888896
{
889-
if (commandAck == true)
890-
return (true); //If the packet we just sent was a CFG packet then we'll get an ACK
897+
if (packetAck.valid == true)
898+
{
899+
//If the packet we just sent was a CFG packet then we'll get an ACK
900+
if (commandAck == UBX_ACK_ACK)
901+
return (true); // Received an ACK
902+
else if (commandAck == UBX_ACK_NACK)
903+
return (false); // Received a NACK
904+
}
905+
891906
if (packetCfg.valid == true)
892907
{
893908
//Did we receive a config packet that matches the cls/id we requested?
@@ -2252,7 +2267,6 @@ uint8_t SFE_UBLOX_GPS::getProtocolVersionHigh(uint16_t maxWait)
22522267
{
22532268
if (moduleQueried.versionNumber == false)
22542269
getProtocolVersion(maxWait);
2255-
moduleQueried.versionNumber = false;
22562270
return (versionHigh);
22572271
}
22582272

@@ -2262,7 +2276,6 @@ uint8_t SFE_UBLOX_GPS::getProtocolVersionLow(uint16_t maxWait)
22622276
{
22632277
if (moduleQueried.versionNumber == false)
22642278
getProtocolVersion(maxWait);
2265-
moduleQueried.versionNumber = false;
22662279
return (versionLow);
22672280
}
22682281

@@ -2274,46 +2287,44 @@ boolean SFE_UBLOX_GPS::getProtocolVersion(uint16_t maxWait)
22742287
packetCfg.cls = UBX_CLASS_MON;
22752288
packetCfg.id = UBX_MON_VER;
22762289

2277-
//We will send the command repeatedly, increasing the startingSpot as we go
2278-
//Then we look at each extension field of 30 bytes
2279-
for (uint8_t extensionNumber = 0; extensionNumber < 10; extensionNumber++)
2280-
{
2281-
packetCfg.len = 0;
2282-
packetCfg.startingSpot = 40 + (30 * extensionNumber);
2290+
packetCfg.len = 0;
2291+
packetCfg.startingSpot = 40; //Start at first "extended software information" string
2292+
2293+
if (sendCommand(packetCfg, maxWait) == false)
2294+
return (false); //If command send fails then bail
22832295

2284-
if (sendCommand(packetCfg, maxWait) == false)
2285-
return (false); //If command send fails then bail
2296+
// Let's make sure we wait for the ACK too (sendCommand will have returned as soon as the module sent its response)
2297+
// This is only required because we are doing multiple sendCommands in quick succession using the same class and ID
2298+
waitForResponse(UBX_CLASS_MON, UBX_MON_VER, 100); // But we'll only wait for 100msec max
22862299

2287-
// Let's make sure we wait for the ACK too (sendCommand will have returned as soon as the module sent its response)
2288-
// This is only required because we are doing multiple sendCommands in quick succession using the same class and ID
2289-
waitForResponse(UBX_CLASS_MON, UBX_MON_VER, 100); // But we'll only wait for 100msec max
2300+
//Payload should now contain ~220 characters (depends on module type)
22902301

2291-
if (_printDebug == true)
2302+
if (_printDebug == true)
2303+
{
2304+
_debugSerial->print(F("MON VER Payload:"));
2305+
for (int location = 0; location < packetCfg.len; location++)
22922306
{
2293-
_debugSerial->print(F("Extension "));
2294-
_debugSerial->print(extensionNumber);
2295-
_debugSerial->print(F(": "));
2296-
for (int location = 0; location < MAX_PAYLOAD_SIZE; location++)
2297-
{
2298-
if (payloadCfg[location] == '\0')
2299-
break;
2300-
_debugSerial->write(payloadCfg[location]);
2301-
}
2302-
_debugSerial->println();
2307+
if (location % 30 == 0)
2308+
_debugSerial->println();
2309+
_debugSerial->write(payloadCfg[location]);
23032310
}
2311+
_debugSerial->println();
2312+
}
23042313

2314+
//We will step through the payload looking at each extension field of 30 bytes
2315+
for (uint8_t extensionNumber = 0; extensionNumber < 10; extensionNumber++)
2316+
{
23052317
//Now we need to find "PROTVER=18.00" in the incoming byte stream
2306-
if (payloadCfg[0] == 'P' && payloadCfg[6] == 'R')
2318+
if (payloadCfg[(30 * extensionNumber) + 0] == 'P' && payloadCfg[(30 * extensionNumber) + 6] == 'R')
23072319
{
2308-
versionHigh = (payloadCfg[8] - '0') * 10 + (payloadCfg[9] - '0'); //Convert '18' to 18
2309-
versionLow = (payloadCfg[11] - '0') * 10 + (payloadCfg[12] - '0'); //Convert '00' to 00
2310-
return (true); // This function returns a boolean (so we can't return versionLow)
2320+
versionHigh = (payloadCfg[(30 * extensionNumber) + 8] - '0') * 10 + (payloadCfg[(30 * extensionNumber) + 9] - '0'); //Convert '18' to 18
2321+
versionLow = (payloadCfg[(30 * extensionNumber) + 11] - '0') * 10 + (payloadCfg[(30 * extensionNumber) + 12] - '0'); //Convert '00' to 00
2322+
moduleQueried.versionNumber = true; //Mark this data as new
2323+
return (true); //Success!
23112324
}
23122325
}
23132326

2314-
moduleQueried.versionNumber = true; //Mark this data as new
2315-
2316-
return (true);
2327+
return (false); //We failed
23172328
}
23182329

23192330
//Relative Positioning Information in NED frame

src/SparkFun_Ublox_Arduino_Library.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ const uint8_t UBX_RTCM_1230 = 0xE6; //GLONASS code-phase biases, set to once eve
149149

150150
const uint8_t UBX_ACK_NACK = 0x00;
151151
const uint8_t UBX_ACK_ACK = 0x01;
152+
const uint8_t UBX_ACK_NONE = 0x02; //Not a real value
152153

153154
//The following consts are used to configure the various ports and streams for those ports. See -CFG-PRT.
154155
const uint8_t COM_PORT_I2C = 0;
@@ -204,7 +205,7 @@ enum dynModel // Possible values for the dynamic platform model
204205

205206
#ifndef MAX_PAYLOAD_SIZE
206207

207-
#define MAX_PAYLOAD_SIZE 128
208+
#define MAX_PAYLOAD_SIZE 256 //We need ~220 bytes for getProtocolVersion on most ublox modules
208209
//#define MAX_PAYLOAD_SIZE 768 //Worst case: UBX_CFG_VALSET packet with 64 keyIDs each with 64 bit values
209210

210211
#endif
@@ -367,9 +368,9 @@ class SFE_UBLOX_GPS
367368

368369
uint32_t getPositionAccuracy(uint16_t maxWait = 500); //Returns the 3D accuracy of the current high-precision fix, in mm. Supported on NEO-M8P, ZED-F9P,
369370

370-
uint8_t getProtocolVersionHigh(uint16_t maxWait = 1000); //Returns the PROTVER XX.00 from UBX-MON-VER register
371-
uint8_t getProtocolVersionLow(uint16_t maxWait = 1000); //Returns the PROTVER 00.XX from UBX-MON-VER register
372-
boolean getProtocolVersion(uint16_t maxWait = 1000); //Queries module, loads low/high bytes
371+
uint8_t getProtocolVersionHigh(uint16_t maxWait = 500); //Returns the PROTVER XX.00 from UBX-MON-VER register
372+
uint8_t getProtocolVersionLow(uint16_t maxWait = 500); //Returns the PROTVER 00.XX from UBX-MON-VER register
373+
boolean getProtocolVersion(uint16_t maxWait = 500); //Queries module, loads low/high bytes
373374

374375
boolean getRELPOSNED(uint16_t maxWait = 1000); //Get Relative Positioning Information of the NED frame
375376

@@ -521,7 +522,7 @@ class SFE_UBLOX_GPS
521522
unsigned long lastCheck = 0;
522523
boolean autoPVT = false; //Whether autoPVT is enabled or not
523524
boolean autoPVTImplicitUpdate = true; // Whether autoPVT is triggered by accessing stale data (=true) or by a call to checkUblox (=false)
524-
boolean commandAck = false; //This goes true after we send a command and it's ack'd
525+
uint8_t commandAck = UBX_ACK_NONE; //This goes to UBX_ACK_ACK after we send a command and it's ack'd
525526
uint16_t ubxFrameCounter; //It counts all UBX frame. [Fixed header(2bytes), CLS(1byte), ID(1byte), length(2bytes), payload(x bytes), checksums(2bytes)]
526527

527528
uint8_t rollingChecksumA; //Rolls forward as we receive incoming bytes. Checked against the last two A/B checksum bytes

0 commit comments

Comments
 (0)