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

Commit 5b51956

Browse files
author
Nathan Seidle
committed
Packet ACK is now checked during sendCommand.
1 parent 99de3be commit 5b51956

File tree

2 files changed

+61
-48
lines changed

2 files changed

+61
-48
lines changed

src/SparkFun_Ublox_Arduino_Library.cpp

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ boolean SFE_UBLOX_GPS::checkUbloxI2C()
237237

238238
if (bytesAvailable == 0)
239239
{
240-
debugPrintln((char *)"Zero bytes available");
240+
debugPrintln((char *)"OK: Zero bytes Zero bytes available");
241241
lastCheck = millis(); //Put off checking to avoid I2C bus traffic
242242
return (false);
243243
}
@@ -368,9 +368,7 @@ void SFE_UBLOX_GPS::process(uint8_t incoming)
368368
else if (ubxFrameCounter == 2) //Class
369369
{
370370
packetAck.counter = 0;
371-
packetAck.valid = false;
372371
packetCfg.counter = 0;
373-
packetCfg.valid = false;
374372

375373
//We can now identify the type of response
376374
if (incoming == UBX_CLASS_ACK)
@@ -509,14 +507,20 @@ void SFE_UBLOX_GPS::processUBX(uint8_t incoming, ubxPacket *incomingUBX)
509507
//Validate this sentence
510508
if (incomingUBX->checksumA == rollingChecksumA && incomingUBX->checksumB == rollingChecksumB)
511509
{
510+
incomingUBX->valid = true;
511+
512512
if (_printDebug == true)
513513
{
514-
_debugSerial->print(F("Size: "));
514+
_debugSerial->print(F("Incoming: Size: "));
515515
_debugSerial->print(incomingUBX->len);
516516
_debugSerial->print(F(" Received: "));
517517
printPacket(incomingUBX);
518+
if (packetCfg.valid == true)
519+
debugPrintln((char *)"packetCfg now valid");
520+
if (packetAck.valid == true)
521+
debugPrintln((char *)"packetAck now valid");
518522
}
519-
incomingUBX->valid = true;
523+
520524
processUBXpacket(incomingUBX); //We've got a valid packet, now do something with it
521525
}
522526
else
@@ -584,7 +588,7 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
584588
}
585589
else if (msg->id == UBX_ACK_NACK && msg->payload[0] == packetCfg.cls && msg->payload[1] == packetCfg.id)
586590
{
587-
//The ack we just received matched the CLS/ID of last packetCfg sent (or received)
591+
//The ack we just received matched the CLS/ID of last packetCfg sent
588592
debugPrintln((char *)"UBX ACK: Not-Acknowledged");
589593
commandAck = UBX_ACK_NACK;
590594
}
@@ -700,9 +704,10 @@ boolean SFE_UBLOX_GPS::sendCommand(ubxPacket outgoingUBX, uint16_t maxWait)
700704

701705
if (_printDebug == true)
702706
{
703-
_debugSerial->print(F("Sending: "));
707+
_debugSerial->print(F("\nSending: "));
704708
printPacket(&outgoingUBX);
705709
}
710+
706711
if (commType == COMM_TYPE_I2C)
707712
{
708713
if (!sendI2cCommand(outgoingUBX, maxWait))
@@ -897,6 +902,10 @@ boolean SFE_UBLOX_GPS::waitForResponse(uint8_t requestedClass, uint8_t requested
897902
{
898903
if (checkUblox() == true) //See if new data is available. Process bytes as they come in.
899904
{
905+
//If we are quering a register the module will send response packet to query as well as a ACK/NACK packet
906+
//So first we check that an ACK came through, then the response
907+
//If we are sending a new register value, the module will simply ACK/NACK our register value.
908+
900909
if (packetAck.valid == true)
901910
{
902911
//If the packet we just sent was a CFG packet then we'll get an ACK
@@ -908,7 +917,7 @@ boolean SFE_UBLOX_GPS::waitForResponse(uint8_t requestedClass, uint8_t requested
908917
_debugSerial->print(millis() - startTime);
909918
_debugSerial->println(F(" msec"));
910919
}
911-
return (true); // Received an ACK
920+
return (true); //Received an ACK
912921
}
913922
else if (commandAck == UBX_ACK_NACK)
914923
{
@@ -918,14 +927,19 @@ boolean SFE_UBLOX_GPS::waitForResponse(uint8_t requestedClass, uint8_t requested
918927
_debugSerial->print(millis() - startTime);
919928
_debugSerial->println(F(" msec"));
920929
}
921-
return (false); // Received a NACK
930+
return (false); //Received a NACK
922931
}
923932
}
924933

925934
if (packetCfg.valid == true)
926935
{
927-
//Did we receive a config packet that matches the cls/id we requested?
928-
if (packetCfg.cls == requestedClass && packetCfg.id == requestedID)
936+
if (commandAck == UBX_ACK_NACK)
937+
{
938+
debugPrintln((char *)"Config valid but command NACK'd");
939+
return (false); //Received a NACK. Is this command not known?
940+
}
941+
942+
if (packetCfg.valid == true)
929943
{
930944
if (_printDebug == true)
931945
{
@@ -937,11 +951,11 @@ boolean SFE_UBLOX_GPS::waitForResponse(uint8_t requestedClass, uint8_t requested
937951
}
938952
else
939953
{
940-
if (_printDebug == true)
941-
{
942-
_debugSerial->print(F("Packet didn't match CLS/ID"));
943-
printPacket(&packetCfg);
944-
}
954+
//We have an ACK but no valid config packet. We must have
955+
//gotten an ACK from sending a new value
956+
957+
debugPrintln((char *)"New config ACK'd");
958+
return (true);
945959
}
946960
}
947961
}
@@ -1491,12 +1505,11 @@ boolean SFE_UBLOX_GPS::setPortOutput(uint8_t portID, uint8_t outStreamSettings,
14911505
if (getPortSettings(portID, maxWait) == false)
14921506
return (false); //Something went wrong. Bail.
14931507

1494-
// Let's make sure we wait for the ACK too (sendCommand will have returned as soon as the module sent its response)
1495-
// This is only required because we are doing two sendCommands in quick succession using the same class and ID
1496-
waitForResponse(UBX_CLASS_CFG, UBX_CFG_PRT, 100); // But we'll only wait for 100msec max
1497-
1498-
//Yes, this is the depreciated way to do it but it's still supported on v27 so it
1499-
//covers both ZED-F9P (v27) and SAM-M8Q (v18)
1508+
if (commandAck != UBX_ACK_ACK)
1509+
{
1510+
debugPrintln((char *)"setPortOutput failed to ACK");
1511+
return (false);
1512+
}
15001513

15011514
packetCfg.cls = UBX_CLASS_CFG;
15021515
packetCfg.id = UBX_CFG_PRT;

src/SparkFun_Ublox_Arduino_Library.h

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -291,30 +291,30 @@ class SFE_UBLOX_GPS
291291

292292
boolean waitForResponse(uint8_t requestedClass, uint8_t requestedID, uint16_t maxTime = 250); //Poll the module until and ack is received
293293

294-
// getPVT will only return data once in each navigation cycle. By default, that is once per second.
295-
// Therefore we should set getPVTmaxWait to slightly longer than that.
296-
// If you change the navigation frequency to (e.g.) 4Hz using setNavigationFrequency(4)
297-
// then you should use a shorter maxWait for getPVT. 300msec would be about right: getPVT(300)
298-
// The same is true for getHPPOSLLH.
299-
#define getPVTmaxWait 1100 // Default maxWait for getPVT and all functions which call it
300-
#define getHPPOSLLHmaxWait 1100 // Default maxWait for getHPPOSLLH and all functions which call it
301-
302-
boolean assumeAutoPVT(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and PVT is send cyclically already
303-
boolean setAutoPVT(boolean enabled, uint16_t maxWait = 250); //Enable/disable automatic PVT reports at the navigation frequency
304-
boolean getPVT(uint16_t maxWait = getPVTmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available.
294+
// getPVT will only return data once in each navigation cycle. By default, that is once per second.
295+
// Therefore we should set getPVTmaxWait to slightly longer than that.
296+
// If you change the navigation frequency to (e.g.) 4Hz using setNavigationFrequency(4)
297+
// then you should use a shorter maxWait for getPVT. 300msec would be about right: getPVT(300)
298+
// The same is true for getHPPOSLLH.
299+
#define getPVTmaxWait 1100 // Default maxWait for getPVT and all functions which call it
300+
#define getHPPOSLLHmaxWait 1100 // Default maxWait for getHPPOSLLH and all functions which call it
301+
302+
boolean assumeAutoPVT(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and PVT is send cyclically already
303+
boolean setAutoPVT(boolean enabled, uint16_t maxWait = 250); //Enable/disable automatic PVT reports at the navigation frequency
304+
boolean getPVT(uint16_t maxWait = getPVTmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available.
305305
boolean setAutoPVT(boolean enabled, boolean implicitUpdate, uint16_t maxWait = 250); //Enable/disable automatic PVT reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update
306-
boolean getHPPOSLLH(uint16_t maxWait = getHPPOSLLHmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available.
307-
308-
int32_t getLatitude(uint16_t maxWait = getPVTmaxWait); //Returns the current latitude in degrees * 10^-7. Auto selects between HighPrecision and Regular depending on ability of module.
309-
int32_t getLongitude(uint16_t maxWait = getPVTmaxWait); //Returns the current longitude in degrees * 10-7. Auto selects between HighPrecision and Regular depending on ability of module.
310-
int32_t getAltitude(uint16_t maxWait = getPVTmaxWait); //Returns the current altitude in mm above ellipsoid
311-
int32_t getAltitudeMSL(uint16_t maxWait = getPVTmaxWait); //Returns the current altitude in mm above mean sea level
312-
uint8_t getSIV(uint16_t maxWait = getPVTmaxWait); //Returns number of sats used in fix
313-
uint8_t getFixType(uint16_t maxWait = getPVTmaxWait); //Returns the type of fix: 0=no, 3=3D, 4=GNSS+Deadreckoning
306+
boolean getHPPOSLLH(uint16_t maxWait = getHPPOSLLHmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available.
307+
308+
int32_t getLatitude(uint16_t maxWait = getPVTmaxWait); //Returns the current latitude in degrees * 10^-7. Auto selects between HighPrecision and Regular depending on ability of module.
309+
int32_t getLongitude(uint16_t maxWait = getPVTmaxWait); //Returns the current longitude in degrees * 10-7. Auto selects between HighPrecision and Regular depending on ability of module.
310+
int32_t getAltitude(uint16_t maxWait = getPVTmaxWait); //Returns the current altitude in mm above ellipsoid
311+
int32_t getAltitudeMSL(uint16_t maxWait = getPVTmaxWait); //Returns the current altitude in mm above mean sea level
312+
uint8_t getSIV(uint16_t maxWait = getPVTmaxWait); //Returns number of sats used in fix
313+
uint8_t getFixType(uint16_t maxWait = getPVTmaxWait); //Returns the type of fix: 0=no, 3=3D, 4=GNSS+Deadreckoning
314314
uint8_t getCarrierSolutionType(uint16_t maxWait = getPVTmaxWait); //Returns RTK solution: 0=no, 1=float solution, 2=fixed solution
315-
int32_t getGroundSpeed(uint16_t maxWait = getPVTmaxWait); //Returns speed in mm/s
316-
int32_t getHeading(uint16_t maxWait = getPVTmaxWait); //Returns heading in degrees * 10^-7
317-
uint16_t getPDOP(uint16_t maxWait = getPVTmaxWait); //Returns positional dillution of precision * 10^-2
315+
int32_t getGroundSpeed(uint16_t maxWait = getPVTmaxWait); //Returns speed in mm/s
316+
int32_t getHeading(uint16_t maxWait = getPVTmaxWait); //Returns heading in degrees * 10^-7
317+
uint16_t getPDOP(uint16_t maxWait = getPVTmaxWait); //Returns positional dillution of precision * 10^-2
318318
uint16_t getYear(uint16_t maxWait = getPVTmaxWait);
319319
uint8_t getMonth(uint16_t maxWait = getPVTmaxWait);
320320
uint8_t getDay(uint16_t maxWait = getPVTmaxWait);
@@ -393,10 +393,10 @@ class SFE_UBLOX_GPS
393393

394394
//Support for geofences
395395
boolean addGeofence(int32_t latitude, int32_t longitude, uint32_t radius, byte confidence = 0, byte pinPolarity = 0, byte pin = 0, uint16_t maxWait = 1100); // Add a new geofence
396-
boolean clearGeofences(uint16_t maxWait = 1100); //Clears all geofences
397-
boolean getGeofenceState(geofenceState &currentGeofenceState, uint16_t maxWait = 1100); //Returns the combined geofence state
398-
boolean clearAntPIO(uint16_t maxWait = 1100); //Clears the antenna control pin settings to release the PIOs
399-
geofenceParams currentGeofenceParams; // Global to store the geofence parameters
396+
boolean clearGeofences(uint16_t maxWait = 1100); //Clears all geofences
397+
boolean getGeofenceState(geofenceState &currentGeofenceState, uint16_t maxWait = 1100); //Returns the combined geofence state
398+
boolean clearAntPIO(uint16_t maxWait = 1100); //Clears the antenna control pin settings to release the PIOs
399+
geofenceParams currentGeofenceParams; // Global to store the geofence parameters
400400

401401
boolean powerSaveMode(bool power_save = true, uint16_t maxWait = 1100);
402402

0 commit comments

Comments
 (0)