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

Commit 21b708a

Browse files
committed
Make I2C polling dynamic based on update freq. Add error check on bytes avialable.
This allows us to more agressively check for I2C data as the user increases the update rate. Also added crazy too big error check on bytes available. On the Artemis, there is sometimes the first bit of the bytes available erroneously set to 1. This causes a very large amount of bytes to be read and many valid packets to not be acted upon. There are still some dropped packets but getting cleaner at 10Hz.
1 parent 00ef7b3 commit 21b708a

File tree

2 files changed

+41
-19
lines changed

2 files changed

+41
-19
lines changed

src/SparkFun_Ublox_Arduino_Library.cpp

+36-18
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ boolean SFE_UBLOX_GPS::checkUblox()
211211
//Returns true if new bytes are available
212212
boolean SFE_UBLOX_GPS::checkUbloxI2C()
213213
{
214-
if (millis() - lastCheck >= I2C_POLLING_WAIT_MS)
214+
if (millis() - lastCheck >= i2cPollingWait)
215215
{
216216
//Get the number of bytes available from the module
217217
uint16_t bytesAvailable = 0;
@@ -241,6 +241,31 @@ boolean SFE_UBLOX_GPS::checkUbloxI2C()
241241
return (false);
242242
}
243243

244+
//Check for bit error
245+
//This error is rare but if we incorrectly interpret the first bit of the two 'data available' bytes as 1
246+
//then we have far too many bytes to check
247+
//Correct back down to
248+
if (bytesAvailable & ((uint16_t)1 << 15))
249+
{
250+
//Clear the MSbit
251+
bytesAvailable &= ~((uint16_t)1 << 15);
252+
253+
if (_printDebug == true)
254+
{
255+
_debugSerial->print("Bytes available error:");
256+
_debugSerial->println(bytesAvailable);
257+
}
258+
}
259+
260+
if (bytesAvailable > 100)
261+
{
262+
if (_printDebug == true)
263+
{
264+
_debugSerial->print("Bytes available:");
265+
_debugSerial->println(bytesAvailable);
266+
}
267+
}
268+
244269
while (bytesAvailable)
245270
{
246271
_i2cPort->beginTransmission(_gpsI2Caddress);
@@ -303,16 +328,6 @@ boolean SFE_UBLOX_GPS::checkUbloxSerial()
303328
//Take a given byte and file it into the proper array
304329
void SFE_UBLOX_GPS::process(uint8_t incoming)
305330
{
306-
307-
if (_printDebug == true)
308-
{
309-
//if (currentSentence == NONE && incoming == 0xB5) //UBX binary frames start with 0xB5, aka μ
310-
// _debugSerial->println(); //Show new packet start
311-
312-
//_debugSerial->print(" ");
313-
//_debugSerial->print(incoming, HEX);
314-
}
315-
316331
if (currentSentence == NONE || currentSentence == NMEA)
317332
{
318333
if (incoming == 0xB5) //UBX binary frames start with 0xB5, aka μ
@@ -510,15 +525,15 @@ void SFE_UBLOX_GPS::processUBX(uint8_t incoming, ubxPacket *incomingUBX)
510525
debugPrintln("Checksum failed. Response too big?");
511526

512527
//Drive an external pin to allow for easier logic analyzation
513-
// digitalWrite(2, LOW);
514-
// delay(10);
515-
// digitalWrite(2, HIGH);
516-
517-
_debugSerial->print("Received: ");
518-
printPacket(incomingUBX);
528+
digitalWrite(2, LOW);
529+
delay(10);
530+
digitalWrite(2, HIGH);
519531

520532
_debugSerial->print("Size: ");
521533
_debugSerial->print(incomingUBX->len);
534+
_debugSerial->print(" Received: ");
535+
printPacket(incomingUBX);
536+
522537
_debugSerial->print(" checksumA: ");
523538
_debugSerial->print(incomingUBX->checksumA);
524539
_debugSerial->print(" checksumB: ");
@@ -891,7 +906,7 @@ boolean SFE_UBLOX_GPS::waitForResponse(uint8_t requestedClass, uint8_t requested
891906
}
892907
}
893908

894-
delay(1);
909+
delayMicroseconds(500);
895910
}
896911

897912
debugPrintln("waitForResponse timeout");
@@ -1251,6 +1266,9 @@ boolean SFE_UBLOX_GPS::setNavigationFrequency(uint8_t navFreq, uint16_t maxWait)
12511266
{
12521267
//if(updateRate > 40) updateRate = 40; //Not needed: module will correct out of bounds values
12531268

1269+
//Adjust the I2C polling timeout based on update rate
1270+
i2cPollingWait = 1000 / (navFreq * 4); //This is the number of ms to wait between checks for new I2C data
1271+
12541272
//Query the module for the latest lat/long
12551273
packetCfg.cls = UBX_CLASS_CFG;
12561274
packetCfg.id = UBX_CFG_RATE;

src/SparkFun_Ublox_Arduino_Library.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,11 @@ class SFE_UBLOX_GPS
428428
ubxPacket packetAck = {0, 0, 0, 0, 0, payloadAck, 0, 0, false};
429429
ubxPacket packetCfg = {0, 0, 0, 0, 0, payloadCfg, 0, 0, false};
430430

431-
const uint8_t I2C_POLLING_WAIT_MS = 100; //Limit checking of new characters to every X ms
431+
//Limit checking of new data to every X ms
432+
//If we are expecting an update every X Hz then we should check every half that amount of time
433+
//Otherwise we may block ourselves from seeing new data
434+
uint8_t i2cPollingWait = 100; //Default to 100ms. Adjusted when user calls setNavigationFrequency()
435+
432436
unsigned long lastCheck = 0;
433437
boolean autoPVT = false; //Whether autoPVT is enabled or not
434438
boolean commandAck = false; //This goes true after we send a command and it's ack'd

0 commit comments

Comments
 (0)