@@ -715,11 +715,28 @@ boolean SFE_UBLOX_GNSS::checkUbloxI2C(ubxPacket *incomingUBX, uint8_t requestedC
715715 uint16_t bytesAvailable = 0 ;
716716 _i2cPort->beginTransmission (_gpsI2Caddress);
717717 _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+ }
719726 return (false ); // Sensor did not ACK
727+ }
720728
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())
723740 {
724741 uint8_t msb = _i2cPort->read ();
725742 uint8_t lsb = _i2cPort->read ();
@@ -728,7 +745,8 @@ boolean SFE_UBLOX_GNSS::checkUbloxI2C(ubxPacket *incomingUBX, uint8_t requestedC
728745 // I believe this is a u-blox bug. Device should never present an 0xFF.
729746 if ((_printDebug == true ) || (_printLimitedDebug == true )) // This is important. Print this if doing limited debugging
730747 {
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);
732750 }
733751 if (debugPin >= 0 )
734752 {
@@ -739,6 +757,23 @@ boolean SFE_UBLOX_GNSS::checkUbloxI2C(ubxPacket *incomingUBX, uint8_t requestedC
739757 lastCheck = millis (); // Put off checking to avoid I2C bus traffic
740758 return (false );
741759 }
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+ // }
742777 bytesAvailable = (uint16_t )msb << 8 | lsb;
743778 }
744779
@@ -762,17 +797,17 @@ boolean SFE_UBLOX_GNSS::checkUbloxI2C(ubxPacket *incomingUBX, uint8_t requestedC
762797 // Clear the MSbit
763798 bytesAvailable &= ~((uint16_t )1 << 15 );
764799
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+ // }
776811 }
777812
778813#ifndef SFE_UBLOX_REDUCED_PROG_MEM
@@ -9615,10 +9650,13 @@ uint32_t SFE_UBLOX_GNSS::getProcessNMEAMask()
96159650// Max is 40Hz(?!)
96169651boolean SFE_UBLOX_GNSS::setNavigationFrequency (uint8_t navFreq, uint16_t maxWait)
96179652{
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
96199655
96209656 // 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
96229660
96239661 // Query the module
96249662 packetCfg.cls = UBX_CLASS_CFG;
@@ -9664,8 +9702,12 @@ uint8_t SFE_UBLOX_GNSS::getNavigationFrequency(uint16_t maxWait)
96649702// Set the elapsed time between GNSS measurements in milliseconds, which defines the rate
96659703boolean SFE_UBLOX_GNSS::setMeasurementRate (uint16_t rate, uint16_t maxWait)
96669704{
9705+ if (rate < 25 ) // "Measurement rate should be greater than or equal to 25 ms."
9706+ rate = 25 ;
9707+
96679708 // 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
96699711
96709712 // Query the module
96719713 packetCfg.cls = UBX_CLASS_CFG;
@@ -10950,6 +10992,14 @@ boolean SFE_UBLOX_GNSS::getSensorFusionStatus(UBX_ESF_STATUS_sensorStatus_t *sen
1095010992// Returns true if the setHNRNavigationRate is successful
1095110993boolean SFE_UBLOX_GNSS::setHNRNavigationRate (uint8_t rate, uint16_t maxWait)
1095210994{
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+
1095311003 packetCfg.cls = UBX_CLASS_CFG;
1095411004 packetCfg.id = UBX_CFG_HNR;
1095511005 packetCfg.len = 0 ;
@@ -10965,10 +11015,6 @@ boolean SFE_UBLOX_GNSS::setHNRNavigationRate(uint8_t rate, uint16_t maxWait)
1096511015 // Update the navigation rate
1096611016 sfe_ublox_status_e result = sendCommand (&packetCfg, maxWait); // We are only expecting an ACK
1096711017
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-
1097211018 return (result == SFE_UBLOX_STATUS_DATA_SENT);
1097311019}
1097411020
0 commit comments