diff --git a/examples/Example16_Nanosecond_MaxOutput/Example16_Nanosecond_MaxOutput.ino b/examples/Example16_Nanosecond_MaxOutput/Example16_Nanosecond_MaxOutput.ino index 0f159f2..6fa1d68 100644 --- a/examples/Example16_Nanosecond_MaxOutput/Example16_Nanosecond_MaxOutput.ino +++ b/examples/Example16_Nanosecond_MaxOutput/Example16_Nanosecond_MaxOutput.ino @@ -99,8 +99,8 @@ void loop() Serial.print(myGNSS.getMinute()); Serial.print(":"); Serial.print(myGNSS.getSecond()); - Serial.print("."); - Serial.print(myGNSS.getNanosecond()); + Serial.print(" nanoseconds: "); + Serial.print(myGNSS.getNanosecond()); // Nanoseconds can be negative myGNSS.flushPVT(); diff --git a/examples/Example16_PartialSecond_MaxOutput/Example16_PartialSecond_MaxOutput.ino b/examples/Example16_PartialSecond_MaxOutput/Example16_PartialSecond_MaxOutput.ino index 58c8876..aee070b 100644 --- a/examples/Example16_PartialSecond_MaxOutput/Example16_PartialSecond_MaxOutput.ino +++ b/examples/Example16_PartialSecond_MaxOutput/Example16_PartialSecond_MaxOutput.ino @@ -110,7 +110,7 @@ void loop() Serial.print("0"); Serial.print(mseconds); - Serial.print(" nanoSeconds: "); + Serial.print(" nanoseconds: "); Serial.print(myGNSS.getNanosecond()); Serial.println(); diff --git a/examples/Example24_GetUnixEpochAndMicros/Example24_GetUnixEpochAndMicros.ino b/examples/Example24_GetUnixEpochAndMicros/Example24_GetUnixEpochAndMicros.ino index b3ea934..2ebdc2a 100644 --- a/examples/Example24_GetUnixEpochAndMicros/Example24_GetUnixEpochAndMicros.ino +++ b/examples/Example24_GetUnixEpochAndMicros/Example24_GetUnixEpochAndMicros.ino @@ -1,7 +1,7 @@ /* Getting Unix Epoch Time and micros using u-blox commands By: UT2UH - Date: March 30th, 2021 + Date: March 31th, 2021 License: MIT. See license file for more information but you can basically do whatever you want with this code. @@ -69,8 +69,11 @@ void loop() // getUnixEpoch marks the PVT data as stale so you will get Unix time and PVT time on alternate seconds uint32_t us; //microseconds returned by getUnixEpoch() - uint32_t epoch = myGNSS.getUnixEpoch(us); - Serial.print("Unix Epoch: "); + uint32_t epoch = myGNSS.getUnixEpoch(); + Serial.print("Unix Epoch rounded: "); + Serial.print(epoch, DEC); + epoch = myGNSS.getUnixEpoch(us); + Serial.print(" Exact Unix Epoch: "); Serial.print(epoch, DEC); Serial.print(" micros: "); Serial.println(us, DEC); @@ -105,4 +108,4 @@ void loop() Serial.print(F(" SIV: ")); Serial.println(SIV); } -} +} \ No newline at end of file diff --git a/examples/Example26_End/Example26_End.ino b/examples/Example26_End/Example26_End.ino new file mode 100644 index 0000000..077ed90 --- /dev/null +++ b/examples/Example26_End/Example26_End.ino @@ -0,0 +1,91 @@ +/* + Demonstrating how to use "end" + By: Paul Clark + SparkFun Electronics + Date: April 1st, 2021 + License: MIT. See license file for more information but you can + basically do whatever you want with this code. + + This example shows how to use the end function. + End will stop all automatic message processing and free (nearly) all used RAM. + The file buffer is deleted (if it exists). + + Feel like supporting open source hardware? + Buy a board from SparkFun! + ZED-F9P RTK2: https://www.sparkfun.com/products/15136 + NEO-M8P RTK: https://www.sparkfun.com/products/15005 + SAM-M8Q: https://www.sparkfun.com/products/15106 + + Hardware Connections: + Plug a Qwiic cable into the GNSS and a BlackBoard + If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425) + Open the serial monitor at 115200 baud to see the output +*/ + +#include //Needed for I2C to GNSS + +#include //http://librarymanager/All#SparkFun_u-blox_GNSS +SFE_UBLOX_GNSS myGNSS; + +void setup() +{ + Serial.begin(115200); + while (!Serial); //Wait for user to open terminal + Serial.println("SparkFun u-blox Example"); + + Wire.begin(); + + //myGNSS.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + if (myGNSS.begin() == false) //Connect to the u-blox module using Wire port + { + Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing.")); + while (1); + } + + myGNSS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise) + //myGNSS.saveConfiguration(); //Optional: Save the current settings to flash and BBR + + myGNSS.end(); // Call end now just because we can - it won't do much as we haven't used any automatic messages +} + +void loop() +{ + // Allocate 128 bytes for file storage - this checks that issue #20 has been resolved + // Allocating only 128 bytes will let this code run on the ATmega328P + // If your processor has plenty of RAM, you can increase this to something useful like 16KB + myGNSS.setFileBufferSize(128); + + if (myGNSS.begin() == false) //Connect to the u-blox module using Wire port + { + Serial.println(F("u-blox GNSS not detected. Freezing.")); + while (1); + } + + Serial.print(F("The file buffer size is: ")); + Serial.println(myGNSS.getFileBufferSize()); + + // Request Position, Velocity, Time + // RAM will be allocated for PVT message processing + // getPVT will return true is fresh PVT data was received and processed + if (myGNSS.getPVT()) + { + long latitude = myGNSS.getLatitude(); + Serial.print(F("Lat: ")); + Serial.print(latitude); + + long longitude = myGNSS.getLongitude(); + Serial.print(F(" Long: ")); + Serial.print(longitude); + Serial.print(F(" (degrees * 10^-7)")); + + long altitude = myGNSS.getAltitude(); + Serial.print(F(" Alt: ")); + Serial.print(altitude); + Serial.println(F(" (mm)")); + } + + // Calling end will free the RAM allocated for file storage and PVT processing + // Calling end is optional. You can comment the next line if you want to. + myGNSS.end(); +} diff --git a/examples/Example27_MultipleRates/Example27_MultipleRates.ino b/examples/Example27_MultipleRates/Example27_MultipleRates.ino new file mode 100644 index 0000000..057b493 --- /dev/null +++ b/examples/Example27_MultipleRates/Example27_MultipleRates.ino @@ -0,0 +1,106 @@ +/* + Configuring the GNSS to produce multiple messages at different rates + By: Paul Clark + SparkFun Electronics + Date: April 1st, 2021 + License: MIT. See license file for more information but you can + basically do whatever you want with this code. + + This example shows how to configure the U-Blox GNSS to output multiple messages at different rates: + PVT is output every second; + POSECEF is output every five seconds; + VELNED is output every ten seconds. + + Feel like supporting open source hardware? + Buy a board from SparkFun! + ZED-F9P RTK2: https://www.sparkfun.com/products/15136 + NEO-M8P RTK: https://www.sparkfun.com/products/15005 + SAM-M8Q: https://www.sparkfun.com/products/15106 + + Hardware Connections: + Plug a Qwiic cable into the GNSS and a BlackBoard + If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425) + Open the serial monitor at 115200 baud to see the output +*/ + +#include //Needed for I2C to GNSS + +#include //http://librarymanager/All#SparkFun_u-blox_GNSS +SFE_UBLOX_GNSS myGNSS; + +void setup() +{ + Serial.begin(115200); + while (!Serial); //Wait for user to open terminal + Serial.println("SparkFun u-blox Example"); + + Wire.begin(); + + if (myGNSS.begin() == false) //Connect to the u-blox module using Wire port + { + Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing.")); + while (1); + } + + myGNSS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise) + myGNSS.setMeasurementRate(1000); //Produce a measurement every 1000ms + myGNSS.setNavigationRate(1); //Produce a navigation solution every measurement + + myGNSS.setAutoPVTrate(1); //Tell the GNSS to send the PVT solution every measurement + myGNSS.setAutoNAVPOSECEFrate(5); //Tell the GNSS to send each POSECEF solution every 5th measurement + myGNSS.setAutoNAVVELNEDrate(10); //Tell the GNSS to send each VELNED solution every 10th measurement + //myGNSS.saveConfiguration(); //Optional: Save the current settings to flash and BBR +} + +void loop() +{ + // Calling getPVT returns true if there actually is a fresh navigation solution available. + if (myGNSS.getPVT()) + { + long latitude = myGNSS.getLatitude(); + Serial.print(F("Lat: ")); + Serial.print(latitude); + + long longitude = myGNSS.getLongitude(); + Serial.print(F(" Long: ")); + Serial.print(longitude); + Serial.print(F(" (degrees * 10^-7)")); + + long altitude = myGNSS.getAltitude(); + Serial.print(F(" Alt: ")); + Serial.print(altitude); + Serial.println(F(" (mm)")); + } + + // Calling getNAVPOSECEF returns true if there actually is a fresh position solution available. + if (myGNSS.getNAVPOSECEF()) + { + Serial.print(F("ecefX: ")); + Serial.print((float)myGNSS.packetUBXNAVPOSECEF->data.ecefX / 100.0, 2); // convert ecefX to m + + Serial.print(F(" ecefY: ")); + Serial.print((float)myGNSS.packetUBXNAVPOSECEF->data.ecefY / 100.0, 2); // convert ecefY to m + + Serial.print(F(" ecefZ: ")); + Serial.print((float)myGNSS.packetUBXNAVPOSECEF->data.ecefZ / 100.0, 2); // convert ecefY to m + Serial.println(F(" (m)")); + + myGNSS.flushNAVPOSECEF(); //Mark all the data as read/stale so we get fresh data next time + } + + // Calling getNAVVELNED returns true if there actually is fresh velocity data available. + if (myGNSS.getNAVVELNED()) + { + Serial.print(F("velN: ")); + Serial.print((float)myGNSS.packetUBXNAVVELNED->data.velN / 100.0, 2); // convert velN to m/s + + Serial.print(F(" velE: ")); + Serial.print((float)myGNSS.packetUBXNAVVELNED->data.velE / 100.0, 2); // convert velE to m/s + + Serial.print(F(" velD: ")); + Serial.print((float)myGNSS.packetUBXNAVVELNED->data.velD / 100.0, 2); // convert velD to m/s + Serial.println(F(" (m/s)")); + + myGNSS.flushNAVVELNED(); //Mark all the data as read/stale so we get fresh data next time + } +} diff --git a/examples/ZED-F9P/Example10_GetHighPrecisionPositionAndAccuracy/Example10_GetHighPrecisionPositionAndAccuracy.ino b/examples/ZED-F9P/Example10_GetHighPrecisionPositionAndAccuracy/Example10_GetHighPrecisionPositionAndAccuracy.ino index 90d97ea..0496d5c 100644 --- a/examples/ZED-F9P/Example10_GetHighPrecisionPositionAndAccuracy/Example10_GetHighPrecisionPositionAndAccuracy.ino +++ b/examples/ZED-F9P/Example10_GetHighPrecisionPositionAndAccuracy/Example10_GetHighPrecisionPositionAndAccuracy.ino @@ -115,11 +115,12 @@ void loop() Serial.print("Lat (deg): "); Serial.print(lat_int); // Print the integer part of the latitude Serial.print("."); - Serial.print(lat_frac); // Print the fractional part of the latitude + printFractional(lat_frac, 9); // Print the fractional part of the latitude with leading zeros Serial.print(", Lon (deg): "); Serial.print(lon_int); // Print the integer part of the latitude Serial.print("."); - Serial.println(lon_frac); // Print the fractional part of the latitude + printFractional(lon_frac, 9); // Print the fractional part of the latitude with leading zeros + Serial.println(); // Now define float storage for the heights and accuracy float f_ellipsoid; @@ -152,3 +153,20 @@ void loop() Serial.println(f_accuracy, 4); // Print the accuracy with 4 decimal places } } + +// Pretty-print the fractional part with leading zeros - without using printf +// (Only works with positive numbers) +void printFractional(int32_t fractional, uint8_t places) +{ + if (places > 1) + { + for (uint8_t place = places - 1; place > 0; place--) + { + if (fractional < pow(10, place)) + { + Serial.print("0"); + } + } + } + Serial.print(fractional); +} diff --git a/keywords.txt b/keywords.txt index 3a24b76..f320104 100644 --- a/keywords.txt +++ b/keywords.txt @@ -50,6 +50,7 @@ UBX_HNR_INS_data_t KEYWORD1 setPacketCfgPayloadSize KEYWORD2 begin KEYWORD2 +end KEYWORD2 setI2CpollingWait KEYWORD2 setI2CTransactionSize KEYWORD2 getI2CTransactionSize KEYWORD2 @@ -81,6 +82,7 @@ checkCallbacks KEYWORD2 pushRawData KEYWORD2 setFileBufferSize KEYWORD2 +getFileBufferSize KEYWORD2 extractFileBufferData KEYWORD2 fileBufferAvailable KEYWORD2 getMaxFileBufferAvail KEYWORD2 @@ -164,7 +166,7 @@ sendCfgValset32 KEYWORD2 getNAVPOSECEF KEYWORD2 setAutoNAVPOSECEF KEYWORD2 -setAutoNAVPOSECEF KEYWORD2 +setAutoNAVPOSECEFrate KEYWORD2 setAutoNAVPOSECEFcallback KEYWORD2 assumeAutoNAVPOSECEF KEYWORD2 initPacketUBXNAVPOSECEF KEYWORD2 @@ -173,7 +175,7 @@ logNAVPOSECEF KEYWORD2 getNAVSTATUS KEYWORD2 setAutoNAVSTATUS KEYWORD2 -setAutoNAVSTATUS KEYWORD2 +setAutoNAVSTATUSrate KEYWORD2 setAutoNAVSTATUScallback KEYWORD2 assumeAutoNAVSTATUS KEYWORD2 initPacketUBXNAVSTATUS KEYWORD2 @@ -182,7 +184,7 @@ logNAVSTATUS KEYWORD2 getDOP KEYWORD2 setAutoDOP KEYWORD2 -setAutoDOP KEYWORD2 +setAutoDOPrate KEYWORD2 setAutoDOPcallback KEYWORD2 assumeAutoDOP KEYWORD2 initPacketUBXNAVDOP KEYWORD2 @@ -192,7 +194,7 @@ logNAVDOP KEYWORD2 getVehAtt KEYWORD2 getNAVATT KEYWORD2 setAutoNAVATT KEYWORD2 -setAutoNAVATT KEYWORD2 +setAutoNAVATTrate KEYWORD2 setAutoNAVATTcallback KEYWORD2 assumeAutoNAVATT KEYWORD2 initPacketUBXNAVATT KEYWORD2 @@ -201,7 +203,7 @@ logNAVATT KEYWORD2 getPVT KEYWORD2 setAutoPVT KEYWORD2 -setAutoPVT KEYWORD2 +setAutoPVTrate KEYWORD2 setAutoPVTcallback KEYWORD2 assumeAutoPVT KEYWORD2 initPacketUBXNAVPVT KEYWORD2 @@ -210,7 +212,7 @@ logNAVPVT KEYWORD2 getNAVODO KEYWORD2 setAutoNAVODO KEYWORD2 -setAutoNAVODO KEYWORD2 +setAutoNAVODOrate KEYWORD2 setAutoNAVODOcallback KEYWORD2 assumeAutoNAVODO KEYWORD2 initPacketUBXNAVODO KEYWORD2 @@ -219,7 +221,7 @@ logNAVODO KEYWORD2 getNAVVELECEF KEYWORD2 setAutoNAVVELECEF KEYWORD2 -setAutoNAVVELECEF KEYWORD2 +setAutoNAVVELECEFrate KEYWORD2 setAutoNAVVELECEFcallback KEYWORD2 assumeAutoNAVVELECEF KEYWORD2 initPacketUBXNAVVELECEF KEYWORD2 @@ -228,6 +230,7 @@ logNAVVELECEF KEYWORD2 getNAVVELNED KEYWORD2 setAutoNAVVELNED KEYWORD2 +setAutoNAVVELNEDrate KEYWORD2 setAutoNAVVELNEDcallback KEYWORD2 assumeAutoNAVVELNED KEYWORD2 initPacketUBXNAVVELNED KEYWORD2 @@ -236,7 +239,7 @@ logNAVVELNED KEYWORD2 getNAVHPPOSECEF KEYWORD2 setAutoNAVHPPOSECEF KEYWORD2 -setAutoNAVHPPOSECEF KEYWORD2 +setAutoNAVHPPOSECEFrate KEYWORD2 setAutoNAVHPPOSECEFcallback KEYWORD2 assumeAutoNAVHPPOSECEF KEYWORD2 initPacketUBXNAVHPPOSECEF KEYWORD2 @@ -245,7 +248,7 @@ logNAVHPPOSECEF KEYWORD2 getHPPOSLLH KEYWORD2 setAutoHPPOSLLH KEYWORD2 -setAutoHPPOSLLH KEYWORD2 +setAutoHPPOSLLHrate KEYWORD2 setAutoHPPOSLLHcallback KEYWORD2 assumeAutoHPPOSLLH KEYWORD2 initPacketUBXNAVHPPOSLLH KEYWORD2 @@ -254,7 +257,7 @@ logNAVHPPOSLLH KEYWORD2 getNAVCLOCK KEYWORD2 setAutoNAVCLOCK KEYWORD2 -setAutoNAVCLOCK KEYWORD2 +setAutoNAVCLOCKrate KEYWORD2 setAutoNAVCLOCKcallback KEYWORD2 assumeAutoNAVCLOCK KEYWORD2 initPacketUBXNAVCLOCK KEYWORD2 @@ -266,6 +269,7 @@ initPacketUBXNAVSVIN KEYWORD2 getRELPOSNED KEYWORD2 setAutoRELPOSNED KEYWORD2 +setAutoRELPOSNEDrate KEYWORD2 setAutoRELPOSNEDcallback KEYWORD2 assumeAutoRELPOSNED KEYWORD2 initPacketUBXNAVRELPOSNED KEYWORD2 @@ -274,6 +278,7 @@ logNAVRELPOSNED KEYWORD2 getRXMSFRBX KEYWORD2 setAutoRXMSFRBX KEYWORD2 +setAutoRXMSFRBXrate KEYWORD2 setAutoRXMSFRBXcallback KEYWORD2 assumeAutoRXMSFRBX KEYWORD2 initPacketUBXRXMSFRBX KEYWORD2 @@ -282,7 +287,7 @@ logRXMSFRBX KEYWORD2 getRXMRAWX KEYWORD2 setAutoRXMRAWX KEYWORD2 -setAutoRXMRAWX KEYWORD2 +setAutoRXMRAWXrate KEYWORD2 setAutoRXMRAWXcallback KEYWORD2 assumeAutoRXMRAWX KEYWORD2 initPacketUBXRXMRAWX KEYWORD2 @@ -291,6 +296,7 @@ logRXMRAWX KEYWORD2 getTIMTM2 KEYWORD2 setAutoTIMTM2 KEYWORD2 +setAutoTIMTM2rate KEYWORD2 setAutoTIMTM2callback KEYWORD2 assumeAutoTIMTM2 KEYWORD2 initPacketUBXTIMTM2 KEYWORD2 @@ -300,6 +306,7 @@ logTIMTM2 KEYWORD2 getEsfAlignment KEYWORD2 getESFALG KEYWORD2 setAutoESFALG KEYWORD2 +setAutoESFALGrate KEYWORD2 setAutoESFALGcallback KEYWORD2 assumeAutoESFALG KEYWORD2 initPacketUBXESFALG KEYWORD2 @@ -309,6 +316,7 @@ logESFALG KEYWORD2 getEsfInfo KEYWORD2 getESFSTATUS KEYWORD2 setAutoESFSTATUS KEYWORD2 +setAutoESFSTATUSrate KEYWORD2 setAutoESFSTATUScallback KEYWORD2 assumeAutoESFSTATUS KEYWORD2 initPacketUBXESFSTATUS KEYWORD2 @@ -318,6 +326,7 @@ logESFSTATUS KEYWORD2 getEsfIns KEYWORD2 getESFINS KEYWORD2 setAutoESFINS KEYWORD2 +setAutoESFINSrate KEYWORD2 setAutoESFINScallback KEYWORD2 assumeAutoESFINS KEYWORD2 initPacketUBXESFINS KEYWORD2 @@ -327,6 +336,7 @@ logESFINS KEYWORD2 getEsfDataInfo KEYWORD2 getESFMEAS KEYWORD2 setAutoESFMEAS KEYWORD2 +setAutoESFMEASrate KEYWORD2 setAutoESFMEAScallback KEYWORD2 assumeAutoESFMEAS KEYWORD2 initPacketUBXESFMEAS KEYWORD2 @@ -336,6 +346,7 @@ logESFMEAS KEYWORD2 getEsfRawDataInfo KEYWORD2 getESFRAW KEYWORD2 setAutoESFRAW KEYWORD2 +setAutoESFRAWrate KEYWORD2 setAutoESFRAWcallback KEYWORD2 assumeAutoESFRAW KEYWORD2 initPacketUBXESFRAW KEYWORD2 @@ -345,6 +356,7 @@ logESFRAW KEYWORD2 getHNRAtt KEYWORD2 getHNRATT KEYWORD2 setAutoHNRATT KEYWORD2 +setAutoHNRATTrate KEYWORD2 setAutoHNRATTcallback KEYWORD2 assumeAutoHNRATT KEYWORD2 initPacketUBXHNRATT KEYWORD2 @@ -354,6 +366,7 @@ logHNRATT KEYWORD2 getHNRDyn KEYWORD2 getHNRINS KEYWORD2 setAutoHNRINS KEYWORD2 +setAutoHNRINSrate KEYWORD2 setAutoHNRINScallback KEYWORD2 assumeAutoHNRINS KEYWORD2 initPacketUBXHNRINS KEYWORD2 @@ -362,7 +375,7 @@ logHNRINS KEYWORD2 getHNRPVT KEYWORD2 setAutoHNRPVT KEYWORD2 -setAutoHNRPVT KEYWORD2 +setAutoHNRPVTrate KEYWORD2 setAutoHNRPVTcallback KEYWORD2 assumeAutoHNRPVT KEYWORD2 initPacketUBXHNRPVT KEYWORD2 diff --git a/library.properties b/library.properties index 41b6fc5..1e27608 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=SparkFun u-blox GNSS Arduino Library -version=2.0.4 +version=2.0.5 author=SparkFun Electronics maintainer=SparkFun Electronics sentence=Library for I2C and Serial Communication with u-blox GNSS modules

diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp index 4d5b20f..2f71233 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp @@ -52,6 +52,297 @@ SFE_UBLOX_GNSS::SFE_UBLOX_GNSS(void) } } +//Stop all automatic message processing. Free all used RAM +void SFE_UBLOX_GNSS::end(void) +{ + //Note: payloadCfg is not deleted + + //Note: payloadAuto is not deleted + + if (ubxFileBuffer != NULL) // Check if RAM has been allocated for the file buffer + { + if (_printDebug == true) + { + _debugSerial->println(F("end: the file buffer has been deleted. You will need to call setFileBufferSize before .begin to create a new one.")); + } + delete[] ubxFileBuffer; + ubxFileBuffer = NULL; // Redundant? + fileBufferSize = 0; // Reset file buffer size. User will have to call setFileBufferSize again + fileBufferMaxAvail = 0; + } + + if (moduleSWVersion != NULL) + { + delete[] moduleSWVersion; + moduleSWVersion = NULL; // Redundant? + } + + if (currentGeofenceParams != NULL) + { + delete[] currentGeofenceParams; + currentGeofenceParams = NULL; // Redundant? + } + + if (packetUBXNAVPOSECEF != NULL) + { + if (packetUBXNAVPOSECEF->callbackData != NULL) + { + delete[] packetUBXNAVPOSECEF->callbackData; + } + delete[] packetUBXNAVPOSECEF; + packetUBXNAVPOSECEF = NULL; // Redundant? + } + + if (packetUBXNAVSTATUS != NULL) + { + if (packetUBXNAVSTATUS->callbackData != NULL) + { + delete[] packetUBXNAVSTATUS->callbackData; + } + delete[] packetUBXNAVSTATUS; + packetUBXNAVSTATUS = NULL; // Redundant? + } + + if (packetUBXNAVDOP != NULL) + { + if (packetUBXNAVDOP->callbackData != NULL) + { + delete[] packetUBXNAVDOP->callbackData; + } + delete[] packetUBXNAVDOP; + packetUBXNAVDOP = NULL; // Redundant? + } + + if (packetUBXNAVATT != NULL) + { + if (packetUBXNAVATT->callbackData != NULL) + { + delete[] packetUBXNAVATT->callbackData; + } + delete[] packetUBXNAVATT; + packetUBXNAVATT = NULL; // Redundant? + } + + if (packetUBXNAVPVT != NULL) + { + if (packetUBXNAVPVT->callbackData != NULL) + { + delete[] packetUBXNAVPVT->callbackData; + if (_printDebug == true) + { + _debugSerial->println(F("end: packetUBXNAVPVT->callbackData has been deleted")); + } + } + delete[] packetUBXNAVPVT; + packetUBXNAVPVT = NULL; // Redundant? + if (_printDebug == true) + { + _debugSerial->println(F("end: packetUBXNAVPVT has been deleted")); + } + } + + if (packetUBXNAVODO != NULL) + { + if (packetUBXNAVODO->callbackData != NULL) + { + delete[] packetUBXNAVODO->callbackData; + } + delete[] packetUBXNAVODO; + packetUBXNAVODO = NULL; // Redundant? + } + + if (packetUBXNAVVELECEF != NULL) + { + if (packetUBXNAVVELECEF->callbackData != NULL) + { + delete[] packetUBXNAVVELECEF->callbackData; + } + delete[] packetUBXNAVVELECEF; + packetUBXNAVVELECEF = NULL; // Redundant? + } + + if (packetUBXNAVVELNED != NULL) + { + if (packetUBXNAVVELNED->callbackData != NULL) + { + delete[] packetUBXNAVVELNED->callbackData; + } + delete[] packetUBXNAVVELNED; + packetUBXNAVVELNED = NULL; // Redundant? + } + + if (packetUBXNAVHPPOSECEF != NULL) + { + if (packetUBXNAVHPPOSECEF->callbackData != NULL) + { + delete[] packetUBXNAVHPPOSECEF->callbackData; + } + delete[] packetUBXNAVHPPOSECEF; + packetUBXNAVHPPOSECEF = NULL; // Redundant? + } + + if (packetUBXNAVHPPOSLLH != NULL) + { + if (packetUBXNAVHPPOSLLH->callbackData != NULL) + { + delete[] packetUBXNAVHPPOSLLH->callbackData; + } + delete[] packetUBXNAVHPPOSLLH; + packetUBXNAVHPPOSLLH = NULL; // Redundant? + } + + if (packetUBXNAVCLOCK != NULL) + { + if (packetUBXNAVCLOCK->callbackData != NULL) + { + delete[] packetUBXNAVCLOCK->callbackData; + } + delete[] packetUBXNAVCLOCK; + packetUBXNAVCLOCK = NULL; // Redundant? + } + + if (packetUBXNAVSVIN != NULL) + { + if (packetUBXNAVSVIN->callbackData != NULL) + { + delete[] packetUBXNAVSVIN->callbackData; + } + delete[] packetUBXNAVSVIN; + packetUBXNAVSVIN = NULL; // Redundant? + } + + if (packetUBXNAVRELPOSNED != NULL) + { + if (packetUBXNAVRELPOSNED->callbackData != NULL) + { + delete[] packetUBXNAVRELPOSNED->callbackData; + } + delete[] packetUBXNAVRELPOSNED; + packetUBXNAVRELPOSNED = NULL; // Redundant? + } + + if (packetUBXRXMSFRBX != NULL) + { + if (packetUBXRXMSFRBX->callbackData != NULL) + { + delete[] packetUBXRXMSFRBX->callbackData; + } + delete[] packetUBXRXMSFRBX; + packetUBXRXMSFRBX = NULL; // Redundant? + } + + if (packetUBXRXMRAWX != NULL) + { + if (packetUBXRXMRAWX->callbackData != NULL) + { + delete[] packetUBXRXMRAWX->callbackData; + } + delete[] packetUBXRXMRAWX; + packetUBXRXMRAWX = NULL; // Redundant? + } + + if (packetUBXCFGRATE != NULL) + { + if (packetUBXCFGRATE->callbackData != NULL) + { + delete[] packetUBXCFGRATE->callbackData; + } + delete[] packetUBXCFGRATE; + packetUBXCFGRATE = NULL; // Redundant? + } + + if (packetUBXTIMTM2 != NULL) + { + if (packetUBXTIMTM2->callbackData != NULL) + { + delete[] packetUBXTIMTM2->callbackData; + } + delete[] packetUBXTIMTM2; + packetUBXTIMTM2 = NULL; // Redundant? + } + + if (packetUBXESFALG != NULL) + { + if (packetUBXESFALG->callbackData != NULL) + { + delete[] packetUBXESFALG->callbackData; + } + delete[] packetUBXESFALG; + packetUBXESFALG = NULL; // Redundant? + } + + if (packetUBXESFSTATUS != NULL) + { + if (packetUBXESFSTATUS->callbackData != NULL) + { + delete[] packetUBXESFSTATUS->callbackData; + } + delete[] packetUBXESFSTATUS; + packetUBXESFSTATUS = NULL; // Redundant? + } + + if (packetUBXESFINS != NULL) + { + if (packetUBXESFINS->callbackData != NULL) + { + delete[] packetUBXESFINS->callbackData; + } + delete[] packetUBXESFINS; + packetUBXESFINS = NULL; // Redundant? + } + + if (packetUBXESFMEAS != NULL) + { + if (packetUBXESFMEAS->callbackData != NULL) + { + delete[] packetUBXESFMEAS->callbackData; + } + delete[] packetUBXESFMEAS; + packetUBXESFMEAS = NULL; // Redundant? + } + + if (packetUBXESFRAW != NULL) + { + if (packetUBXESFRAW->callbackData != NULL) + { + delete[] packetUBXESFRAW->callbackData; + } + delete[] packetUBXESFRAW; + packetUBXESFRAW = NULL; // Redundant? + } + + if (packetUBXHNRATT != NULL) + { + if (packetUBXHNRATT->callbackData != NULL) + { + delete[] packetUBXHNRATT->callbackData; + } + delete[] packetUBXHNRATT; + packetUBXHNRATT = NULL; // Redundant? + } + + if (packetUBXHNRINS != NULL) + { + if (packetUBXHNRINS->callbackData != NULL) + { + delete[] packetUBXHNRINS->callbackData; + } + delete[] packetUBXHNRINS; + packetUBXHNRINS = NULL; // Redundant? + } + + if (packetUBXHNRPVT != NULL) + { + if (packetUBXHNRPVT->callbackData != NULL) + { + delete[] packetUBXHNRPVT->callbackData; + } + delete[] packetUBXHNRPVT; + packetUBXHNRPVT = NULL; // Redundant? + } + +} + //Allow the user to change packetCfgPayloadSize. Handy if you want to process big messages like RAWX //This can be called before .begin if required / desired void SFE_UBLOX_GNSS::setPacketCfgPayloadSize(size_t payloadSize) @@ -63,7 +354,7 @@ void SFE_UBLOX_GNSS::setPacketCfgPayloadSize(size_t payloadSize) payloadCfg = NULL; // Redundant? packetCfg.payload = payloadCfg; if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("setPacketCfgPayloadSize: Zero payloadSize! This will end _very_ badly...")); + _debugSerial->println(F("setPacketCfgPayloadSize: Zero payloadSize!")); } else if (payloadCfg == NULL) //Memory has not yet been allocated - so use new @@ -72,7 +363,7 @@ void SFE_UBLOX_GNSS::setPacketCfgPayloadSize(size_t payloadSize) packetCfg.payload = payloadCfg; if (payloadCfg == NULL) if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("setPacketCfgPayloadSize: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("setPacketCfgPayloadSize: PANIC! RAM allocation failed!")); } else //Memory has already been allocated - so resize @@ -85,7 +376,7 @@ void SFE_UBLOX_GNSS::setPacketCfgPayloadSize(size_t payloadSize) packetCfg.payload = payloadCfg; if (payloadCfg == NULL) if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("setPacketCfgPayloadSize: PANIC! RAM resize failed! This will end _very_ badly...")); + _debugSerial->println(F("setPacketCfgPayloadSize: PANIC! RAM resize failed!")); } packetCfgPayloadSize = payloadSize; @@ -3009,6 +3300,12 @@ void SFE_UBLOX_GNSS::setFileBufferSize(uint16_t bufferSize) fileBufferSize = bufferSize; } +//Return the file buffer size +uint16_t SFE_UBLOX_GNSS::getFileBufferSize(void) +{ + return (fileBufferSize); +} + // Extract numBytes of data from the file buffer. Copy it to destination. // It is the user's responsibility to ensure destination is large enough. // Returns the number of bytes extracted - which may be less than numBytes. @@ -3076,7 +3373,16 @@ boolean SFE_UBLOX_GNSS::createFileBuffer(void) { if (_printDebug == true) { - _debugSerial->println(F("createFileBuffer: Warning. FileBufferSize is zero. Data logging is not possible.")); + _debugSerial->println(F("createFileBuffer: Warning. fileBufferSize is zero. Data logging is not possible.")); + } + return(false); + } + + if (ubxFileBuffer != NULL) // Bail if RAM has already been allocated for the file buffer + { // This will happen if you call .begin more than once - without calling .end first + if (_printDebug == true) + { + _debugSerial->println(F("createFileBuffer: Warning. File buffer already exists. Skipping...")); } return(false); } @@ -3092,6 +3398,12 @@ boolean SFE_UBLOX_GNSS::createFileBuffer(void) return(false); } + if (_printDebug == true) + { + _debugSerial->print(F("createFileBuffer: fileBufferSize is: ")); + _debugSerial->println(fileBufferSize); + } + fileBufferHead = 0; // Initialize head and tail fileBufferTail = 0; @@ -3743,7 +4055,7 @@ boolean SFE_UBLOX_GNSS::initModuleSWVersion() if (moduleSWVersion == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initModuleSWVersion: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initModuleSWVersion: PANIC! RAM allocation failed!")); return (false); } moduleSWVersion->versionHigh = 0; @@ -3928,7 +4240,7 @@ boolean SFE_UBLOX_GNSS::initGeofenceParams() if (currentGeofenceParams == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initGeofenceParams: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initGeofenceParams: PANIC! RAM allocation failed!")); return (false); } currentGeofenceParams->numFences = 0; @@ -4800,29 +5112,38 @@ boolean SFE_UBLOX_GNSS::getNAVPOSECEF(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoNAVPOSECEF(boolean enable, uint16_t maxWait) { - return setAutoNAVPOSECEF(enable, true, maxWait); + return setAutoNAVPOSECEFrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic navigation message generation by the GNSS. This changes the way getPOSECEF //works. boolean SFE_UBLOX_GNSS::setAutoNAVPOSECEF(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoNAVPOSECEFrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getPOSECEF +//works. +boolean SFE_UBLOX_GNSS::setAutoNAVPOSECEFrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXNAVPOSECEF == NULL) initPacketUBXNAVPOSECEF(); //Check that RAM has been allocated for the data if (packetUBXNAVPOSECEF == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_NAV; payloadCfg[1] = UBX_NAV_POSECEF; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXNAVPOSECEF->automaticFlags.flags.bits.automatic = enable; + packetUBXNAVPOSECEF->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXNAVPOSECEF->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXNAVPOSECEF->moduleQueried.moduleQueried.bits.all = false; @@ -4877,7 +5198,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXNAVPOSECEF() if (packetUBXNAVPOSECEF == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVPOSECEF: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXNAVPOSECEF: PANIC! RAM allocation failed!")); return (false); } packetUBXNAVPOSECEF->automaticFlags.flags.all = 0; @@ -4944,33 +5265,42 @@ boolean SFE_UBLOX_GNSS::getNAVSTATUS(uint16_t maxWait) } } -//Enable or disable automatic navigation message generation by the GNSS. This changes the way getSTATUS +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getNAVSTATUS //works. boolean SFE_UBLOX_GNSS::setAutoNAVSTATUS(boolean enable, uint16_t maxWait) { - return setAutoNAVSTATUS(enable, true, maxWait); + return setAutoNAVSTATUSrate(enable ? 1 : 0, true, maxWait); } -//Enable or disable automatic navigation message generation by the GNSS. This changes the way getSTATUS +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getNAVSTATUS //works. boolean SFE_UBLOX_GNSS::setAutoNAVSTATUS(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoNAVSTATUSrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getNAVSTATUS +//works. +boolean SFE_UBLOX_GNSS::setAutoNAVSTATUSrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXNAVSTATUS == NULL) initPacketUBXNAVSTATUS(); //Check that RAM has been allocated for the data if (packetUBXNAVSTATUS == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_NAV; payloadCfg[1] = UBX_NAV_STATUS; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXNAVSTATUS->automaticFlags.flags.bits.automatic = enable; + packetUBXNAVSTATUS->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXNAVSTATUS->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXNAVSTATUS->moduleQueried.moduleQueried.bits.all = false; @@ -5025,7 +5355,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXNAVSTATUS() if (packetUBXNAVSTATUS == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVSTATUS: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXNAVSTATUS: PANIC! RAM allocation failed!")); return (false); } packetUBXNAVSTATUS->automaticFlags.flags.all = 0; @@ -5118,12 +5448,19 @@ boolean SFE_UBLOX_GNSS::getDOP(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoDOP(boolean enable, uint16_t maxWait) { - return setAutoDOP(enable, true, maxWait); + return setAutoDOPrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic navigation message generation by the GNSS. This changes the way getDOP //works. boolean SFE_UBLOX_GNSS::setAutoDOP(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoDOPrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getDOP +//works. +boolean SFE_UBLOX_GNSS::setAutoDOPrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXNAVDOP == NULL) initPacketUBXNAVDOP(); //Check that RAM has been allocated for the data if (packetUBXNAVDOP == NULL) //Only attempt this if RAM allocation was successful @@ -5135,12 +5472,12 @@ boolean SFE_UBLOX_GNSS::setAutoDOP(boolean enable, boolean implicitUpdate, uint1 packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_NAV; payloadCfg[1] = UBX_NAV_DOP; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXNAVDOP->automaticFlags.flags.bits.automatic = enable; + packetUBXNAVDOP->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXNAVDOP->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXNAVDOP->moduleQueried.moduleQueried.bits.all = false; @@ -5195,7 +5532,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXNAVDOP() if (packetUBXNAVDOP == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVDOP: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXNAVDOP: PANIC! RAM allocation failed!")); return (false); } packetUBXNAVDOP->automaticFlags.flags.all = 0; @@ -5272,29 +5609,38 @@ boolean SFE_UBLOX_GNSS::getNAVATT(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoNAVATT(boolean enable, uint16_t maxWait) { - return setAutoNAVATT(enable, true, maxWait); + return setAutoNAVATTrate(enable ? 1 : 0, true, maxWait); } -//Enable or disable automatic NAV ATT attitude message generation by the GNSS. This changes the way getVehAtt +//Enable or disable automatic NAV ATT message generation by the GNSS. This changes the way getVehAtt //works. boolean SFE_UBLOX_GNSS::setAutoNAVATT(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoNAVATTrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic NAV ATT attitude message generation by the GNSS. This changes the way getVehAtt +//works. +boolean SFE_UBLOX_GNSS::setAutoNAVATTrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXNAVATT == NULL) initPacketUBXNAVATT(); //Check that RAM has been allocated for the data if (packetUBXNAVATT == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_NAV; payloadCfg[1] = UBX_NAV_ATT; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXNAVATT->automaticFlags.flags.bits.automatic = enable; + packetUBXNAVATT->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXNAVATT->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXNAVATT->moduleQueried.moduleQueried.bits.all = false; // Mark data as stale @@ -5349,7 +5695,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXNAVATT() if (packetUBXNAVATT == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVATT: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXNAVATT: PANIC! RAM allocation failed!")); return (false); } packetUBXNAVATT->automaticFlags.flags.all = 0; @@ -5443,29 +5789,38 @@ boolean SFE_UBLOX_GNSS::getPVT(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoPVT(boolean enable, uint16_t maxWait) { - return setAutoPVT(enable, true, maxWait); + return setAutoPVTrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic navigation message generation by the GNSS. This changes the way getPVT //works. boolean SFE_UBLOX_GNSS::setAutoPVT(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoPVTrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getPVT +//works. +boolean SFE_UBLOX_GNSS::setAutoPVTrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXNAVPVT == NULL) initPacketUBXNAVPVT(); //Check that RAM has been allocated for the PVT data if (packetUBXNAVPVT == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_NAV; payloadCfg[1] = UBX_NAV_PVT; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXNAVPVT->automaticFlags.flags.bits.automatic = enable; + packetUBXNAVPVT->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXNAVPVT->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; @@ -5521,7 +5876,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXNAVPVT() if (packetUBXNAVPVT == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVPVT: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXNAVPVT: PANIC! RAM allocation failed!")); return (false); } packetUBXNAVPVT->automaticFlags.flags.all = 0; @@ -5593,29 +5948,38 @@ boolean SFE_UBLOX_GNSS::getNAVODO(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoNAVODO(boolean enable, uint16_t maxWait) { - return setAutoNAVODO(enable, true, maxWait); + return setAutoNAVODOrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic navigation message generation by the GNSS. This changes the way getODO //works. boolean SFE_UBLOX_GNSS::setAutoNAVODO(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoNAVODOrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getODO +//works. +boolean SFE_UBLOX_GNSS::setAutoNAVODOrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXNAVODO == NULL) initPacketUBXNAVODO(); //Check that RAM has been allocated for the data if (packetUBXNAVODO == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_NAV; payloadCfg[1] = UBX_NAV_ODO; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXNAVODO->automaticFlags.flags.bits.automatic = enable; + packetUBXNAVODO->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXNAVODO->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXNAVODO->moduleQueried.moduleQueried.bits.all = false; @@ -5670,7 +6034,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXNAVODO() if (packetUBXNAVODO == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVODO: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXNAVODO: PANIC! RAM allocation failed!")); return (false); } packetUBXNAVODO->automaticFlags.flags.all = 0; @@ -5740,29 +6104,38 @@ boolean SFE_UBLOX_GNSS::getNAVVELECEF(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoNAVVELECEF(boolean enable, uint16_t maxWait) { - return setAutoNAVVELECEF(enable, true, maxWait); + return setAutoNAVVELECEFrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic navigation message generation by the GNSS. This changes the way getVELECEF //works. boolean SFE_UBLOX_GNSS::setAutoNAVVELECEF(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoNAVVELECEFrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getVELECEF +//works. +boolean SFE_UBLOX_GNSS::setAutoNAVVELECEFrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXNAVVELECEF == NULL) initPacketUBXNAVVELECEF(); //Check that RAM has been allocated for the data if (packetUBXNAVVELECEF == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_NAV; payloadCfg[1] = UBX_NAV_VELECEF; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXNAVVELECEF->automaticFlags.flags.bits.automatic = enable; + packetUBXNAVVELECEF->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXNAVVELECEF->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXNAVVELECEF->moduleQueried.moduleQueried.bits.all = false; @@ -5817,7 +6190,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXNAVVELECEF() if (packetUBXNAVVELECEF == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVVELECEF: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXNAVVELECEF: PANIC! RAM allocation failed!")); return (false); } packetUBXNAVVELECEF->automaticFlags.flags.all = 0; @@ -5887,12 +6260,19 @@ boolean SFE_UBLOX_GNSS::getNAVVELNED(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoNAVVELNED(boolean enable, uint16_t maxWait) { - return setAutoNAVVELNED(enable, true, maxWait); + return setAutoNAVVELNEDrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic navigation message generation by the GNSS. This changes the way getVELNED //works. boolean SFE_UBLOX_GNSS::setAutoNAVVELNED(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoNAVVELNEDrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getVELNED +//works. +boolean SFE_UBLOX_GNSS::setAutoNAVVELNEDrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXNAVVELNED == NULL) initPacketUBXNAVVELNED(); //Check that RAM has been allocated for the data if (packetUBXNAVVELNED == NULL) //Only attempt this if RAM allocation was successful @@ -5904,12 +6284,12 @@ boolean SFE_UBLOX_GNSS::setAutoNAVVELNED(boolean enable, boolean implicitUpdate, packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_NAV; payloadCfg[1] = UBX_NAV_VELNED; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXNAVVELNED->automaticFlags.flags.bits.automatic = enable; + packetUBXNAVVELNED->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXNAVVELNED->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXNAVVELNED->moduleQueried.moduleQueried.bits.all = false; @@ -5964,7 +6344,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXNAVVELNED() if (packetUBXNAVVELNED == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVVELNED: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXNAVVELNED: PANIC! RAM allocation failed!")); return (false); } packetUBXNAVVELNED->automaticFlags.flags.all = 0; @@ -6034,29 +6414,38 @@ boolean SFE_UBLOX_GNSS::getNAVHPPOSECEF(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoNAVHPPOSECEF(boolean enable, uint16_t maxWait) { - return setAutoNAVHPPOSECEF(enable, true, maxWait); + return setAutoNAVHPPOSECEFrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic navigation message generation by the GNSS. This changes the way getHPPOSECEF //works. boolean SFE_UBLOX_GNSS::setAutoNAVHPPOSECEF(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoNAVHPPOSECEFrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getHPPOSECEF +//works. +boolean SFE_UBLOX_GNSS::setAutoNAVHPPOSECEFrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXNAVHPPOSECEF == NULL) initPacketUBXNAVHPPOSECEF(); //Check that RAM has been allocated for the data if (packetUBXNAVHPPOSECEF == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_NAV; payloadCfg[1] = UBX_NAV_HPPOSECEF; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.automatic = enable; + packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXNAVHPPOSECEF->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false; @@ -6111,7 +6500,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXNAVHPPOSECEF() if (packetUBXNAVHPPOSECEF == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVHPPOSECEF: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXNAVHPPOSECEF: PANIC! RAM allocation failed!")); return (false); } packetUBXNAVHPPOSECEF->automaticFlags.flags.all = 0; @@ -6203,29 +6592,38 @@ boolean SFE_UBLOX_GNSS::getHPPOSLLH(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoHPPOSLLH(boolean enable, uint16_t maxWait) { - return setAutoHPPOSLLH(enable, true, maxWait); + return setAutoHPPOSLLHrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic navigation message generation by the GNSS. This changes the way getHPPOSLLH //works. boolean SFE_UBLOX_GNSS::setAutoHPPOSLLH(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoHPPOSLLHrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getHPPOSLLH +//works. +boolean SFE_UBLOX_GNSS::setAutoHPPOSLLHrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXNAVHPPOSLLH == NULL) initPacketUBXNAVHPPOSLLH(); //Check that RAM has been allocated for the data if (packetUBXNAVHPPOSLLH == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_NAV; payloadCfg[1] = UBX_NAV_HPPOSLLH; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.automatic = enable; + packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXNAVHPPOSLLH->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXNAVHPPOSLLH->moduleQueried.moduleQueried.bits.all = false; @@ -6280,7 +6678,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXNAVHPPOSLLH() if (packetUBXNAVHPPOSLLH == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVHPPOSLLH: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXNAVHPPOSLLH: PANIC! RAM allocation failed!")); return (false); } packetUBXNAVHPPOSLLH->automaticFlags.flags.all = 0; @@ -6350,29 +6748,38 @@ boolean SFE_UBLOX_GNSS::getNAVCLOCK(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoNAVCLOCK(boolean enable, uint16_t maxWait) { - return setAutoNAVCLOCK(enable, true, maxWait); + return setAutoNAVCLOCKrate(enable ? 1 : 0, true, maxWait); } -//Enable or disable automatic CLOCK attitude message generation by the GNSS. This changes the way getNAVCLOCK +//Enable or disable automatic CLOCK message generation by the GNSS. This changes the way getNAVCLOCK //works. boolean SFE_UBLOX_GNSS::setAutoNAVCLOCK(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoNAVCLOCKrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic CLOCK attitude message generation by the GNSS. This changes the way getNAVCLOCK +//works. +boolean SFE_UBLOX_GNSS::setAutoNAVCLOCKrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXNAVCLOCK == NULL) initPacketUBXNAVCLOCK(); //Check that RAM has been allocated for the data if (packetUBXNAVCLOCK == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_NAV; payloadCfg[1] = UBX_NAV_CLOCK; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXNAVCLOCK->automaticFlags.flags.bits.automatic = enable; + packetUBXNAVCLOCK->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXNAVCLOCK->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXNAVCLOCK->moduleQueried.moduleQueried.bits.all = false; // Mark data as stale @@ -6427,7 +6834,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXNAVCLOCK() if (packetUBXNAVCLOCK == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVCLOCK: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXNAVCLOCK: PANIC! RAM allocation failed!")); return (false); } packetUBXNAVCLOCK->automaticFlags.flags.all = 0; @@ -6488,7 +6895,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXNAVSVIN() if (packetUBXNAVSVIN == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVSVIN: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXNAVSVIN: PANIC! RAM allocation failed!")); return (false); } packetUBXNAVSVIN->automaticFlags.flags.all = 0; @@ -6549,29 +6956,38 @@ boolean SFE_UBLOX_GNSS::getRELPOSNED(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoRELPOSNED(boolean enable, uint16_t maxWait) { - return setAutoRELPOSNED(enable, true, maxWait); + return setAutoRELPOSNEDrate(enable ? 1 : 0, true, maxWait); } -//Enable or disable automatic HNR attitude message generation by the GNSS. This changes the way getRELPOSNED +//Enable or disable automatic RELPOSNED message generation by the GNSS. This changes the way getRELPOSNED //works. boolean SFE_UBLOX_GNSS::setAutoRELPOSNED(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoRELPOSNEDrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic HNR attitude message generation by the GNSS. This changes the way getRELPOSNED +//works. +boolean SFE_UBLOX_GNSS::setAutoRELPOSNEDrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXNAVRELPOSNED == NULL) initPacketUBXNAVRELPOSNED(); //Check that RAM has been allocated for the data if (packetUBXNAVRELPOSNED == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_NAV; payloadCfg[1] = UBX_NAV_RELPOSNED; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXNAVRELPOSNED->automaticFlags.flags.bits.automatic = enable; + packetUBXNAVRELPOSNED->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXNAVRELPOSNED->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXNAVRELPOSNED->moduleQueried.moduleQueried.bits.all = false; // Mark data as stale @@ -6626,7 +7042,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXNAVRELPOSNED() if (packetUBXNAVRELPOSNED == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXNAVRELPOSNED: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXNAVRELPOSNED: PANIC! RAM allocation failed!")); return (false); } packetUBXNAVRELPOSNED->automaticFlags.flags.all = 0; @@ -6696,29 +7112,38 @@ boolean SFE_UBLOX_GNSS::getRXMSFRBX(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoRXMSFRBX(boolean enable, uint16_t maxWait) { - return setAutoRXMSFRBX(enable, true, maxWait); + return setAutoRXMSFRBXrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic navigation message generation by the GNSS. This changes the way getRXMSFRBX //works. boolean SFE_UBLOX_GNSS::setAutoRXMSFRBX(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoRXMSFRBXrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getRXMSFRBX +//works. +boolean SFE_UBLOX_GNSS::setAutoRXMSFRBXrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXRXMSFRBX == NULL) initPacketUBXRXMSFRBX(); //Check that RAM has been allocated for the data if (packetUBXRXMSFRBX == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_RXM; payloadCfg[1] = UBX_RXM_SFRBX; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXRXMSFRBX->automaticFlags.flags.bits.automatic = enable; + packetUBXRXMSFRBX->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXRXMSFRBX->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXRXMSFRBX->moduleQueried = false; @@ -6773,7 +7198,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXRXMSFRBX() if (packetUBXRXMSFRBX == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXRXMSFRBX: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXRXMSFRBX: PANIC! RAM allocation failed!")); return (false); } packetUBXRXMSFRBX->automaticFlags.flags.all = 0; @@ -6843,29 +7268,38 @@ boolean SFE_UBLOX_GNSS::getRXMRAWX(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoRXMRAWX(boolean enable, uint16_t maxWait) { - return setAutoRXMRAWX(enable, true, maxWait); + return setAutoRXMRAWXrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic navigation message generation by the GNSS. This changes the way getRXMRAWX //works. boolean SFE_UBLOX_GNSS::setAutoRXMRAWX(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoRXMRAWXrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getRXMRAWX +//works. +boolean SFE_UBLOX_GNSS::setAutoRXMRAWXrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXRXMRAWX == NULL) initPacketUBXRXMRAWX(); //Check that RAM has been allocated for the data if (packetUBXRXMRAWX == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_RXM; payloadCfg[1] = UBX_RXM_RAWX; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXRXMRAWX->automaticFlags.flags.bits.automatic = enable; + packetUBXRXMRAWX->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXRXMRAWX->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXRXMRAWX->moduleQueried = false; @@ -6920,7 +7354,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXRXMRAWX() if (packetUBXRXMRAWX == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXRXMRAWX: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXRXMRAWX: PANIC! RAM allocation failed!")); return (false); } packetUBXRXMRAWX->automaticFlags.flags.all = 0; @@ -6994,7 +7428,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXCFGRATE() if (packetUBXCFGRATE == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXCFGRATE: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXCFGRATE: PANIC! RAM allocation failed!")); return (false); } packetUBXCFGRATE->automaticFlags.flags.all = 0; @@ -7050,29 +7484,38 @@ boolean SFE_UBLOX_GNSS::getTIMTM2(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoTIMTM2(boolean enable, uint16_t maxWait) { - return setAutoTIMTM2(enable, true, maxWait); + return setAutoTIMTM2rate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic navigation message generation by the GNSS. This changes the way getTIMTM2 //works. boolean SFE_UBLOX_GNSS::setAutoTIMTM2(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoTIMTM2rate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic navigation message generation by the GNSS. This changes the way getTIMTM2 +//works. +boolean SFE_UBLOX_GNSS::setAutoTIMTM2rate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXTIMTM2 == NULL) initPacketUBXTIMTM2(); //Check that RAM has been allocated for the data if (packetUBXTIMTM2 == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_TIM; payloadCfg[1] = UBX_TIM_TM2; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXTIMTM2->automaticFlags.flags.bits.automatic = enable; + packetUBXTIMTM2->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXTIMTM2->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXTIMTM2->moduleQueried.moduleQueried.bits.all = false; @@ -7127,7 +7570,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXTIMTM2() if (packetUBXTIMTM2 == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXTIMTM2: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXTIMTM2: PANIC! RAM allocation failed!")); return (false); } packetUBXTIMTM2->automaticFlags.flags.all = 0; @@ -7226,29 +7669,38 @@ boolean SFE_UBLOX_GNSS::getESFALG(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoESFALG(boolean enable, uint16_t maxWait) { - return setAutoESFALG(enable, true, maxWait); + return setAutoESFALGrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic ESF ALG message generation by the GNSS. This changes the way getEsfAlignment //works. boolean SFE_UBLOX_GNSS::setAutoESFALG(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoESFALGrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic ESF ALG message generation by the GNSS. This changes the way getEsfAlignment +//works. +boolean SFE_UBLOX_GNSS::setAutoESFALGrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXESFALG == NULL) initPacketUBXESFALG(); //Check that RAM has been allocated for the data if (packetUBXESFALG == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_ESF; payloadCfg[1] = UBX_ESF_ALG; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXESFALG->automaticFlags.flags.bits.automatic = enable; + packetUBXESFALG->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXESFALG->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXESFALG->moduleQueried.moduleQueried.bits.all = false; // Mark data as stale @@ -7303,7 +7755,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXESFALG() if (packetUBXESFALG == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXESFALG: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXESFALG: PANIC! RAM allocation failed!")); return (false); } packetUBXESFALG->automaticFlags.flags.all = 0; @@ -7402,29 +7854,38 @@ boolean SFE_UBLOX_GNSS::getESFSTATUS(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoESFSTATUS(boolean enable, uint16_t maxWait) { - return setAutoESFSTATUS(enable, true, maxWait); + return setAutoESFSTATUSrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic ESF STATUS message generation by the GNSS. This changes the way getESFInfo //works. boolean SFE_UBLOX_GNSS::setAutoESFSTATUS(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoESFSTATUSrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic ESF STATUS message generation by the GNSS. This changes the way getESFInfo +//works. +boolean SFE_UBLOX_GNSS::setAutoESFSTATUSrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXESFSTATUS == NULL) initPacketUBXESFSTATUS(); //Check that RAM has been allocated for the data if (packetUBXESFSTATUS == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_ESF; payloadCfg[1] = UBX_ESF_STATUS; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXESFSTATUS->automaticFlags.flags.bits.automatic = enable; + packetUBXESFSTATUS->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXESFSTATUS->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXESFSTATUS->moduleQueried.moduleQueried.bits.all = false; // Mark data as stale @@ -7480,7 +7941,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXESFSTATUS() if (packetUBXESFSTATUS == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXESFSTATUS: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXESFSTATUS: PANIC! RAM allocation failed!")); return (false); } packetUBXESFSTATUS->automaticFlags.flags.all = 0; @@ -7579,29 +8040,38 @@ boolean SFE_UBLOX_GNSS::getESFINS(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoESFINS(boolean enable, uint16_t maxWait) { - return setAutoESFINS(enable, true, maxWait); + return setAutoESFINSrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic ESF INS message generation by the GNSS. This changes the way getESFIns //works. boolean SFE_UBLOX_GNSS::setAutoESFINS(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoESFINSrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic ESF INS message generation by the GNSS. This changes the way getESFIns +//works. +boolean SFE_UBLOX_GNSS::setAutoESFINSrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXESFINS == NULL) initPacketUBXESFINS(); //Check that RAM has been allocated for the data if (packetUBXESFINS == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_ESF; payloadCfg[1] = UBX_ESF_INS; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXESFINS->automaticFlags.flags.bits.automatic = enable; + packetUBXESFINS->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXESFINS->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXESFINS->moduleQueried.moduleQueried.bits.all = false; // Mark data as stale @@ -7656,7 +8126,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXESFINS() if (packetUBXESFINS == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXESFINS: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXESFINS: PANIC! RAM allocation failed!")); return (false); } packetUBXESFINS->automaticFlags.flags.all = 0; @@ -7755,29 +8225,38 @@ boolean SFE_UBLOX_GNSS::getESFMEAS(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoESFMEAS(boolean enable, uint16_t maxWait) { - return setAutoESFMEAS(enable, true, maxWait); + return setAutoESFMEASrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic ESF MEAS message generation by the GNSS. This changes the way getESFDataInfo //works. boolean SFE_UBLOX_GNSS::setAutoESFMEAS(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoESFMEASrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic ESF MEAS message generation by the GNSS. This changes the way getESFDataInfo +//works. +boolean SFE_UBLOX_GNSS::setAutoESFMEASrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXESFMEAS == NULL) initPacketUBXESFMEAS(); //Check that RAM has been allocated for the data if (packetUBXESFMEAS == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_ESF; payloadCfg[1] = UBX_ESF_MEAS; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXESFMEAS->automaticFlags.flags.bits.automatic = enable; + packetUBXESFMEAS->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXESFMEAS->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXESFMEAS->moduleQueried.moduleQueried.bits.all = false; // Mark data as stale @@ -7832,7 +8311,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXESFMEAS() if (packetUBXESFMEAS == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXESFMEAS: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXESFMEAS: PANIC! RAM allocation failed!")); return (false); } packetUBXESFMEAS->automaticFlags.flags.all = 0; @@ -7931,29 +8410,38 @@ boolean SFE_UBLOX_GNSS::getESFRAW(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoESFRAW(boolean enable, uint16_t maxWait) { - return setAutoESFRAW(enable, true, maxWait); + return setAutoESFRAWrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic ESF RAW message generation by the GNSS. This changes the way getESFRawDataInfo //works. boolean SFE_UBLOX_GNSS::setAutoESFRAW(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoESFRAWrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic ESF RAW message generation by the GNSS. This changes the way getESFRawDataInfo +//works. +boolean SFE_UBLOX_GNSS::setAutoESFRAWrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXESFRAW == NULL) initPacketUBXESFRAW(); //Check that RAM has been allocated for the data if (packetUBXESFRAW == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_ESF; payloadCfg[1] = UBX_ESF_RAW; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXESFRAW->automaticFlags.flags.bits.automatic = enable; + packetUBXESFRAW->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXESFRAW->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXESFRAW->moduleQueried.moduleQueried.bits.all = false; // Mark data as stale @@ -8008,7 +8496,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXESFRAW() if (packetUBXESFRAW == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXESFRAW: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXESFRAW: PANIC! RAM allocation failed!")); return (false); } packetUBXESFRAW->automaticFlags.flags.all = 0; @@ -8112,29 +8600,38 @@ boolean SFE_UBLOX_GNSS::getHNRATT(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoHNRATT(boolean enable, uint16_t maxWait) { - return setAutoHNRATT(enable, true, maxWait); + return setAutoHNRATTrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic HNR attitude message generation by the GNSS. This changes the way getHNRAtt //works. boolean SFE_UBLOX_GNSS::setAutoHNRATT(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoHNRATTrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic HNR attitude message generation by the GNSS. This changes the way getHNRAtt +//works. +boolean SFE_UBLOX_GNSS::setAutoHNRATTrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXHNRATT == NULL) initPacketUBXHNRATT(); //Check that RAM has been allocated for the data if (packetUBXHNRATT == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_HNR; payloadCfg[1] = UBX_HNR_ATT; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXHNRATT->automaticFlags.flags.bits.automatic = enable; + packetUBXHNRATT->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXHNRATT->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXHNRATT->moduleQueried.moduleQueried.bits.all = false; // Mark data as stale @@ -8189,7 +8686,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXHNRATT() if (packetUBXHNRATT == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXHNRATT: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXHNRATT: PANIC! RAM allocation failed!")); return (false); } packetUBXHNRATT->automaticFlags.flags.all = 0; @@ -8294,29 +8791,38 @@ boolean SFE_UBLOX_GNSS::getHNRINS(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoHNRINS(boolean enable, uint16_t maxWait) { - return setAutoHNRINS(enable, true, maxWait); + return setAutoHNRINSrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic HNR vehicle dynamics message generation by the GNSS. This changes the way getHNRDyn //works. boolean SFE_UBLOX_GNSS::setAutoHNRINS(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoHNRINSrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic HNR vehicle dynamics message generation by the GNSS. This changes the way getHNRDyn +//works. +boolean SFE_UBLOX_GNSS::setAutoHNRINSrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXHNRINS == NULL) initPacketUBXHNRINS(); //Check that RAM has been allocated for the data if (packetUBXHNRINS == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_HNR; payloadCfg[1] = UBX_HNR_INS; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXHNRINS->automaticFlags.flags.bits.automatic = enable; + packetUBXHNRINS->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXHNRINS->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXHNRINS->moduleQueried.moduleQueried.bits.all = false; // Mark data as stale @@ -8371,7 +8877,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXHNRINS() if (packetUBXHNRINS == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXHNRINS: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXHNRINS: PANIC! RAM allocation failed!")); return (false); } packetUBXHNRINS->automaticFlags.flags.all = 0; @@ -8470,29 +8976,38 @@ boolean SFE_UBLOX_GNSS::getHNRPVT(uint16_t maxWait) //works. boolean SFE_UBLOX_GNSS::setAutoHNRPVT(boolean enable, uint16_t maxWait) { - return setAutoHNRPVT(enable, true, maxWait); + return setAutoHNRPVTrate(enable ? 1 : 0, true, maxWait); } //Enable or disable automatic HNR PVT message generation by the GNSS. This changes the way getHNRPVT //works. boolean SFE_UBLOX_GNSS::setAutoHNRPVT(boolean enable, boolean implicitUpdate, uint16_t maxWait) +{ + return setAutoHNRPVTrate(enable ? 1 : 0, implicitUpdate, maxWait); +} + +//Enable or disable automatic HNR PVT message generation by the GNSS. This changes the way getHNRPVT +//works. +boolean SFE_UBLOX_GNSS::setAutoHNRPVTrate(uint8_t rate, boolean implicitUpdate, uint16_t maxWait) { if (packetUBXHNRPVT == NULL) initPacketUBXHNRPVT(); //Check that RAM has been allocated for the data if (packetUBXHNRPVT == NULL) //Only attempt this if RAM allocation was successful return false; + if (rate > 127) rate = 127; + packetCfg.cls = UBX_CLASS_CFG; packetCfg.id = UBX_CFG_MSG; packetCfg.len = 3; packetCfg.startingSpot = 0; payloadCfg[0] = UBX_CLASS_HNR; payloadCfg[1] = UBX_HNR_PVT; - payloadCfg[2] = enable ? 1 : 0; // rate relative to navigation freq. + payloadCfg[2] = rate; // rate relative to navigation freq. boolean ok = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK if (ok) { - packetUBXHNRPVT->automaticFlags.flags.bits.automatic = enable; + packetUBXHNRPVT->automaticFlags.flags.bits.automatic = (rate > 0); packetUBXHNRPVT->automaticFlags.flags.bits.implicitUpdate = implicitUpdate; } packetUBXHNRPVT->moduleQueried.moduleQueried.bits.all = false; // Mark data as stale @@ -8547,7 +9062,7 @@ boolean SFE_UBLOX_GNSS::initPacketUBXHNRPVT() if (packetUBXHNRPVT == NULL) { if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging - _debugSerial->println(F("initPacketUBXHNRPVT: PANIC! RAM allocation failed! This will end _very_ badly...")); + _debugSerial->println(F("initPacketUBXHNRPVT: PANIC! RAM allocation failed!")); return (false); } packetUBXHNRPVT->automaticFlags.flags.all = 0; @@ -8954,16 +9469,41 @@ int32_t SFE_UBLOX_GNSS::getNanosecond(uint16_t maxWait) return (packetUBXNAVPVT->data.nano); } -//Get the current Unix epoch - includes microseconds +//Get the current Unix epoch time rounded up to the nearest second +uint32_t SFE_UBLOX_GNSS::getUnixEpoch(uint16_t maxWait) +{ + if (packetUBXNAVPVT == NULL) initPacketUBXNAVPVT(); //Check that RAM has been allocated for the PVT data + if (packetUBXNAVPVT == NULL) //Bail if the RAM allocation failed + return 0; + + if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.sec == false) + getPVT(maxWait); + packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.year = false; + packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.month = false; + packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.day = false; + packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.hour = false; + packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.min = false; + packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.sec = false; + packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; + // assemble time elements into time_t - credits to Thomas Roell @ https://github.com/GrumpyOldPizza + uint32_t t = ((((((((uint32_t)packetUBXNAVPVT->data.year - 1970) * 365) + ((((uint32_t)packetUBXNAVPVT->data.year - 1970) + 3) / 4)) + + DAYS_SINCE_MONTH[((uint32_t)packetUBXNAVPVT->data.year - 1970) & 3][(uint32_t)packetUBXNAVPVT->data.month] + + ((uint32_t)packetUBXNAVPVT->data.day - 1)) * 24 + + (uint32_t)packetUBXNAVPVT->data.hour) * 60 + + (uint32_t)packetUBXNAVPVT->data.min) * 60 + + (uint32_t)packetUBXNAVPVT->data.sec); + return t; +} + +//Get the current Unix epoch including microseconds uint32_t SFE_UBLOX_GNSS::getUnixEpoch(uint32_t& microsecond, uint16_t maxWait) { if (packetUBXNAVPVT == NULL) initPacketUBXNAVPVT(); //Check that RAM has been allocated for the PVT data if (packetUBXNAVPVT == NULL) //Bail if the RAM allocation failed return 0; - if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.confirmedTime == false) + if (packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.nano == false) getPVT(maxWait); - packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.confirmedTime = false; packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.year = false; packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.month = false; packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.day = false; @@ -8972,23 +9512,19 @@ uint32_t SFE_UBLOX_GNSS::getUnixEpoch(uint32_t& microsecond, uint16_t maxWait) packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.sec = false; packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.nano = false; packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.all = false; - uint32_t t = 0; - if((bool)packetUBXNAVPVT->data.flags2.bits.confirmedTime) - { - // assemble time elements into time_t - credits to Thomas Roell @ https://github.com/GrumpyOldPizza - t = (uint32_t)(((((((packetUBXNAVPVT->data.year - 1970) * 365) + (((packetUBXNAVPVT->data.year - 1970) + 3) / 4)) + - DAYS_SINCE_MONTH[(packetUBXNAVPVT->data.year - 1970) & 3][packetUBXNAVPVT->data.month] + - (packetUBXNAVPVT->data.day - 1)) * 24 + - packetUBXNAVPVT->data.hour) * 60 + - packetUBXNAVPVT->data.min) * 60 + - packetUBXNAVPVT->data.sec); - int32_t us = packetUBXNAVPVT->data.nano / 1000; - microsecond = (uint32_t)us; - // adjust t if nano is negative - if(us < 0) { - microsecond = (uint32_t)(us + 1000000); - t--; - } + // assemble time elements into time_t - credits to Thomas Roell @ https://github.com/GrumpyOldPizza + uint32_t t = ((((((((uint32_t)packetUBXNAVPVT->data.year - 1970) * 365) + ((((uint32_t)packetUBXNAVPVT->data.year - 1970) + 3) / 4)) + + DAYS_SINCE_MONTH[((uint32_t)packetUBXNAVPVT->data.year - 1970) & 3][(uint32_t)packetUBXNAVPVT->data.month] + + ((uint32_t)packetUBXNAVPVT->data.day - 1)) * 24 + + (uint32_t)packetUBXNAVPVT->data.hour) * 60 + + (uint32_t)packetUBXNAVPVT->data.min) * 60 + + (uint32_t)packetUBXNAVPVT->data.sec); + int32_t us = packetUBXNAVPVT->data.nano / 1000; + microsecond = (uint32_t)us; + // adjust t if nano is negative + if(us < 0) { + microsecond = (uint32_t)(us + 1000000); + t--; } return t; } diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.h b/src/SparkFun_u-blox_GNSS_Arduino_Library.h index a534530..8e8ab2d 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.h +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.h @@ -482,6 +482,8 @@ class SFE_UBLOX_GNSS //serialPort needs to be perviously initialized to correct baud rate boolean begin(Stream &serialPort); //Returns true if module is detected + void end(void); //Stop all automatic message processing. Free all used RAM + void setI2CpollingWait(uint8_t newPollingWait_ms); // Allow the user to change the I2C polling wait if required //Control the size of the internal I2C transaction amount @@ -564,6 +566,7 @@ class SFE_UBLOX_GNSS // Support for data logging void setFileBufferSize(uint16_t bufferSize); // Set the size of the file buffer. This must be called _before_ .begin. + uint16_t getFileBufferSize(void); // Return the size of the file buffer uint16_t extractFileBufferData(uint8_t *destination, uint16_t numBytes); // Extract numBytes of data from the file buffer. Copy it to destination. It is the user's responsibility to ensure destination is large enough. uint16_t fileBufferAvailable(void); // Returns the number of bytes available in file buffer which are waiting to be read uint16_t getMaxFileBufferAvail(void); // Returns the maximum number of bytes which the file buffer has contained. Handy for checking the buffer is large enough to handle all the incoming data. @@ -697,6 +700,7 @@ class SFE_UBLOX_GNSS boolean getNAVPOSECEF(uint16_t maxWait = defaultMaxWait); // NAV POSECEF boolean setAutoNAVPOSECEF(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic POSECEF reports at the navigation frequency boolean setAutoNAVPOSECEF(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic POSECEF reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoNAVPOSECEFrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic POSECEF reports boolean setAutoNAVPOSECEFcallback(void (*callbackPointer)(UBX_NAV_POSECEF_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic POSECEF reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoNAVPOSECEF(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and POSECEF is send cyclically already void flushNAVPOSECEF(); //Mark all the data as read/stale @@ -705,6 +709,7 @@ class SFE_UBLOX_GNSS boolean getNAVSTATUS(uint16_t maxWait = defaultMaxWait); // NAV STATUS boolean setAutoNAVSTATUS(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic STATUS reports at the navigation frequency boolean setAutoNAVSTATUS(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic STATUS reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoNAVSTATUSrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic STATUS reports boolean setAutoNAVSTATUScallback(void (*callbackPointer)(UBX_NAV_STATUS_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic STATUS reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoNAVSTATUS(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and STATUS is send cyclically already void flushNAVSTATUS(); //Mark all the data as read/stale @@ -713,6 +718,7 @@ class SFE_UBLOX_GNSS boolean getDOP(uint16_t maxWait = defaultMaxWait); //Query module for latest dilution of precision values and load global vars:. If autoDOP is disabled, performs an explicit poll and waits, if enabled does not block. Returns true if new DOP is available. boolean setAutoDOP(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic DOP reports at the navigation frequency boolean setAutoDOP(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic DOP reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoDOPrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic DOP reports boolean setAutoDOPcallback(void (*callbackPointer)(UBX_NAV_DOP_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic DOP reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoDOP(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and DOP is send cyclically already void flushDOP(); //Mark all the DOP data as read/stale @@ -722,6 +728,7 @@ class SFE_UBLOX_GNSS boolean getNAVATT(uint16_t maxWait = defaultMaxWait); // NAV ATT boolean setAutoNAVATT(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic vehicle attitude reports at the navigation frequency boolean setAutoNAVATT(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic vehicle attitude reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoNAVATTrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic ATT reports boolean setAutoNAVATTcallback(void (*callbackPointer)(UBX_NAV_ATT_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic ATT reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoNAVATT(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and vehicle attitude is send cyclically already void flushNAVATT(); //Mark all the data as read/stale @@ -730,6 +737,7 @@ class SFE_UBLOX_GNSS boolean getPVT(uint16_t maxWait = defaultMaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Returns true if new PVT is available. boolean setAutoPVT(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic PVT reports at the navigation frequency boolean setAutoPVT(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic PVT reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoPVTrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic PVT reports boolean setAutoPVTcallback(void (*callbackPointer)(UBX_NAV_PVT_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic PVT reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoPVT(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and PVT is send cyclically already void flushPVT(); //Mark all the PVT data as read/stale @@ -738,6 +746,7 @@ class SFE_UBLOX_GNSS boolean getNAVODO(uint16_t maxWait = defaultMaxWait); // NAV ODO boolean setAutoNAVODO(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic ODO reports at the navigation frequency boolean setAutoNAVODO(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic ODO reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoNAVODOrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic ODO reports boolean setAutoNAVODOcallback(void (*callbackPointer)(UBX_NAV_ODO_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic ODO reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoNAVODO(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and ODO is send cyclically already void flushNAVODO(); //Mark all the data as read/stale @@ -746,6 +755,7 @@ class SFE_UBLOX_GNSS boolean getNAVVELECEF(uint16_t maxWait = defaultMaxWait); // NAV VELECEF boolean setAutoNAVVELECEF(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic VELECEF reports at the navigation frequency boolean setAutoNAVVELECEF(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic VELECEF reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoNAVVELECEFrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic VELECEF reports boolean setAutoNAVVELECEFcallback(void (*callbackPointer)(UBX_NAV_VELECEF_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic VELECEF reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoNAVVELECEF(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and VELECEF is send cyclically already void flushNAVVELECEF(); //Mark all the data as read/stale @@ -754,6 +764,7 @@ class SFE_UBLOX_GNSS boolean getNAVVELNED(uint16_t maxWait = defaultMaxWait); // NAV VELNED boolean setAutoNAVVELNED(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic VELNED reports at the navigation frequency boolean setAutoNAVVELNED(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic VELNED reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoNAVVELNEDrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic VELNED reports boolean setAutoNAVVELNEDcallback(void (*callbackPointer)(UBX_NAV_VELNED_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic VELNED reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoNAVVELNED(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and VELNED is send cyclically already void flushNAVVELNED(); //Mark all the data as read/stale @@ -762,6 +773,7 @@ class SFE_UBLOX_GNSS boolean getNAVHPPOSECEF(uint16_t maxWait = defaultMaxWait); // NAV HPPOSECEF boolean setAutoNAVHPPOSECEF(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic HPPOSECEF reports at the navigation frequency boolean setAutoNAVHPPOSECEF(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic HPPOSECEF reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoNAVHPPOSECEFrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic HPPOSECEF reports boolean setAutoNAVHPPOSECEFcallback(void (*callbackPointer)(UBX_NAV_HPPOSECEF_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic HPPOSECEF reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoNAVHPPOSECEF(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and HPPOSECEF is send cyclically already void flushNAVHPPOSECEF(); //Mark all the data as read/stale @@ -770,6 +782,7 @@ class SFE_UBLOX_GNSS boolean getHPPOSLLH(uint16_t maxWait = defaultMaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Returns true if new HPPOSLLH is available. boolean setAutoHPPOSLLH(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic HPPOSLLH reports at the navigation frequency boolean setAutoHPPOSLLH(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic HPPOSLLH reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoHPPOSLLHrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic HPPOSLLH reports boolean setAutoHPPOSLLHcallback(void (*callbackPointer)(UBX_NAV_HPPOSLLH_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic HPPOSLLH reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoHPPOSLLH(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and HPPOSLLH is send cyclically already void flushHPPOSLLH(); //Mark all the HPPPOSLLH data as read/stale. This is handy to get data alignment after CRC failure @@ -778,6 +791,7 @@ class SFE_UBLOX_GNSS boolean getNAVCLOCK(uint16_t maxWait = defaultMaxWait); // NAV CLOCK boolean setAutoNAVCLOCK(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic clock reports at the navigation frequency boolean setAutoNAVCLOCK(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic clock reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoNAVCLOCKrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic CLOCK reports boolean setAutoNAVCLOCKcallback(void (*callbackPointer)(UBX_NAV_CLOCK_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic CLOCK reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoNAVCLOCK(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and clock is send cyclically already void flushNAVCLOCK(); //Mark all the data as read/stale @@ -789,6 +803,7 @@ class SFE_UBLOX_GNSS boolean getRELPOSNED(uint16_t maxWait = defaultMaxWait); //Get Relative Positioning Information of the NED frame boolean setAutoRELPOSNED(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic RELPOSNED reports boolean setAutoRELPOSNED(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic RELPOSNED, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoRELPOSNEDrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic RELPOSNEDreports boolean setAutoRELPOSNEDcallback(void (*callbackPointer)(UBX_NAV_RELPOSNED_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic RELPOSNED reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoRELPOSNED(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and RELPOSNED is send cyclically already void flushNAVRELPOSNED(); //Mark all the data as read/stale @@ -799,6 +814,7 @@ class SFE_UBLOX_GNSS boolean getRXMSFRBX(uint16_t maxWait = defaultMaxWait); // RXM SFRBX boolean setAutoRXMSFRBX(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic RXM SFRBX reports at the navigation frequency boolean setAutoRXMSFRBX(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic RXM SFRBX reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoRXMSFRBXrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic SFRBX reports boolean setAutoRXMSFRBXcallback(void (*callbackPointer)(UBX_RXM_SFRBX_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic SFRBX reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoRXMSFRBX(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and RXM SFRBX is send cyclically already void flushRXMSFRBX(); //Mark all the data as read/stale @@ -807,6 +823,7 @@ class SFE_UBLOX_GNSS boolean getRXMRAWX(uint16_t maxWait = defaultMaxWait); // RXM RAWX boolean setAutoRXMRAWX(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic RXM RAWX reports at the navigation frequency boolean setAutoRXMRAWX(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic RXM RAWX reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoRXMRAWXrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic RAWX reports boolean setAutoRXMRAWXcallback(void (*callbackPointer)(UBX_RXM_RAWX_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic RAWX reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoRXMRAWX(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and RXM RAWX is send cyclically already void flushRXMRAWX(); //Mark all the data as read/stale @@ -822,6 +839,7 @@ class SFE_UBLOX_GNSS boolean getTIMTM2(uint16_t maxWait = defaultMaxWait); // TIM TM2 boolean setAutoTIMTM2(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic TIM TM2 reports at the navigation frequency boolean setAutoTIMTM2(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic TIM TM2 reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoTIMTM2rate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic TIM TM2 reports boolean setAutoTIMTM2callback(void (*callbackPointer)(UBX_TIM_TM2_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic TM2 reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoTIMTM2(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and TIM TM2 is send cyclically already void flushTIMTM2(); //Mark all the data as read/stale @@ -833,6 +851,7 @@ class SFE_UBLOX_GNSS boolean getESFALG(uint16_t maxWait = defaultMaxWait); // ESF ALG boolean setAutoESFALG(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic ESF ALG reports boolean setAutoESFALG(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic ESF ALG reports, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoESFALGrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic ALG reports boolean setAutoESFALGcallback(void (*callbackPointer)(UBX_ESF_ALG_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic ALG reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoESFALG(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and ESF ALG is send cyclically already void flushESFALG(); //Mark all the data as read/stale @@ -842,6 +861,7 @@ class SFE_UBLOX_GNSS boolean getESFSTATUS(uint16_t maxWait = defaultMaxWait); // ESF STATUS boolean setAutoESFSTATUS(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic ESF STATUS reports boolean setAutoESFSTATUS(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic ESF STATUS reports, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoESFSTATUSrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic STATUS reports boolean setAutoESFSTATUScallback(void (*callbackPointer)(UBX_ESF_STATUS_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic STATUS reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoESFSTATUS(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and ESF STATUS is send cyclically already void flushESFSTATUS(); //Mark all the data as read/stale @@ -851,6 +871,7 @@ class SFE_UBLOX_GNSS boolean getESFINS(uint16_t maxWait = defaultMaxWait); // ESF INS boolean setAutoESFINS(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic ESF INS reports boolean setAutoESFINS(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic ESF INS reports, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoESFINSrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic INS reports boolean setAutoESFINScallback(void (*callbackPointer)(UBX_ESF_INS_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic INS reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoESFINS(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and ESF INS is send cyclically already void flushESFINS(); //Mark all the data as read/stale @@ -860,6 +881,7 @@ class SFE_UBLOX_GNSS boolean getESFMEAS(uint16_t maxWait = defaultMaxWait); // ESF MEAS boolean setAutoESFMEAS(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic ESF MEAS reports boolean setAutoESFMEAS(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic ESF MEAS reports, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoESFMEASrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic MEAS reports boolean setAutoESFMEAScallback(void (*callbackPointer)(UBX_ESF_MEAS_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic MEAS reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoESFMEAS(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and ESF MEAS is send cyclically already void flushESFMEAS(); //Mark all the data as read/stale @@ -869,6 +891,7 @@ class SFE_UBLOX_GNSS boolean getESFRAW(uint16_t maxWait = defaultMaxWait); // ESF RAW boolean setAutoESFRAW(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic ESF RAW reports boolean setAutoESFRAW(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic ESF RAW reports, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoESFRAWrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic RAW reports boolean setAutoESFRAWcallback(void (*callbackPointer)(UBX_ESF_RAW_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic RAW reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoESFRAW(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and ESF RAW is send cyclically already void flushESFRAW(); //Mark all the data as read/stale @@ -880,6 +903,7 @@ class SFE_UBLOX_GNSS boolean getHNRATT(uint16_t maxWait = defaultMaxWait); // Returns true if the get HNR attitude is successful boolean setAutoHNRATT(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic HNR Attitude reports at the HNR rate boolean setAutoHNRATT(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic HNR Attitude reports at the HNR rate, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoHNRATTrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic ATT reports boolean setAutoHNRATTcallback(void (*callbackPointer)(UBX_HNR_ATT_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic ATT reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoHNRATT(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and HNR Attitude is send cyclically already void flushHNRATT(); //Mark all the data as read/stale @@ -889,6 +913,7 @@ class SFE_UBLOX_GNSS boolean getHNRINS(uint16_t maxWait = defaultMaxWait); // Returns true if the get HNR dynamics is successful boolean setAutoHNRINS(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic HNR dynamics reports at the HNR rate boolean setAutoHNRINS(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic HNR dynamics reports at the HNR rate, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoHNRINSrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic INS reports boolean setAutoHNRINScallback(void (*callbackPointer)(UBX_HNR_INS_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic INS reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoHNRINS(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and HNR dynamics is send cyclically already void flushHNRINS(); //Mark all the data as read/stale @@ -897,6 +922,7 @@ class SFE_UBLOX_GNSS boolean getHNRPVT(uint16_t maxWait = defaultMaxWait); // Returns true if the get HNR PVT is successful boolean setAutoHNRPVT(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic HNR PVT reports at the HNR rate boolean setAutoHNRPVT(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic HNR PVT reports at the HNR rate, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update + boolean setAutoHNRPVTrate(uint8_t rate, boolean implicitUpdate = true, uint16_t maxWait = defaultMaxWait); //Set the rate for automatic PVT reports boolean setAutoHNRPVTcallback(void (*callbackPointer)(UBX_HNR_PVT_data_t), uint16_t maxWait = defaultMaxWait); //Enable automatic PVT reports at the navigation frequency. Data is accessed from the callback. boolean assumeAutoHNRPVT(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and HNR PVT is send cyclically already void flushHNRPVT(); //Mark all the data as read/stale @@ -938,6 +964,7 @@ class SFE_UBLOX_GNSS uint8_t getSecond(uint16_t maxWait = defaultMaxWait); uint16_t getMillisecond(uint16_t maxWait = defaultMaxWait); int32_t getNanosecond(uint16_t maxWait = defaultMaxWait); + uint32_t getUnixEpoch(uint16_t maxWait = defaultMaxWait); uint32_t getUnixEpoch(uint32_t& microsecond, uint16_t maxWait = defaultMaxWait); bool getDateValid(uint16_t maxWait = defaultMaxWait);