From e53424c57ca36f249a33a8b36b668d9656f709cd Mon Sep 17 00:00:00 2001 From: PaulZC Date: Thu, 31 Dec 2020 08:09:38 +0000 Subject: [PATCH] v1.8.10. u-blox corrections. Improved .begin and .isConnected. The main improvement here is that isConnected will return true if sendCommand returns DATA_RECEIVED or DATA_OVERWRITTEN. The RATE reply is likely to be overwritten if auto HNR messages are already enabled. --- README.md | 4 ++-- Theory.md | 8 +++---- library.properties | 2 +- src/SparkFun_Ublox_Arduino_Library.cpp | 31 +++++++++++++++++++++++--- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3936f47..35ab39d 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ SparkFun u-blox Arduino Library U-blox makes some incredible GPS receivers covering everything from low-cost, highly configurable modules such as the SAM-M8Q all the way up to the surveyor grade ZED-F9P with precision of the diameter of a dime. This library focuses on configuration and control of u-blox devices over I2C (called DDC by u-blox) and Serial. The UBX protocol is supported over both I2C and serial, and is a much easier and lighterweight interface to a GPS module. Stop parsing NMEA data! And simply ask for the datums you need. -This library can be installed via the Arduino Library manager. Search for **SparkFun Ublox**. +This library can be installed via the Arduino Library manager. Search for **SparkFun u-blox GNSS**. Although not an integrated part of the library, you will find an example of how to communicate with the older series 6 and 7 modules in the [examples folder](./examples/Series_6_7). @@ -58,7 +58,7 @@ Thanks to: Need a Python version for Raspberry Pi? Checkout the [Qwiic Ublox GPS Py module](https://github.com/sparkfun/Qwiic_Ublox_Gps_Py). -Need a library for the Ublox and Particle? Checkout the [Particle library](https://github.com/aseelye/SparkFun_Ublox_Particle_Library) fork. +Need a library for the u-blox and Particle? Checkout the [Particle library](https://github.com/aseelye/SparkFun_Ublox_Particle_Library) fork. Contributing -------------- diff --git a/Theory.md b/Theory.md index 53511e3..6469b3e 100644 --- a/Theory.md +++ b/Theory.md @@ -1,7 +1,7 @@ -How I2C (aka DDC) communication works with a uBlox module +How I2C (aka DDC) communication works with a u-blox module =========================================================== -When the user calls one of the methods the library will poll the Ublox module for new data. +When the user calls one of the methods the library will poll the u-blox module for new data. * Wait for a minimum of 25 ms between polls (configured dynamically when update rate is set) * Write 0xFD to module @@ -17,9 +17,9 @@ How data is processed by this library A method will call **sendCommand()**. This will begin waiting for a response with either **waitForACKResponse()** or **waitForNoACKResponse()** depending on the command we have sent (CFG commands generate an ACK where others like PVT do not). -Once **waitForACKResponse()** or **waitForNoACKResponse()** is called the library will start checking the ublox module for new bytes. These bytes may be part of a NMEA sentence, an RTCM sentence, or a UBX packet. The library will file each byte into the appropriate container. Once a given sentence or packet is complete, the appropriate processUBX(), processNMEA() will be called. These functions deal with specific processing for each type. +Once **waitForACKResponse()** or **waitForNoACKResponse()** is called the library will start checking the u-blox module for new bytes. These bytes may be part of a NMEA sentence, an RTCM sentence, or a UBX packet. The library will file each byte into the appropriate container. Once a given sentence or packet is complete, the appropriate processUBX(), processNMEA() will be called. These functions deal with specific processing for each type. -Note: When interfacing to a ublox module over I2C **checkUbloxI2C()** will read all bytes currently sitting in the I2C buffer. This may pick up multiple UBX packets. For example, an ACK for a VALSET may be mixed in with an **AutoPVT** response. We cannot tell **checkUbloxI2C()** to stop once a given ACK is found because we run the risk of leaving unprocessed bytes in the I2C buffer and losing them. We don't have this issue with **checkUbloxSerial()**. +Note: When interfacing to a u-blox module over I2C **checkUbloxI2C()** will read all bytes currently sitting in the I2C buffer. This may pick up multiple UBX packets. For example, an ACK for a VALSET may be mixed in with an **AutoPVT** response. We cannot tell **checkUbloxI2C()** to stop once a given ACK is found because we run the risk of leaving unprocessed bytes in the I2C buffer and losing them. We don't have this issue with **checkUbloxSerial()**. **processUBX()** will check the CRC of the UBX packet. If validated, the packet will be marked as valid. Once a packet is marked as valid then **processUBXpacket()** is called to extract the contents. This is most commonly used to get the position, velocity, and time (PVT) out of the packet but is also used to check the nature of an ACK packet. diff --git a/library.properties b/library.properties index a3f6858..bd172b4 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=SparkFun u-blox Arduino Library -version=1.8.9 +version=1.8.10 author=SparkFun Electronics maintainer=SparkFun Electronics sentence=Library for I2C and Serial Communication with u-blox modules diff --git a/src/SparkFun_Ublox_Arduino_Library.cpp b/src/SparkFun_Ublox_Arduino_Library.cpp index 224305d..7fc43de 100644 --- a/src/SparkFun_Ublox_Arduino_Library.cpp +++ b/src/SparkFun_Ublox_Arduino_Library.cpp @@ -92,7 +92,16 @@ boolean SFE_UBLOX_GPS::begin(TwoWire &wirePort, uint8_t deviceAddress) _gpsI2Caddress = deviceAddress; //Store the I2C address from user - return (isConnected()); + // Attempt isConnected up to 3 times if required + boolean success = isConnected(); + + if (!success) + success = isConnected(); + + if (!success) + success = isConnected(); + + return (success); } //Initialize the Serial port @@ -101,7 +110,16 @@ boolean SFE_UBLOX_GPS::begin(Stream &serialPort) commType = COMM_TYPE_SERIAL; _serialPort = &serialPort; //Grab which port the user wants us to use - return (isConnected()); + // Attempt isConnected up to 3 times if required + boolean success = isConnected(); + + if (!success) + success = isConnected(); + + if (!success) + success = isConnected(); + + return (success); } //Sets the global size for I2C transactions @@ -1401,7 +1419,14 @@ boolean SFE_UBLOX_GPS::isConnected(uint16_t maxWait) packetCfg.len = 0; packetCfg.startingSpot = 0; - return (sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_RECEIVED); // We are polling the RATE so we expect data and an ACK + sfe_ublox_status_e result = sendCommand(&packetCfg, maxWait); // Poll the navigation rate + + // In this case, we don't acutally care what the navigation rate is, we're just polling it to indicate a connection. + // So we return true if result is DATA_RECEIVED or DATA_OVERWRITTEN (just in case the RATE was overwritten by an auto packet). + if ((result == SFE_UBLOX_STATUS_DATA_RECEIVED) || (result == SFE_UBLOX_STATUS_DATA_OVERWRITTEN)) + return (true); + else + return (false); } //Given a message, calc and store the two byte "8-Bit Fletcher" checksum over the entirety of the message