Merge pull request #163 from sparkfun/release_candidate

v2.2.18
This commit is contained in:
Paul
2022-10-28 10:22:18 +01:00
committed by GitHub
6 changed files with 577 additions and 16 deletions
@@ -0,0 +1,340 @@
/*
Configuring the GNSS to automatically send RXM SFRBX and RAWX reports over SPI and log them to file on SD card using full 4-bit SDIO
By: Paul Clark
SparkFun Electronics
Date: October 20th, 2022
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 send RXM SFRBX and RAWX reports automatically
and log the data to SD card in UBX format.
This code is written for the OpenLog ESP32 (DEV-20594) - coming soon!
Hardware set-up:
Close the DSEL jumper on the ZED-F9P breakout - to select SPI mode
Connect:
OpenLog ESP32 : ZED-F9P
GND GND
3V3_SW 3V3
SCK (18) SCK
PICO (23) PICO (MOSI)
POCI (19) POCI (MISO)
33 CS
** Please note: this example will only work on u-blox ADR or High Precision GNSS or Time Sync products **
Data is logged in u-blox UBX format.
Feel like supporting open source hardware?
Buy a board from SparkFun!
OpenLog ESP32: https://www.sparkfun.com/products/20594
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
NEO-M8P RTK: https://www.sparkfun.com/products/15005
*/
#define GNSS_CS 33 // Connect the ZED-F9P CS pin to OpenLog ESP32 pin 33
#define EN_3V3_SW 32 // The 3.3V_SW regulator Enable pin is connected to D32
#define STAT_LED 25 // The OpenLog ESP32 STAT LED is connected to pin 25
#define IMU_CS 5 // The ISM330 IMU CS is connected to pin 5
#define MAG_CS 27 // The MMC5983 Mag CS is connected to pin 27
#include "FS.h"
#include "SD_MMC.h"
File myFile;
#include <SPI.h>
#define spiPort SPI
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_GNSS
SFE_UBLOX_GNSS myGNSS;
#define sdWriteSize 2048 // Write data to the SD card in blocks of n*512 bytes
#define fileBufferSize 65530 // Allocate just under 64KBytes of RAM for UBX message storage
#define navRate 20 // Set the Nav Rate (Frequency) to 20Hz
//#define ubxOnly // Uncomment this line to log UBX (RAWX and SFRBX) only
uint8_t *myBuffer; // Use myBuffer to hold the data while we write it to SD card
unsigned long lastPrint; // Record when the last Serial print took place
// Note: we'll keep a count of how many SFRBX and RAWX messages arrive - but the count will not be completely accurate.
// If two or more SFRBX messages arrive together as a group and are processed by one call to checkUblox, the count will
// only increase by one.
int numSFRBX = 0; // Keep count of how many SFRBX message groups have been received (see note above)
int numRAWX = 0; // Keep count of how many RAWX message groups have been received (see note above)
// Callback: newSFRBX will be called when new RXM SFRBX data arrives
// See u-blox_structs.h for the full definition of UBX_RXMSFRBX_data_t
// _____ You can use any name you like for the callback. Use the same name when you call setAutoRXMSFRBXcallback
// / _____ This _must_ be UBX_RXM_SFRBX_data_t
// | / _____ You can use any name you like for the struct
// | | /
// | | |
void newSFRBX(UBX_RXM_SFRBX_data_t *ubxDataStruct)
{
numSFRBX++; // Increment the count
}
// Callback: newRAWX will be called when new RXM RAWX data arrives
// See u-blox_structs.h for the full definition of UBX_RXMRAWX_data_t
// _____ You can use any name you like for the callback. Use the same name when you call setAutoRXMRAWXcallback
// / _____ This _must_ be UBX_RXM_RAWX_data_t
// | / _____ You can use any name you like for the struct
// | | /
// | | |
void newRAWX(UBX_RXM_RAWX_data_t *ubxDataStruct)
{
numRAWX++; // Increment the count
}
void setup()
{
Serial.begin(115200);
pinMode(STAT_LED, OUTPUT); // Flash the STAT LED each time we write to the SD card
digitalWrite(STAT_LED, LOW);
pinMode(GNSS_CS, OUTPUT);
digitalWrite(GNSS_CS, HIGH);
pinMode(IMU_CS, OUTPUT);
digitalWrite(IMU_CS, HIGH);
pinMode(MAG_CS, OUTPUT);
digitalWrite(MAG_CS, HIGH);
spiPort.begin();
// Do a fake transaction to initialize the SPI pins
spiPort.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
spiPort.transfer(0);
spiPort.endTransaction();
pinMode(EN_3V3_SW, OUTPUT); // Enable power for the microSD card and GNSS
digitalWrite(EN_3V3_SW, HIGH);
delay(3000); // Allow time for the GNSS and SD card to start up and for Tera Term to reconnect
Serial.println(F("SparkFun OpenLog ESP32 GNSS Logging : SPI and SDIO"));
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Initialize the GNSS
Serial.println(F("Initializing the GNSS..."));
//myGNSS.enableDebugging(); // Uncomment this line to see helpful debug messages on Serial
myGNSS.setFileBufferSize(fileBufferSize); // setFileBufferSize must be called _before_ .begin
// Connect to the u-blox module using SPI port, csPin and speed setting
// ublox devices generally work up to 5MHz. We'll use 4MHz for this example:
bool begun = false;
do
{
begun = myGNSS.begin(spiPort, GNSS_CS, 4000000);
if (!begun)
{
Serial.println(F("u-blox GNSS not detected on SPI bus."));
delay(1000);
}
}
while (!begun);
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Wait for a 3D fix. Get the date and time for the log file
//myGNSS.factoryDefault(); delay(5000); // Uncomment this line to reset the module back to its factory defaults
#ifdef ubxOnly
myGNSS.setSPIOutput(COM_TYPE_UBX); //Set the SPI port to output only UBX
#else
myGNSS.setSPIOutput(COM_TYPE_UBX | COM_TYPE_NMEA); //Set the SPI port to output both UBX and NMEA messages
#endif
//myGNSS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Optional: save (only) the communications port settings to flash and BBR
Serial.print(F("Waiting for a 3D fix"));
uint8_t fix = 0;
do
{
fix = myGNSS.getFixType();
delay(1000);
Serial.print(F("."));
}
while ( fix != 3 ); // Wait for a 3D fix
Serial.println();
uint16_t y = myGNSS.getYear();
uint8_t M = myGNSS.getMonth();
uint8_t d = myGNSS.getDay();
uint8_t h = myGNSS.getHour();
uint8_t m = myGNSS.getMinute();
uint8_t s = myGNSS.getSecond();
char szBuffer[40] = {'\0'};
snprintf(szBuffer, sizeof(szBuffer), "/%04d%02d%02d%02d%02d%02d.ubx", y, M, d, h, m, s);
Serial.println(F("GNSS initialized."));
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Initialize the SD card. Open the log file
Serial.println(F("Initializing SD card..."));
// Begin the SD card
if(!SD_MMC.begin())
{
Serial.println(F("Card mount failed. Freezing..."));
while(1);
}
// Open the log file for writing
Serial.printf("Log file is: %s\r\n", szBuffer);
myFile = SD_MMC.open((const char *)szBuffer, FILE_WRITE);
if(!myFile)
{
Serial.println(F("Failed to open log file for writing. Freezing..."));
while(1);
}
Serial.println(F("SD card initialized."));
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Wait for a key press
while (Serial.available()) // Make sure the Serial buffer is empty
{
Serial.read();
}
Serial.println(F("Press any key to start logging."));
while (!Serial.available()) // Wait for the user to press a key
{
; // Do nothing
}
delay(100); // Wait, just in case multiple characters were sent
while (Serial.available()) // Empty the Serial buffer
{
Serial.read();
}
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Enable RAWX and SFRBX
myGNSS.setAutoRXMSFRBXcallbackPtr(&newSFRBX); // Enable automatic RXM SFRBX messages with callback to newSFRBX
myGNSS.logRXMSFRBX(); // Enable RXM SFRBX data logging
myGNSS.setAutoRXMRAWXcallbackPtr(&newRAWX); // Enable automatic RXM RAWX messages with callback to newRAWX
myGNSS.logRXMRAWX(); // Enable RXM RAWX data logging
myBuffer = new uint8_t[sdWriteSize]; // Create our own buffer to hold the data while we write it to SD card
#ifndef ubxOnly
myGNSS.enableNMEAMessage(UBX_NMEA_GGA, COM_PORT_SPI, navRate); // Ensure the GxGGA (Global positioning system fix data) message is enabled. Send every second.
myGNSS.enableNMEAMessage(UBX_NMEA_GSA, COM_PORT_SPI, navRate); // Ensure the GxGSA (GNSS DOP and Active satellites) message is enabled. Send every second.
myGNSS.enableNMEAMessage(UBX_NMEA_GSV, COM_PORT_SPI, navRate); // Ensure the GxGSV (GNSS satellites in view) message is enabled. Send every second.
myGNSS.enableNMEAMessage(UBX_NMEA_GST, COM_PORT_SPI, navRate); // Ensure the GxGST (Position error statistics) message is enabled. Send every second.
myGNSS.enableNMEAMessage(UBX_NMEA_RMC, COM_PORT_SPI, navRate); // Ensure the GxRMC (Recommended minimum: position, velocity and time) message is enabled. Send every second.
myGNSS.setNMEALoggingMask(SFE_UBLOX_FILTER_NMEA_GGA | SFE_UBLOX_FILTER_NMEA_GSA | SFE_UBLOX_FILTER_NMEA_GSV | SFE_UBLOX_FILTER_NMEA_GST | SFE_UBLOX_FILTER_NMEA_RMC); // Log only these NMEA messages
#endif
myGNSS.setNavigationFrequency(navRate); // Set navigation rate
Serial.println(F("Press any key to stop logging."));
lastPrint = millis(); // Initialize lastPrint
}
void loop()
{
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
myGNSS.checkUblox(); // Check for the arrival of new data and process it.
myGNSS.checkCallbacks(); // Check if any callbacks are waiting to be processed.
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
while (myGNSS.fileBufferAvailable() >= sdWriteSize) // Check to see if we have at least sdWriteSize waiting in the buffer
{
digitalWrite(STAT_LED, HIGH); // Flash the STAT LED each time we write to the SD card
myGNSS.extractFileBufferData(myBuffer, sdWriteSize); // Extract exactly sdWriteSize bytes from the UBX file buffer and put them into myBuffer
myFile.write(myBuffer, sdWriteSize); // Write exactly sdWriteSize bytes from myBuffer to the ubxDataFile on the SD card
// In case the SD writing is slow or there is a lot of data to write, keep checking for the arrival of new data
myGNSS.checkUblox(); // Check for the arrival of new data and process it.
myGNSS.checkCallbacks(); // Check if any callbacks are waiting to be processed.
digitalWrite(STAT_LED, LOW); // Turn the STAT LED off again
}
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
if (millis() > (lastPrint + 1000)) // Print the message count once per second
{
uint16_t maxBufferBytes = myGNSS.getMaxFileBufferAvail(); // Get how full the file buffer has been (not how full it is now)
float bufferHigh = 100.0 * (float)maxBufferBytes / (float)fileBufferSize;
Serial.print(F("Message groups received: SFRBX: ")); // Print how many message groups have been received (see note above)
Serial.print(numSFRBX);
Serial.print(F(" RAWX: "));
Serial.print(numRAWX);
Serial.print(F(" \tBuffer high tide: "));
Serial.print(bufferHigh, 1); // It is a fun thing to watch how full the buffer gets
if (bufferHigh > 90.)
Serial.println(F("%!!"));
else if (bufferHigh > 80.)
Serial.println(F("%!"));
else
Serial.println(F("%"));
lastPrint = millis(); // Update lastPrint
}
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
if (Serial.available()) // Check if the user wants to stop logging
{
uint16_t remainingBytes = myGNSS.fileBufferAvailable(); // Check if there are any bytes remaining in the file buffer
while (remainingBytes > 0) // While there is still data in the file buffer
{
digitalWrite(STAT_LED, HIGH); // Flash the STAT LED while we write to the SD card
uint16_t bytesToWrite = remainingBytes; // Write the remaining bytes to SD card sdWriteSize bytes at a time
if (bytesToWrite > sdWriteSize)
{
bytesToWrite = sdWriteSize;
}
myGNSS.extractFileBufferData(myBuffer, bytesToWrite); // Extract bytesToWrite bytes from the UBX file buffer and put them into myBuffer
myFile.write(myBuffer, bytesToWrite); // Write bytesToWrite bytes from myBuffer to the ubxDataFile on the SD card
remainingBytes -= bytesToWrite; // Decrement remainingBytes
}
digitalWrite(STAT_LED, LOW); // Turn the STAT LED off
myFile.close(); // Close the data file
myGNSS.setNavigationFrequency(1); // Set navigation rate to 1Hz
myGNSS.disableMessage(UBX_CLASS_RXM, UBX_RXM_RAWX, COM_PORT_SPI);
myGNSS.disableMessage(UBX_CLASS_RXM, UBX_RXM_SFRBX, COM_PORT_SPI);
myGNSS.setSPIOutput(COM_TYPE_UBX | COM_TYPE_NMEA); // Re-enable NMEA
Serial.println(F("Logging stopped. Freezing..."));
while(1); // Do nothing more
}
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
}
+5
View File
@@ -79,6 +79,7 @@ NMEA_ZDA_data_t KEYWORD1
####################################### #######################################
setPacketCfgPayloadSize KEYWORD2 setPacketCfgPayloadSize KEYWORD2
getPacketCfgSpaceRemaining KEYWORD2
begin KEYWORD2 begin KEYWORD2
end KEYWORD2 end KEYWORD2
setI2CpollingWait KEYWORD2 setI2CpollingWait KEYWORD2
@@ -232,6 +233,7 @@ setVal8 KEYWORD2
setVal16 KEYWORD2 setVal16 KEYWORD2
setVal32 KEYWORD2 setVal32 KEYWORD2
setVal64 KEYWORD2 setVal64 KEYWORD2
newCfgValset KEYWORD2
newCfgValset8 KEYWORD2 newCfgValset8 KEYWORD2
newCfgValset16 KEYWORD2 newCfgValset16 KEYWORD2
newCfgValset32 KEYWORD2 newCfgValset32 KEYWORD2
@@ -244,6 +246,9 @@ sendCfgValset8 KEYWORD2
sendCfgValset16 KEYWORD2 sendCfgValset16 KEYWORD2
sendCfgValset32 KEYWORD2 sendCfgValset32 KEYWORD2
sendCfgValset64 KEYWORD2 sendCfgValset64 KEYWORD2
sendCfgValset KEYWORD2
getCfgValsetLen KEYWORD2
getCfgValsetSpaceRemaining KEYWORD2
getNAVPOSECEF KEYWORD2 getNAVPOSECEF KEYWORD2
setAutoNAVPOSECEF KEYWORD2 setAutoNAVPOSECEF KEYWORD2
+1 -1
View File
@@ -1,5 +1,5 @@
name=SparkFun u-blox GNSS Arduino Library name=SparkFun u-blox GNSS Arduino Library
version=2.2.17 version=2.2.18
author=SparkFun Electronics <techsupport@sparkfun.com> author=SparkFun Electronics <techsupport@sparkfun.com>
maintainer=SparkFun Electronics <sparkfun.com> maintainer=SparkFun Electronics <sparkfun.com>
sentence=Library for I2C, Serial and SPI Communication with u-blox GNSS modules<br/><br/> sentence=Library for I2C, Serial and SPI Communication with u-blox GNSS modules<br/><br/>
@@ -627,6 +627,12 @@ bool SFE_UBLOX_GNSS::setPacketCfgPayloadSize(size_t payloadSize)
return (success); return (success);
} }
// Return the number of free bytes remaining in packetCfgPayload
size_t SFE_UBLOX_GNSS::getPacketCfgSpaceRemaining()
{
return (packetCfgPayloadSize - packetCfg.len);
}
// Initialize the I2C port // Initialize the I2C port
bool SFE_UBLOX_GNSS::begin(TwoWire &wirePort, uint8_t deviceAddress, uint16_t maxWait, bool assumeSuccess) bool SFE_UBLOX_GNSS::begin(TwoWire &wirePort, uint8_t deviceAddress, uint16_t maxWait, bool assumeSuccess)
{ {
@@ -9178,6 +9184,8 @@ uint8_t SFE_UBLOX_GNSS::newCfgValset64(uint32_t key, uint64_t value, uint8_t lay
packetCfg.len = 4 + 4 + 8; // 4 byte header, 4 byte key ID, 8 bytes of value packetCfg.len = 4 + 4 + 8; // 4 byte header, 4 byte key ID, 8 bytes of value
packetCfg.startingSpot = 0; packetCfg.startingSpot = 0;
_numCfgKeyIDs = 1;
// Clear all of packet payload // Clear all of packet payload
memset(payloadCfg, 0, packetCfgPayloadSize); memset(payloadCfg, 0, packetCfgPayloadSize);
@@ -9215,6 +9223,8 @@ uint8_t SFE_UBLOX_GNSS::newCfgValset32(uint32_t key, uint32_t value, uint8_t lay
packetCfg.len = 4 + 4 + 4; // 4 byte header, 4 byte key ID, 4 bytes of value packetCfg.len = 4 + 4 + 4; // 4 byte header, 4 byte key ID, 4 bytes of value
packetCfg.startingSpot = 0; packetCfg.startingSpot = 0;
_numCfgKeyIDs = 1;
// Clear all of packet payload // Clear all of packet payload
memset(payloadCfg, 0, packetCfgPayloadSize); memset(payloadCfg, 0, packetCfgPayloadSize);
@@ -9248,6 +9258,8 @@ uint8_t SFE_UBLOX_GNSS::newCfgValset16(uint32_t key, uint16_t value, uint8_t lay
packetCfg.len = 4 + 4 + 2; // 4 byte header, 4 byte key ID, 2 bytes of value packetCfg.len = 4 + 4 + 2; // 4 byte header, 4 byte key ID, 2 bytes of value
packetCfg.startingSpot = 0; packetCfg.startingSpot = 0;
_numCfgKeyIDs = 1;
// Clear all of packet payload // Clear all of packet payload
memset(payloadCfg, 0, packetCfgPayloadSize); memset(payloadCfg, 0, packetCfgPayloadSize);
@@ -9279,6 +9291,8 @@ uint8_t SFE_UBLOX_GNSS::newCfgValset8(uint32_t key, uint8_t value, uint8_t layer
packetCfg.len = 4 + 4 + 1; // 4 byte header, 4 byte key ID, 1 byte value packetCfg.len = 4 + 4 + 1; // 4 byte header, 4 byte key ID, 1 byte value
packetCfg.startingSpot = 0; packetCfg.startingSpot = 0;
_numCfgKeyIDs = 1;
// Clear all of packet payload // Clear all of packet payload
memset(payloadCfg, 0, packetCfgPayloadSize); memset(payloadCfg, 0, packetCfgPayloadSize);
@@ -9298,10 +9312,49 @@ uint8_t SFE_UBLOX_GNSS::newCfgValset8(uint32_t key, uint8_t value, uint8_t layer
return (true); return (true);
} }
// Start defining a new (empty) UBX-CFG-VALSET ubxPacket
// Configuration of modern u-blox modules is now done via getVal/setVal/delVal, ie protocol v27 and above found on ZED-F9P
uint8_t SFE_UBLOX_GNSS::newCfgValset(uint8_t layer)
{
packetCfg.cls = UBX_CLASS_CFG;
packetCfg.id = UBX_CFG_VALSET;
packetCfg.len = 4; // 4 byte header
packetCfg.startingSpot = 0;
_numCfgKeyIDs = 0;
// Clear all of packet payload
memset(payloadCfg, 0, packetCfgPayloadSize);
payloadCfg[0] = 0; // Message Version - set to 0
payloadCfg[1] = layer; // By default we ask for the BBR layer
// All done
return (true);
}
// Add another keyID and value to an existing UBX-CFG-VALSET ubxPacket // Add another keyID and value to an existing UBX-CFG-VALSET ubxPacket
// This function takes a full 32-bit key and 64-bit value // This function takes a full 32-bit key and 64-bit value
uint8_t SFE_UBLOX_GNSS::addCfgValset64(uint32_t key, uint64_t value) uint8_t SFE_UBLOX_GNSS::addCfgValset64(uint32_t key, uint64_t value)
{ {
if (packetCfg.len >= (packetCfgPayloadSize - 12))
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("addCfgValset64: packetCfgPayloadSize reached!"));
#endif
return false;
}
if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS)
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("addCfgValset64: key limit reached!"));
#endif
return false;
}
// Load key into outgoing payload // Load key into outgoing payload
payloadCfg[packetCfg.len + 0] = key >> 8 * 0; // Key LSB payloadCfg[packetCfg.len + 0] = key >> 8 * 0; // Key LSB
payloadCfg[packetCfg.len + 1] = key >> 8 * 1; payloadCfg[packetCfg.len + 1] = key >> 8 * 1;
@@ -9321,6 +9374,8 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset64(uint32_t key, uint64_t value)
// Update packet length: 4 byte key ID, 8 bytes of value // Update packet length: 4 byte key ID, 8 bytes of value
packetCfg.len = packetCfg.len + 4 + 8; packetCfg.len = packetCfg.len + 4 + 8;
_numCfgKeyIDs++;
// All done // All done
return (true); return (true);
} }
@@ -9329,6 +9384,24 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset64(uint32_t key, uint64_t value)
// This function takes a full 32-bit key and 32-bit value // This function takes a full 32-bit key and 32-bit value
uint8_t SFE_UBLOX_GNSS::addCfgValset32(uint32_t key, uint32_t value) uint8_t SFE_UBLOX_GNSS::addCfgValset32(uint32_t key, uint32_t value)
{ {
if (packetCfg.len >= (packetCfgPayloadSize - 8))
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("addCfgValset32: packetCfgPayloadSize reached!"));
#endif
return false;
}
if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS)
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("addCfgValset32: key limit reached!"));
#endif
return false;
}
// Load key into outgoing payload // Load key into outgoing payload
payloadCfg[packetCfg.len + 0] = key >> 8 * 0; // Key LSB payloadCfg[packetCfg.len + 0] = key >> 8 * 0; // Key LSB
payloadCfg[packetCfg.len + 1] = key >> 8 * 1; payloadCfg[packetCfg.len + 1] = key >> 8 * 1;
@@ -9344,6 +9417,8 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset32(uint32_t key, uint32_t value)
// Update packet length: 4 byte key ID, 4 bytes of value // Update packet length: 4 byte key ID, 4 bytes of value
packetCfg.len = packetCfg.len + 4 + 4; packetCfg.len = packetCfg.len + 4 + 4;
_numCfgKeyIDs++;
// All done // All done
return (true); return (true);
} }
@@ -9352,6 +9427,24 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset32(uint32_t key, uint32_t value)
// This function takes a full 32-bit key and 16-bit value // This function takes a full 32-bit key and 16-bit value
uint8_t SFE_UBLOX_GNSS::addCfgValset16(uint32_t key, uint16_t value) uint8_t SFE_UBLOX_GNSS::addCfgValset16(uint32_t key, uint16_t value)
{ {
if (packetCfg.len >= (packetCfgPayloadSize - 6))
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("addCfgValset16: packetCfgPayloadSize reached!"));
#endif
return false;
}
if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS)
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("addCfgValset16: key limit reached!"));
#endif
return false;
}
// Load key into outgoing payload // Load key into outgoing payload
payloadCfg[packetCfg.len + 0] = key >> 8 * 0; // Key LSB payloadCfg[packetCfg.len + 0] = key >> 8 * 0; // Key LSB
payloadCfg[packetCfg.len + 1] = key >> 8 * 1; payloadCfg[packetCfg.len + 1] = key >> 8 * 1;
@@ -9365,6 +9458,8 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset16(uint32_t key, uint16_t value)
// Update packet length: 4 byte key ID, 2 bytes of value // Update packet length: 4 byte key ID, 2 bytes of value
packetCfg.len = packetCfg.len + 4 + 2; packetCfg.len = packetCfg.len + 4 + 2;
_numCfgKeyIDs++;
// All done // All done
return (true); return (true);
} }
@@ -9373,6 +9468,24 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset16(uint32_t key, uint16_t value)
// This function takes a full 32-bit key and 8-bit value // This function takes a full 32-bit key and 8-bit value
uint8_t SFE_UBLOX_GNSS::addCfgValset8(uint32_t key, uint8_t value) uint8_t SFE_UBLOX_GNSS::addCfgValset8(uint32_t key, uint8_t value)
{ {
if (packetCfg.len >= (packetCfgPayloadSize - 5))
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("addCfgValset8: packetCfgPayloadSize reached!"));
#endif
return false;
}
if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS)
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("addCfgValset8: key limit reached!"));
#endif
return false;
}
// Load key into outgoing payload // Load key into outgoing payload
payloadCfg[packetCfg.len + 0] = key >> 8 * 0; // Key LSB payloadCfg[packetCfg.len + 0] = key >> 8 * 0; // Key LSB
payloadCfg[packetCfg.len + 1] = key >> 8 * 1; payloadCfg[packetCfg.len + 1] = key >> 8 * 1;
@@ -9385,6 +9498,8 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset8(uint32_t key, uint8_t value)
// Update packet length: 4 byte key ID, 1 byte value // Update packet length: 4 byte key ID, 1 byte value
packetCfg.len = packetCfg.len + 4 + 1; packetCfg.len = packetCfg.len + 4 + 1;
_numCfgKeyIDs++;
// All done // All done
return (true); return (true);
} }
@@ -9393,9 +9508,26 @@ uint8_t SFE_UBLOX_GNSS::addCfgValset8(uint32_t key, uint8_t value)
// This function takes a full 32-bit key and 64-bit value // This function takes a full 32-bit key and 64-bit value
uint8_t SFE_UBLOX_GNSS::sendCfgValset64(uint32_t key, uint64_t value, uint16_t maxWait) uint8_t SFE_UBLOX_GNSS::sendCfgValset64(uint32_t key, uint64_t value, uint16_t maxWait)
{ {
if (packetCfg.len >= (packetCfgPayloadSize - 12))
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("sendCfgValset64: packetCfgPayloadSize reached!"));
#endif
}
else if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS)
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("sendCfgValset64: key limit reached!"));
#endif
}
else
// Load keyID and value into outgoing payload // Load keyID and value into outgoing payload
addCfgValset64(key, value); addCfgValset64(key, value);
_numCfgKeyIDs = 0;
// Send VALSET command with this key and value // Send VALSET command with this key and value
return (sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK return (sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
} }
@@ -9404,9 +9536,26 @@ uint8_t SFE_UBLOX_GNSS::sendCfgValset64(uint32_t key, uint64_t value, uint16_t m
// This function takes a full 32-bit key and 32-bit value // This function takes a full 32-bit key and 32-bit value
uint8_t SFE_UBLOX_GNSS::sendCfgValset32(uint32_t key, uint32_t value, uint16_t maxWait) uint8_t SFE_UBLOX_GNSS::sendCfgValset32(uint32_t key, uint32_t value, uint16_t maxWait)
{ {
if (packetCfg.len >= (packetCfgPayloadSize - 8))
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("sendCfgValset32: packetCfgPayloadSize reached!"));
#endif
}
else if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS)
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("sendCfgValset32: key limit reached!"));
#endif
}
else
// Load keyID and value into outgoing payload // Load keyID and value into outgoing payload
addCfgValset32(key, value); addCfgValset32(key, value);
_numCfgKeyIDs = 0;
// Send VALSET command with this key and value // Send VALSET command with this key and value
return (sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK return (sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
} }
@@ -9415,9 +9564,26 @@ uint8_t SFE_UBLOX_GNSS::sendCfgValset32(uint32_t key, uint32_t value, uint16_t m
// This function takes a full 32-bit key and 16-bit value // This function takes a full 32-bit key and 16-bit value
uint8_t SFE_UBLOX_GNSS::sendCfgValset16(uint32_t key, uint16_t value, uint16_t maxWait) uint8_t SFE_UBLOX_GNSS::sendCfgValset16(uint32_t key, uint16_t value, uint16_t maxWait)
{ {
if (packetCfg.len >= (packetCfgPayloadSize - 6))
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("sendCfgValset16: packetCfgPayloadSize reached!"));
#endif
}
else if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS)
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("sendCfgValset16: key limit reached!"));
#endif
}
else
// Load keyID and value into outgoing payload // Load keyID and value into outgoing payload
addCfgValset16(key, value); addCfgValset16(key, value);
_numCfgKeyIDs = 0;
// Send VALSET command with this key and value // Send VALSET command with this key and value
return (sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK return (sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
} }
@@ -9426,13 +9592,51 @@ uint8_t SFE_UBLOX_GNSS::sendCfgValset16(uint32_t key, uint16_t value, uint16_t m
// This function takes a full 32-bit key and 8-bit value // This function takes a full 32-bit key and 8-bit value
uint8_t SFE_UBLOX_GNSS::sendCfgValset8(uint32_t key, uint8_t value, uint16_t maxWait) uint8_t SFE_UBLOX_GNSS::sendCfgValset8(uint32_t key, uint8_t value, uint16_t maxWait)
{ {
if (packetCfg.len >= (packetCfgPayloadSize - 5))
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("sendCfgValset8: packetCfgPayloadSize reached!"));
#endif
}
else if (_numCfgKeyIDs == CFG_VALSET_MAX_KEYS)
{
#ifndef SFE_UBLOX_REDUCED_PROG_MEM
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
_debugSerial->println(F("sendCfgValset8: key limit reached!"));
#endif
}
else
// Load keyID and value into outgoing payload // Load keyID and value into outgoing payload
addCfgValset8(key, value); addCfgValset8(key, value);
_numCfgKeyIDs = 0;
// Send VALSET command with this key and value // Send VALSET command with this key and value
return (sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK return (sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
} }
// Send the UBX-CFG-VALSET ubxPacket
uint8_t SFE_UBLOX_GNSS::sendCfgValset(uint16_t maxWait)
{
_numCfgKeyIDs = 0;
// Send VALSET command with this key and value
return (sendCommand(&packetCfg, maxWait) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
}
// Return the number of keys in the CfgValset
uint8_t SFE_UBLOX_GNSS::getCfgValsetLen()
{
return _numCfgKeyIDs;
}
// Return the number of free bytes remaining in packetCfgPayload
size_t SFE_UBLOX_GNSS::getCfgValsetSpaceRemaining()
{
return getPacketCfgSpaceRemaining();
}
//=-=-=-=-=-=-=-= "Automatic" Messages =-=-=-=-=-=-=-==-=-=-=-=-=-=-= //=-=-=-=-=-=-=-= "Automatic" Messages =-=-=-=-=-=-=-==-=-=-=-=-=-=-=
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
@@ -664,6 +664,7 @@ public:
// New in v2.0: allow the payload size for packetCfg to be changed // New in v2.0: allow the payload size for packetCfg to be changed
bool setPacketCfgPayloadSize(size_t payloadSize); // Set packetCfgPayloadSize bool setPacketCfgPayloadSize(size_t payloadSize); // Set packetCfgPayloadSize
size_t getPacketCfgSpaceRemaining(); // Returns the number of free bytes remaining in packetCfgPayload
// Begin communication with the GNSS. Advanced users can assume success if required. Useful if the port is already outputting messages at high navigation rate. // Begin communication with the GNSS. Advanced users can assume success if required. Useful if the port is already outputting messages at high navigation rate.
// Begin will then return true if "signs of life" have been seen: reception of _any_ valid UBX packet or _any_ valid NMEA header. // Begin will then return true if "signs of life" have been seen: reception of _any_ valid UBX packet or _any_ valid NMEA header.
@@ -979,6 +980,7 @@ public:
uint8_t setVal16(uint32_t keyID, uint16_t value, uint8_t layer = VAL_LAYER_ALL, uint16_t maxWait = defaultMaxWait); // Sets the 16-bit value at a given group/id/size location uint8_t setVal16(uint32_t keyID, uint16_t value, uint8_t layer = VAL_LAYER_ALL, uint16_t maxWait = defaultMaxWait); // Sets the 16-bit value at a given group/id/size location
uint8_t setVal32(uint32_t keyID, uint32_t value, uint8_t layer = VAL_LAYER_ALL, uint16_t maxWait = defaultMaxWait); // Sets the 32-bit value at a given group/id/size location uint8_t setVal32(uint32_t keyID, uint32_t value, uint8_t layer = VAL_LAYER_ALL, uint16_t maxWait = defaultMaxWait); // Sets the 32-bit value at a given group/id/size location
uint8_t setVal64(uint32_t keyID, uint64_t value, uint8_t layer = VAL_LAYER_ALL, uint16_t maxWait = defaultMaxWait); // Sets the 64-bit value at a given group/id/size location uint8_t setVal64(uint32_t keyID, uint64_t value, uint8_t layer = VAL_LAYER_ALL, uint16_t maxWait = defaultMaxWait); // Sets the 64-bit value at a given group/id/size location
uint8_t newCfgValset(uint8_t layer = VAL_LAYER_ALL); // Create a new, empty UBX-CFG-VALSET. Add entries with addCfgValset8/16/32/64
uint8_t newCfgValset8(uint32_t keyID, uint8_t value, uint8_t layer = VAL_LAYER_ALL); // Define a new UBX-CFG-VALSET with the given KeyID and 8-bit value uint8_t newCfgValset8(uint32_t keyID, uint8_t value, uint8_t layer = VAL_LAYER_ALL); // Define a new UBX-CFG-VALSET with the given KeyID and 8-bit value
uint8_t newCfgValset16(uint32_t keyID, uint16_t value, uint8_t layer = VAL_LAYER_ALL); // Define a new UBX-CFG-VALSET with the given KeyID and 16-bit value uint8_t newCfgValset16(uint32_t keyID, uint16_t value, uint8_t layer = VAL_LAYER_ALL); // Define a new UBX-CFG-VALSET with the given KeyID and 16-bit value
uint8_t newCfgValset32(uint32_t keyID, uint32_t value, uint8_t layer = VAL_LAYER_ALL); // Define a new UBX-CFG-VALSET with the given KeyID and 32-bit value uint8_t newCfgValset32(uint32_t keyID, uint32_t value, uint8_t layer = VAL_LAYER_ALL); // Define a new UBX-CFG-VALSET with the given KeyID and 32-bit value
@@ -991,6 +993,9 @@ public:
uint8_t sendCfgValset16(uint32_t keyID, uint16_t value, uint16_t maxWait = defaultMaxWait); // Add the final KeyID and 16-bit value to an existing UBX-CFG-VALSET ubxPacket and send it uint8_t sendCfgValset16(uint32_t keyID, uint16_t value, uint16_t maxWait = defaultMaxWait); // Add the final KeyID and 16-bit value to an existing UBX-CFG-VALSET ubxPacket and send it
uint8_t sendCfgValset32(uint32_t keyID, uint32_t value, uint16_t maxWait = defaultMaxWait); // Add the final KeyID and 32-bit value to an existing UBX-CFG-VALSET ubxPacket and send it uint8_t sendCfgValset32(uint32_t keyID, uint32_t value, uint16_t maxWait = defaultMaxWait); // Add the final KeyID and 32-bit value to an existing UBX-CFG-VALSET ubxPacket and send it
uint8_t sendCfgValset64(uint32_t keyID, uint64_t value, uint16_t maxWait = defaultMaxWait); // Add the final KeyID and 64-bit value to an existing UBX-CFG-VALSET ubxPacket and send it uint8_t sendCfgValset64(uint32_t keyID, uint64_t value, uint16_t maxWait = defaultMaxWait); // Add the final KeyID and 64-bit value to an existing UBX-CFG-VALSET ubxPacket and send it
uint8_t sendCfgValset(uint16_t maxWait = defaultMaxWait); // Send the CfgValset (UBX-CFG-VALSET) construct
uint8_t getCfgValsetLen(); // Returns the length of the current CfgValset construct as number-of-keyIDs
size_t getCfgValsetSpaceRemaining(); // Returns the number of free bytes remaining in packetCfg
// get and set functions for all of the "automatic" message processing // get and set functions for all of the "automatic" message processing
@@ -1788,6 +1793,9 @@ private:
// .begin will return true if the assumeSuccess parameter is true and if _signsOfLife is true // .begin will return true if the assumeSuccess parameter is true and if _signsOfLife is true
// _signsOfLife is set to true when: a valid UBX message is seen; a valig NMEA header is seen. // _signsOfLife is set to true when: a valid UBX message is seen; a valig NMEA header is seen.
bool _signsOfLife; bool _signsOfLife;
// Keep track of how many keys have been added to CfgValset
uint8_t _numCfgKeyIDs = 0;
}; };
#endif #endif
+4
View File
@@ -43,6 +43,10 @@
#ifndef __u_blox_config_keys_h__ #ifndef __u_blox_config_keys_h__
#define __u_blox_config_keys_h__ #define __u_blox_config_keys_h__
// Define the maximum length of a multi-CfgValset construct
// "This message is limited to containing a maximum of 64 key-value pairs"
const uint8_t CFG_VALSET_MAX_KEYS = 64;
// The following consts are used to generate KEY values for the advanced protocol functions of VELGET/SET/DEL // The following consts are used to generate KEY values for the advanced protocol functions of VELGET/SET/DEL
const uint8_t VAL_SIZE_1 = 0x01; // One bit const uint8_t VAL_SIZE_1 = 0x01; // One bit
const uint8_t VAL_SIZE_8 = 0x02; // One byte const uint8_t VAL_SIZE_8 = 0x02; // One byte