From 2ce23fe6960101fdfd8716510de2c5e2970addb2 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Thu, 1 Apr 2021 09:41:18 +0100 Subject: [PATCH 1/4] Correct #20. Add .end. Add getFileBufferSize. Add Example26 --- examples/Example26_End/Example26_End.ino | 91 +++++ keywords.txt | 2 + src/SparkFun_u-blox_GNSS_Arduino_Library.cpp | 374 +++++++++++++++++-- src/SparkFun_u-blox_GNSS_Arduino_Library.h | 3 + 4 files changed, 439 insertions(+), 31 deletions(-) create mode 100644 examples/Example26_End/Example26_End.ino 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/keywords.txt b/keywords.txt index 3a24b76..fbf544f 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 diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp index 15dd564..915a1b1 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 +boolean 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; @@ -4877,7 +5189,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; @@ -5025,7 +5337,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; @@ -5195,7 +5507,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; @@ -5349,7 +5661,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; @@ -5521,7 +5833,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; @@ -5670,7 +5982,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; @@ -5817,7 +6129,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; @@ -5964,7 +6276,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; @@ -6111,7 +6423,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; @@ -6280,7 +6592,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; @@ -6427,7 +6739,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 +6800,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; @@ -6626,7 +6938,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; @@ -6773,7 +7085,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; @@ -6920,7 +7232,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 +7306,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; @@ -7127,7 +7439,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; @@ -7303,7 +7615,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; @@ -7480,7 +7792,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; @@ -7656,7 +7968,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; @@ -7832,7 +8144,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; @@ -8008,7 +8320,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; @@ -8189,7 +8501,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; @@ -8371,7 +8683,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; @@ -8547,7 +8859,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; diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.h b/src/SparkFun_u-blox_GNSS_Arduino_Library.h index 7af2ca4..219db4e 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 + boolean 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. From e483b119cc254833419d528c9b23c520475d2dbc Mon Sep 17 00:00:00 2001 From: PaulZC Date: Thu, 1 Apr 2021 11:14:04 +0100 Subject: [PATCH 2/4] Update ZED_F9P\Example10 - corrects issue #19 --- .../Example16_Nanosecond_MaxOutput.ino | 4 ++-- .../Example16_PartialSecond_MaxOutput.ino | 2 +- ...10_GetHighPrecisionPositionAndAccuracy.ino | 22 +++++++++++++++++-- 3 files changed, 23 insertions(+), 5 deletions(-) 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/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); +} From 47f95a10b8ec3670bac850a82f90d9a700601698 Mon Sep 17 00:00:00 2001 From: PaulZC Date: Thu, 1 Apr 2021 12:45:34 +0100 Subject: [PATCH 3/4] .end now returns void. Update getUnixEpoch so it runs correctly on the ATmega328P --- src/SparkFun_u-blox_GNSS_Arduino_Library.cpp | 26 ++++++++++---------- src/SparkFun_u-blox_GNSS_Arduino_Library.h | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp index 915a1b1..3fde61c 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp @@ -53,7 +53,7 @@ SFE_UBLOX_GNSS::SFE_UBLOX_GNSS(void) } //Stop all automatic message processing. Free all used RAM -boolean SFE_UBLOX_GNSS::end(void) +void SFE_UBLOX_GNSS::end(void) { //Note: payloadCfg is not deleted @@ -9283,12 +9283,12 @@ uint32_t SFE_UBLOX_GNSS::getUnixEpoch(uint16_t maxWait) 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) + (((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); + 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; } @@ -9310,12 +9310,12 @@ uint32_t SFE_UBLOX_GNSS::getUnixEpoch(uint32_t& microsecond, uint16_t maxWait) packetUBXNAVPVT->moduleQueried.moduleQueried1.bits.nano = 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) + (((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); + 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 diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.h b/src/SparkFun_u-blox_GNSS_Arduino_Library.h index 219db4e..515a87d 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.h +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.h @@ -482,7 +482,7 @@ class SFE_UBLOX_GNSS //serialPort needs to be perviously initialized to correct baud rate boolean begin(Stream &serialPort); //Returns true if module is detected - boolean end(void); //Stop all automatic message processing. Free all used RAM + 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 From de5e73947be92f137f644df54039b043bf95dcda Mon Sep 17 00:00:00 2001 From: PaulZC Date: Thu, 1 Apr 2021 13:52:30 +0100 Subject: [PATCH 4/4] Starting to add support for multiple message rates --- .../Example27_MultipleRates.ino | 90 +++++++++++++++++++ src/SparkFun_u-blox_GNSS_Arduino_Library.cpp | 26 ++++-- src/SparkFun_u-blox_GNSS_Arduino_Library.h | 2 + 3 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 examples/Example27_MultipleRates/Example27_MultipleRates.ino diff --git a/examples/Example27_MultipleRates/Example27_MultipleRates.ino b/examples/Example27_MultipleRates/Example27_MultipleRates.ino new file mode 100644 index 0000000..2fa97bf --- /dev/null +++ b/examples/Example27_MultipleRates/Example27_MultipleRates.ino @@ -0,0 +1,90 @@ +/* + 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 once per measurement; + POS_ECEF is output every second measurement; + VEL_NED is output every third measurement. + + 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" each PVT solution every measurement + //myGNSS.setAutoPOSECEFrate(2); //Tell the GNSS to "send" each POS_ECEF solution every second measurement + myGNSS.setAutoNAVVELNEDrate(3); //Tell the GNSS to "send" each VEL_NED solution every third 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 getVELNED 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/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp index 3fde61c..75e0cca 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.cpp @@ -5755,12 +5755,19 @@ 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 @@ -5772,12 +5779,12 @@ boolean SFE_UBLOX_GNSS::setAutoPVT(boolean enable, boolean implicitUpdate, uint1 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; @@ -6199,12 +6206,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 @@ -6216,12 +6230,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; diff --git a/src/SparkFun_u-blox_GNSS_Arduino_Library.h b/src/SparkFun_u-blox_GNSS_Arduino_Library.h index 515a87d..aee8552 100644 --- a/src/SparkFun_u-blox_GNSS_Arduino_Library.h +++ b/src/SparkFun_u-blox_GNSS_Arduino_Library.h @@ -733,6 +733,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); //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 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 @@ -757,6 +758,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); //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 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