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

processUBXpacket() does not handle NACK #45

Closed
@sslupsky

Description

@sslupsky

Subject of the issue

The processUBXpacket() method does not handle a NACK from the module. This is possible response from the module that needs to be handled otherwise it can result in unreliable processing of the module response.

The following was taken from the UBlox protocol specification:

32.5.1 Acknowledgement
When messages from the class CFG are sent to the receiver, the receiver will send an "acknowledge" (UBX-ACK-ACK) or a "not acknowledge" (UBX-ACK-NAK) message back to the sender, depending on whether or not the message was processed correctly.

I have corrected the issue and can submit a PR if you would like me to. The modified code is copied below. I am not sure how to highlight the changes inside a code block as bolding doesn't seem to work inside the code block.

The changes also address another issue with the indication of a valid packet. This is now more reliable as well.

SparkFun_Ublox_Arduino_Library.cpp

void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
{
  switch (msg->cls)
  {
  case UBX_CLASS_ACK:
    //We don't want to store ACK packets, just set commandAck flag
    if (msg->id == UBX_ACK_ACK && msg->payload[0] == packetCfg.cls && msg->payload[1] == packetCfg.id)
    {
      //The ack we just received matched the CLS/ID of last packetCfg sent
      if (_printDebug == true)
      {
        _debugSerial->println("UBX ACK: Acknowledged");
      }
      commandAck = UBX_ACK_ACK;
    }
    else if (msg->id == UBX_ACK_NACK && msg->payload[0] == packetCfg.cls && msg->payload[1] == packetCfg.id)
    {
      //The ack we just received matched the CLS/ID of last packetCfg sent
      if (_printDebug == true)
      {
        _debugSerial->println("UBX ACK:  Not-Acknowledged");
      }
      commandAck = UBX_ACK_NACK;
    }
boolean SFE_UBLOX_GPS::waitForResponse(uint8_t requestedClass, uint8_t requestedID, uint16_t maxTime)
{
  commandAck = UBX_ACK_NONE;      //Reset flag
  packetCfg.valid = false; //This will go true when we receive a response to the packet we sent
  packetAck.valid = false;

  unsigned long startTime = millis();
  while (millis() - startTime < maxTime)
  {
    checkUblox(); //See if new data is available. Process bytes as they come in.

    if (packetAck.valid == true)
    {
      if (commandAck == UBX_ACK_ACK) {
        return (true);   //  Received an ACK
      }
      else if (commandAck == UBX_ACK_NACK) {
        return (false);  //  Received a NACK
      }
boolean SFE_UBLOX_GPS::getPVT(uint16_t maxWait)
{
  if (autoPVT)
  {
    //The GPS is automatically reporting, we just check whether we got unread data
    checkUblox();
    return moduleQueried.all;
  }
  else
  {
    //The GPS is not automatically reporting navigation position so we have to poll explicitly
    packetCfg.cls = UBX_CLASS_NAV;
    packetCfg.id = UBX_NAV_PVT;
    packetCfg.len = 0;
    //packetCfg.startingSpot = 20; //Begin listening at spot 20 so we can record up to 20+MAX_PAYLOAD_SIZE = 84 bytes Note:now hard-coded in processUBX
    packetCfg.valid = false;

SparkFun_Ublox_Arduino_Library.h

	const uint8_t I2C_POLLING_WAIT_MS = 25; //Limit checking of new characters to every X ms
	unsigned long lastCheck = 0;
	boolean autoPVT = false;	//Whether autoPVT is enabled or not
	uint8_t commandAck = UBX_ACK_NONE; //This goes true after we send a command and it's ack'd
	uint8_t ubxFrameCounter;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions