@@ -715,11 +715,28 @@ boolean SFE_UBLOX_GNSS::checkUbloxI2C(ubxPacket *incomingUBX, uint8_t requestedC
715
715
uint16_t bytesAvailable = 0;
716
716
_i2cPort->beginTransmission(_gpsI2Caddress);
717
717
_i2cPort->write(0xFD); //0xFD (MSB) and 0xFE (LSB) are the registers that contain number of bytes available
718
- if (_i2cPort->endTransmission(false) != 0) //Send a restart command. Do not release bus.
718
+ uint8_t i2cError = _i2cPort->endTransmission(false); //Send a restart command. Do not release bus.
719
+ if (i2cError != 0)
720
+ {
721
+ if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
722
+ {
723
+ _debugSerial->print(F("checkUbloxI2C: I2C error: endTransmission returned "));
724
+ _debugSerial->println(i2cError);
725
+ }
719
726
return (false); //Sensor did not ACK
727
+ }
720
728
721
- _i2cPort->requestFrom((uint8_t)_gpsI2Caddress, (uint8_t)2);
722
- if (_i2cPort->available())
729
+ uint8_t bytesReturned = _i2cPort->requestFrom((uint8_t)_gpsI2Caddress, (uint8_t)2);
730
+ if (bytesReturned != 2)
731
+ {
732
+ if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
733
+ {
734
+ _debugSerial->print(F("checkUbloxI2C: I2C error: requestFrom 0xFD returned "));
735
+ _debugSerial->println(bytesReturned);
736
+ }
737
+ return (false); //Sensor did not return 2 bytes
738
+ }
739
+ //if (_i2cPort->available())
723
740
{
724
741
uint8_t msb = _i2cPort->read();
725
742
uint8_t lsb = _i2cPort->read();
@@ -728,7 +745,8 @@ boolean SFE_UBLOX_GNSS::checkUbloxI2C(ubxPacket *incomingUBX, uint8_t requestedC
728
745
//I believe this is a u-blox bug. Device should never present an 0xFF.
729
746
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
730
747
{
731
- _debugSerial->println(F("checkUbloxI2C: u-blox bug, length lsb is 0xFF"));
748
+ _debugSerial->print(F("checkUbloxI2C: u-blox bug? Length lsb is 0xFF. i2cPollingWait is "));
749
+ _debugSerial->println(i2cPollingWait);
732
750
}
733
751
if (debugPin >= 0)
734
752
{
@@ -739,6 +757,23 @@ boolean SFE_UBLOX_GNSS::checkUbloxI2C(ubxPacket *incomingUBX, uint8_t requestedC
739
757
lastCheck = millis(); //Put off checking to avoid I2C bus traffic
740
758
return (false);
741
759
}
760
+ // if (msb == 0xFF)
761
+ // {
762
+ // //I believe this is a u-blox bug. Device should never present an 0xFF.
763
+ // if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
764
+ // {
765
+ // _debugSerial->print(F("checkUbloxI2C: u-blox bug? Length msb is 0xFF. i2cPollingWait is "));
766
+ // _debugSerial->println(i2cPollingWait);
767
+ // }
768
+ // if (debugPin >= 0)
769
+ // {
770
+ // digitalWrite((uint8_t)debugPin, LOW);
771
+ // delay(10);
772
+ // digitalWrite((uint8_t)debugPin, HIGH);
773
+ // }
774
+ // lastCheck = millis(); //Put off checking to avoid I2C bus traffic
775
+ // return (false);
776
+ // }
742
777
bytesAvailable = (uint16_t)msb << 8 | lsb;
743
778
}
744
779
@@ -762,17 +797,17 @@ boolean SFE_UBLOX_GNSS::checkUbloxI2C(ubxPacket *incomingUBX, uint8_t requestedC
762
797
//Clear the MSbit
763
798
bytesAvailable &= ~((uint16_t)1 << 15);
764
799
765
- if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
766
- {
767
- _debugSerial->print(F("checkUbloxI2C: Bytes available error: "));
768
- _debugSerial->println(bytesAvailable);
769
- if (debugPin >= 0)
770
- {
771
- digitalWrite((uint8_t)debugPin, LOW);
772
- delay(10);
773
- digitalWrite((uint8_t)debugPin, HIGH);
774
- }
775
- }
800
+ // if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
801
+ // {
802
+ // _debugSerial->print(F("checkUbloxI2C: Bytes available error: "));
803
+ // _debugSerial->println(bytesAvailable);
804
+ // if (debugPin >= 0)
805
+ // {
806
+ // digitalWrite((uint8_t)debugPin, LOW);
807
+ // delay(10);
808
+ // digitalWrite((uint8_t)debugPin, HIGH);
809
+ // }
810
+ // }
776
811
}
777
812
778
813
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
@@ -9615,10 +9650,13 @@ uint32_t SFE_UBLOX_GNSS::getProcessNMEAMask()
9615
9650
//Max is 40Hz(?!)
9616
9651
boolean SFE_UBLOX_GNSS::setNavigationFrequency(uint8_t navFreq, uint16_t maxWait)
9617
9652
{
9618
- //if(updateRate > 40) updateRate = 40; //Not needed: module will correct out of bounds values
9653
+ if (navFreq > 40)
9654
+ navFreq = 40; // Limit navFreq to 40Hz so i2cPollingWait is set correctly
9619
9655
9620
9656
//Adjust the I2C polling timeout based on update rate
9621
- i2cPollingWait = 1000 / (((int)navFreq) * 4); //This is the number of ms to wait between checks for new I2C data
9657
+ //Do this even if the sendCommand fails
9658
+ i2cPollingWaitNAV = 1000 / (((int)navFreq) * 4); //This is the number of ms to wait between checks for new I2C data
9659
+ i2cPollingWait = i2cPollingWaitNAV < i2cPollingWaitHNR ? i2cPollingWaitNAV : i2cPollingWaitHNR; // Set i2cPollingWait to the lower of NAV and HNR
9622
9660
9623
9661
//Query the module
9624
9662
packetCfg.cls = UBX_CLASS_CFG;
@@ -9664,8 +9702,12 @@ uint8_t SFE_UBLOX_GNSS::getNavigationFrequency(uint16_t maxWait)
9664
9702
//Set the elapsed time between GNSS measurements in milliseconds, which defines the rate
9665
9703
boolean SFE_UBLOX_GNSS::setMeasurementRate(uint16_t rate, uint16_t maxWait)
9666
9704
{
9705
+ if (rate < 25) // "Measurement rate should be greater than or equal to 25 ms."
9706
+ rate = 25;
9707
+
9667
9708
//Adjust the I2C polling timeout based on update rate
9668
- i2cPollingWait = rate / 4; //This is the number of ms to wait between checks for new I2C data
9709
+ i2cPollingWaitNAV = rate / 4; //This is the number of ms to wait between checks for new I2C data
9710
+ i2cPollingWait = i2cPollingWaitNAV < i2cPollingWaitHNR ? i2cPollingWaitNAV : i2cPollingWaitHNR; // Set i2cPollingWait to the lower of NAV and HNR
9669
9711
9670
9712
//Query the module
9671
9713
packetCfg.cls = UBX_CLASS_CFG;
@@ -10950,6 +10992,14 @@ boolean SFE_UBLOX_GNSS::getSensorFusionStatus(UBX_ESF_STATUS_sensorStatus_t *sen
10950
10992
// Returns true if the setHNRNavigationRate is successful
10951
10993
boolean SFE_UBLOX_GNSS::setHNRNavigationRate(uint8_t rate, uint16_t maxWait)
10952
10994
{
10995
+ if (rate > 40)
10996
+ rate = 40; // Limit rate to 40Hz so i2cPollingWait is set correctly
10997
+
10998
+ //Adjust the I2C polling timeout based on update rate
10999
+ //Do this even if the sendCommand is not ACK'd
11000
+ i2cPollingWaitHNR = 1000 / (((int)rate) * 4); //This is the number of ms to wait between checks for new I2C data
11001
+ i2cPollingWait = i2cPollingWaitNAV < i2cPollingWaitHNR ? i2cPollingWaitNAV : i2cPollingWaitHNR; // Set i2cPollingWait to the lower of NAV and HNR
11002
+
10953
11003
packetCfg.cls = UBX_CLASS_CFG;
10954
11004
packetCfg.id = UBX_CFG_HNR;
10955
11005
packetCfg.len = 0;
@@ -10965,10 +11015,6 @@ boolean SFE_UBLOX_GNSS::setHNRNavigationRate(uint8_t rate, uint16_t maxWait)
10965
11015
//Update the navigation rate
10966
11016
sfe_ublox_status_e result = sendCommand(&packetCfg, maxWait); // We are only expecting an ACK
10967
11017
10968
- //Adjust the I2C polling timeout based on update rate
10969
- if (result == SFE_UBLOX_STATUS_DATA_SENT)
10970
- i2cPollingWait = 1000 / (((int)rate) * 4); //This is the number of ms to wait between checks for new I2C data
10971
-
10972
11018
return (result == SFE_UBLOX_STATUS_DATA_SENT);
10973
11019
}
10974
11020
0 commit comments