@@ -0,0 +1,241 @@
|
|||||||
|
/*
|
||||||
|
Demonstrate how to log NMEA and UBX data simultaneously
|
||||||
|
By: Paul Clark
|
||||||
|
SparkFun Electronics
|
||||||
|
Date: April 13th, 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 send PVT reports automatically
|
||||||
|
and log those and any incoming NMEA messages to SD card in UBX format
|
||||||
|
|
||||||
|
** Please note: this example will only work on processors like the Artemis which have plenty of RAM available **
|
||||||
|
|
||||||
|
This code is intended to be run on the MicroMod Data Logging Carrier Board using the Artemis Processor
|
||||||
|
but can be adapted by changing the chip select pin and SPI definitions:
|
||||||
|
https://www.sparkfun.com/products/16829
|
||||||
|
https://www.sparkfun.com/products/16401
|
||||||
|
|
||||||
|
Hardware Connections:
|
||||||
|
Please see: https://learn.sparkfun.com/tutorials/micromod-data-logging-carrier-board-hookup-guide
|
||||||
|
Insert the Artemis Processor into the MicroMod Data Logging Carrier Board and secure with the screw.
|
||||||
|
Connect your GNSS breakout to the Carrier Board using a Qwiic cable.
|
||||||
|
Connect an antenna to your GNSS board if required.
|
||||||
|
Insert a formatted micro-SD card into the socket on the Carrier Board.
|
||||||
|
Connect the Carrier Board to your computer using a USB-C cable.
|
||||||
|
Ensure you have the SparkFun Apollo3 boards installed: http://boardsmanager/All#SparkFun_Apollo3
|
||||||
|
This code has been tested using version 1.2.1 of the Apollo3 boards on Arduino IDE 1.8.13.
|
||||||
|
Select "SparkFun Artemis MicroMod" as the board type.
|
||||||
|
Press upload to upload the code onto the Artemis.
|
||||||
|
Open the Serial Monitor at 115200 baud to see the output.
|
||||||
|
|
||||||
|
To minimise I2C bus errors, it is a good idea to open the I2C pull-up split pad links on
|
||||||
|
both the MicroMod Data Logging Carrier Board and the u-blox module breakout.
|
||||||
|
|
||||||
|
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
|
||||||
|
ZOE-M8Q: https://www.sparkfun.com/products/15193
|
||||||
|
SAM-M8Q: https://www.sparkfun.com/products/15210
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <SD.h>
|
||||||
|
#include <Wire.h> //Needed for I2C to GNSS
|
||||||
|
|
||||||
|
#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;
|
||||||
|
|
||||||
|
File myFile; //File that all GNSS data is written to
|
||||||
|
|
||||||
|
#define sdChipSelect CS //Primary SPI Chip Select is CS for the MicroMod Artemis Processor. Adjust for your processor if necessary.
|
||||||
|
|
||||||
|
#define sdWriteSize 512 // Write data to the SD card in blocks of 512 bytes
|
||||||
|
#define fileBufferSize 16384 // Allocate 16KBytes of RAM for UBX message storage
|
||||||
|
|
||||||
|
unsigned long lastPrint; // Record when the last Serial print took place
|
||||||
|
unsigned long bytesWritten = 0; // Record how many bytes have been written to SD card
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial); //Wait for user to open terminal
|
||||||
|
Serial.println("SparkFun u-blox Example");
|
||||||
|
|
||||||
|
pinMode(LED_BUILTIN, OUTPUT); // Flash LED_BUILTIN each time we write to the SD card
|
||||||
|
digitalWrite(LED_BUILTIN, LOW);
|
||||||
|
|
||||||
|
Wire.begin(); // Start I2C communication
|
||||||
|
|
||||||
|
#if defined(AM_PART_APOLLO3)
|
||||||
|
Wire.setPullups(0); // On the Artemis, we can disable the internal I2C pull-ups too to help reduce bus errors
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("Initializing SD card...");
|
||||||
|
|
||||||
|
// See if the card is present and can be initialized:
|
||||||
|
if (!SD.begin(sdChipSelect))
|
||||||
|
{
|
||||||
|
Serial.println("Card failed, or not present. Freezing...");
|
||||||
|
// don't do anything more:
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
Serial.println("SD card initialized.");
|
||||||
|
|
||||||
|
// Create or open a file called "PVT_NMEA.ubx" on the SD card.
|
||||||
|
// If the file already exists, the new data is appended to the end of the file.
|
||||||
|
myFile = SD.open("PVT_NMEA.ubx", FILE_WRITE);
|
||||||
|
if(!myFile)
|
||||||
|
{
|
||||||
|
Serial.println(F("Failed to create UBX data file! Freezing..."));
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//myGNSS.enableDebugging(); // Uncomment this line to enable lots of helpful GNSS debug messages on Serial
|
||||||
|
//myGNSS.enableDebugging(Serial, true); // Or, uncomment this line to enable only the important GNSS debug messages on Serial
|
||||||
|
|
||||||
|
//myGNSS.disableUBX7Fcheck(); // RAWX data can legitimately contain 0x7F. Uncomment this line to disable the "7F" check in checkUbloxI2C
|
||||||
|
|
||||||
|
// SD cards can occasionally 'hiccup' and a write takes much longer than usual. The buffer needs to be big enough
|
||||||
|
// to hold the backlog of data if/when this happens.
|
||||||
|
// getMaxFileBufferAvail will tell us the maximum number of bytes which the file buffer has contained.
|
||||||
|
myGNSS.setFileBufferSize(fileBufferSize); // setFileBufferSize must be called _before_ .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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uncomment the next line if you want to reset your module back to the default settings with 1Hz navigation rate
|
||||||
|
// This will (re)enable the standard NMEA messages too
|
||||||
|
// This will also disable any "auto" UBX messages that were enabled and saved by other examples and reduce the load on the I2C bus
|
||||||
|
//myGNSS.factoryDefault(); delay(5000);
|
||||||
|
|
||||||
|
myGNSS.setI2COutput(COM_TYPE_UBX | COM_TYPE_NMEA); //Set the I2C port to output both UBX and NMEA messages
|
||||||
|
|
||||||
|
//myGNSS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Optional: save (only) the communications port settings to flash and BBR
|
||||||
|
|
||||||
|
myGNSS.setNavigationFrequency(1); //Produce one navigation solution per second
|
||||||
|
|
||||||
|
myGNSS.setAutoPVT(true, false); // Enable automatic NAV PVT messages: without callback; without implicit update
|
||||||
|
myGNSS.logNAVPVT(); // Enable NAV PVT data logging
|
||||||
|
|
||||||
|
myGNSS.enableNMEAMessage(UBX_NMEA_GGA, COM_PORT_I2C, 1); // Ensure the GxGGA (Global positioning system fix data) message is enabled. Send every measurement.
|
||||||
|
myGNSS.enableNMEAMessage(UBX_NMEA_GSA, COM_PORT_I2C, 1); // Ensure the GxGSA (GNSS DOP and Active satellites) message is enabled. Send every measurement.
|
||||||
|
myGNSS.enableNMEAMessage(UBX_NMEA_GSV, COM_PORT_I2C, 1); // Ensure the GxGSV (GNSS satellites in view) message is enabled. Send every measurement.
|
||||||
|
|
||||||
|
myGNSS.setNMEALoggingMask(SFE_UBLOX_FILTER_NMEA_ALL); // Enable logging of all enabled NMEA messages
|
||||||
|
//myGNSS.setNMEALoggingMask(SFE_UBLOX_FILTER_NMEA_GGA | SFE_UBLOX_FILTER_NMEA_GSA); // Or we can, for example, log only GxGGA & GxGSA and ignore GxGSV
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||||
|
|
||||||
|
while (myGNSS.fileBufferAvailable() >= sdWriteSize) // Check to see if we have at least sdWriteSize waiting in the buffer
|
||||||
|
{
|
||||||
|
digitalWrite(LED_BUILTIN, HIGH); // Flash LED_BUILTIN each time we write to the SD card
|
||||||
|
|
||||||
|
uint8_t myBuffer[sdWriteSize]; // Create our own buffer to hold the data while we write it to SD card
|
||||||
|
|
||||||
|
myGNSS.extractFileBufferData((uint8_t *)&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
|
||||||
|
|
||||||
|
bytesWritten += sdWriteSize; // Update bytesWritten
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
digitalWrite(LED_BUILTIN, LOW); // Turn LED_BUILTIN off again
|
||||||
|
}
|
||||||
|
|
||||||
|
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||||
|
|
||||||
|
if (millis() > (lastPrint + 1000)) // Print bytesWritten once per second
|
||||||
|
{
|
||||||
|
Serial.print(F("The number of bytes written to SD card is ")); // Print how many bytes have been written to SD card
|
||||||
|
Serial.println(bytesWritten);
|
||||||
|
|
||||||
|
uint16_t maxBufferBytes = myGNSS.getMaxFileBufferAvail(); // Get how full the file buffer has been (not how full it is now)
|
||||||
|
|
||||||
|
//Serial.print(F("The maximum number of bytes which the file buffer has contained is: ")); // It is a fun thing to watch how full the buffer gets
|
||||||
|
//Serial.println(maxBufferBytes);
|
||||||
|
|
||||||
|
if (maxBufferBytes > ((fileBufferSize / 5) * 4)) // Warn the user if fileBufferSize was more than 80% full
|
||||||
|
{
|
||||||
|
Serial.println(F("Warning: the file buffer has been over 80% full. Some data may have been lost."));
|
||||||
|
}
|
||||||
|
|
||||||
|
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(LED_BUILTIN, HIGH); // Flash LED_BUILTIN while we write to the SD card
|
||||||
|
|
||||||
|
uint8_t myBuffer[sdWriteSize]; // Create our own buffer to hold the data while we write it to 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((uint8_t *)&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
|
||||||
|
|
||||||
|
bytesWritten += bytesToWrite; // Update bytesWritten
|
||||||
|
|
||||||
|
remainingBytes -= bytesToWrite; // Decrement remainingBytes
|
||||||
|
}
|
||||||
|
|
||||||
|
digitalWrite(LED_BUILTIN, LOW); // Turn LED_BUILTIN off
|
||||||
|
|
||||||
|
Serial.print(F("The total number of bytes written to SD card is ")); // Print how many bytes have been written to SD card
|
||||||
|
Serial.println(bytesWritten);
|
||||||
|
|
||||||
|
myFile.close(); // Close the data file
|
||||||
|
|
||||||
|
Serial.println(F("Logging stopped. Freezing..."));
|
||||||
|
while(1); // Do nothing more
|
||||||
|
}
|
||||||
|
|
||||||
|
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||||
|
}
|
||||||
-3
@@ -81,9 +81,6 @@ void setup()
|
|||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Another trick we can use is to mark the CFG RATE data as stale so we can be sure we read fresh data
|
|
||||||
myGNSS.packetUBXCFGRATE->moduleQueried.moduleQueried.all = 0; // Mark all of the CFG RATE data as stale
|
|
||||||
|
|
||||||
// Read and print the updated measurement rate and navigation rate
|
// Read and print the updated measurement rate and navigation rate
|
||||||
|
|
||||||
rate = myGNSS.getMeasurementRate(); //Get the measurement rate of this module
|
rate = myGNSS.getMeasurementRate(); //Get the measurement rate of this module
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
Getting leap second event info as SNTP Leap Indicator, time to a leap second event and the number of leap seconds since GPS epoch
|
||||||
|
By: UT2UH
|
||||||
|
Date: April 14th, 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 query a u-blox module for the leap second event info to cast to SNTP Leap Indicator enumeration.
|
||||||
|
We also turn off the NMEA output on the I2C port. This decreases the amount of I2C traffic dramatically.
|
||||||
|
|
||||||
|
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||||
|
|
||||||
|
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 <Wire.h> //Needed for I2C to GNSS
|
||||||
|
|
||||||
|
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||||
|
SFE_UBLOX_GNSS myGNSS;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LI_NO_WARNING, //Time leaping not scheduled
|
||||||
|
LI_LAST_MINUTE_61_SEC, //Last minute has 61 seconds
|
||||||
|
LI_LAST_MINUTE_59_SEC, //Last minute has 59 seconds
|
||||||
|
LI_ALARM_CONDITION //The NTP server's clock not synchronized
|
||||||
|
} ntp_LI_e;
|
||||||
|
|
||||||
|
|
||||||
|
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to u-blox module.
|
||||||
|
|
||||||
|
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)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uncomment the next line if you need to completely reset your module
|
||||||
|
//myGNSS.factoryDefault(); delay(5000); // Reset everything and wait while the module restarts
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
Serial.println("Compare Unix Epoch given with reference one from https://www.epochconverter.com/");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||||
|
//The module only responds when a new position is available
|
||||||
|
if (millis() - lastTime > 1000)
|
||||||
|
{
|
||||||
|
lastTime = millis(); //Update the timer
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
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);
|
||||||
|
int32_t timeToLeapSecEvent;
|
||||||
|
ntp_LI_e leapIndicator = (ntp_LI_e)myGNSS.getLeapIndicator(timeToLeapSecEvent);
|
||||||
|
Serial.print("NTP LI: ");
|
||||||
|
Serial.print(leapIndicator, DEC);
|
||||||
|
switch (leapIndicator){
|
||||||
|
case LI_NO_WARNING:
|
||||||
|
Serial.print(" - No event scheduled");
|
||||||
|
break;
|
||||||
|
case LI_LAST_MINUTE_61_SEC:
|
||||||
|
Serial.print(" - last minute will end at 23:60");
|
||||||
|
break;
|
||||||
|
case LI_LAST_MINUTE_59_SEC:
|
||||||
|
Serial.print(" - last minute will end at 23:58");
|
||||||
|
break;
|
||||||
|
case LI_ALARM_CONDITION:
|
||||||
|
default:
|
||||||
|
Serial.print(" - Unknown (clock not synchronized)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Serial.print(". Time to the next leap second event: ");
|
||||||
|
Serial.println(timeToLeapSecEvent, DEC);
|
||||||
|
|
||||||
|
sfe_ublox_ls_src_e leapSecSource;
|
||||||
|
Serial.print("Leap seconds since GPS Epoch (Jan 6th, 1980): ");
|
||||||
|
Serial.print(myGNSS.getCurrentLeapSeconds(leapSecSource), DEC);
|
||||||
|
switch (leapSecSource){
|
||||||
|
case SFE_UBLOX_LS_SRC_DEFAULT:
|
||||||
|
Serial.print(" - hardcoded");
|
||||||
|
break;
|
||||||
|
case SFE_UBLOX_LS_SRC_GLONASS:
|
||||||
|
Serial.print(" - derived from GPS and GLONASS time difference");
|
||||||
|
break;
|
||||||
|
case SFE_UBLOX_LS_SRC_GPS:
|
||||||
|
Serial.print(" - according to GPS");
|
||||||
|
break;
|
||||||
|
case SFE_UBLOX_LS_SRC_SBAS:
|
||||||
|
Serial.print(" - according to SBAS");
|
||||||
|
break;
|
||||||
|
case SFE_UBLOX_LS_SRC_BEIDOU:
|
||||||
|
Serial.print(" - according to BeiDou");
|
||||||
|
break;
|
||||||
|
case SFE_UBLOX_LS_SRC_GALILEO:
|
||||||
|
Serial.print(" - according to Galileo");
|
||||||
|
break;
|
||||||
|
case SFE_UBLOX_LS_SRC_AIDED:
|
||||||
|
Serial.print(" - last minute will end at 23:58");
|
||||||
|
break;
|
||||||
|
case SFE_UBLOX_LS_SRC_CONFIGURED:
|
||||||
|
Serial.print(" - as configured)");
|
||||||
|
break;
|
||||||
|
case SFE_UBLOX_LS_SRC_UNKNOWN:
|
||||||
|
default:
|
||||||
|
Serial.print(" - source unknown");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
@@ -45,6 +45,10 @@ void setup()
|
|||||||
Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing."));
|
Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing."));
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myGNSS.setProcessNMEAMask(SFE_UBLOX_FILTER_NMEA_ALL); // Make sure the library is passing all NMEA messages to processNMEA
|
||||||
|
|
||||||
|
myGNSS.setProcessNMEAMask(SFE_UBLOX_FILTER_NMEA_GGA); // Or, we can be kind to MicroNMEA and _only_ pass the GGA messages to it
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
@@ -60,12 +64,12 @@ void loop()
|
|||||||
Serial.println(latitude_mdeg / 1000000., 6);
|
Serial.println(latitude_mdeg / 1000000., 6);
|
||||||
Serial.print("Longitude (deg): ");
|
Serial.print("Longitude (deg): ");
|
||||||
Serial.println(longitude_mdeg / 1000000., 6);
|
Serial.println(longitude_mdeg / 1000000., 6);
|
||||||
|
|
||||||
|
nmea.clear(); // Clear the MicroNMEA storage to make sure we are getting fresh data
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Serial.print("No Fix - ");
|
Serial.println("Waiting for fresh data");
|
||||||
Serial.print("Num. satellites: ");
|
|
||||||
Serial.println(nmea.getNumSatellites());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delay(250); //Don't pound too hard on the I2C bus
|
delay(250); //Don't pound too hard on the I2C bus
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ UBX_NAV_HPPOSECEF_data_t KEYWORD1
|
|||||||
UBX_NAV_HPPOSLLH_data_t KEYWORD1
|
UBX_NAV_HPPOSLLH_data_t KEYWORD1
|
||||||
UBX_NAV_CLOCK_data_t KEYWORD1
|
UBX_NAV_CLOCK_data_t KEYWORD1
|
||||||
UBX_NAV_RELPOSNED_data_t KEYWORD1
|
UBX_NAV_RELPOSNED_data_t KEYWORD1
|
||||||
|
UBX_NAV_TIMELS_data_t KEYWORD1
|
||||||
|
|
||||||
UBX_RXM_SFRBX_data_t KEYWORD1
|
UBX_RXM_SFRBX_data_t KEYWORD1
|
||||||
UBX_RXM_RAWX_data_t KEYWORD1
|
UBX_RXM_RAWX_data_t KEYWORD1
|
||||||
@@ -264,6 +265,11 @@ initPacketUBXNAVCLOCK KEYWORD2
|
|||||||
flushNAVCLOCK KEYWORD2
|
flushNAVCLOCK KEYWORD2
|
||||||
logNAVCLOCK KEYWORD2
|
logNAVCLOCK KEYWORD2
|
||||||
|
|
||||||
|
getLeapSecondEvent KEYWORD2
|
||||||
|
getLeapIndicator KEYWORD2
|
||||||
|
getCurrentLeapSeconds KEYWORD2
|
||||||
|
initPacketUBXNAVTIMELS KEYWORD2
|
||||||
|
|
||||||
getSurveyStatus KEYWORD2
|
getSurveyStatus KEYWORD2
|
||||||
initPacketUBXNAVSVIN KEYWORD2
|
initPacketUBXNAVSVIN KEYWORD2
|
||||||
|
|
||||||
@@ -382,12 +388,18 @@ initPacketUBXHNRPVT KEYWORD2
|
|||||||
flushHNRPVT KEYWORD2
|
flushHNRPVT KEYWORD2
|
||||||
logHNRPVT KEYWORD2
|
logHNRPVT KEYWORD2
|
||||||
|
|
||||||
|
setNMEALoggingMask KEYWORD2
|
||||||
|
getNMEALoggingMask KEYWORD2
|
||||||
|
setProcessNMEAMask KEYWORD2
|
||||||
|
getProcessNMEAMask KEYWORD2
|
||||||
|
|
||||||
setNavigationFrequency KEYWORD2
|
setNavigationFrequency KEYWORD2
|
||||||
getNavigationFrequency KEYWORD2
|
getNavigationFrequency KEYWORD2
|
||||||
setMeasurementRate KEYWORD2
|
setMeasurementRate KEYWORD2
|
||||||
getMeasurementRate KEYWORD2
|
getMeasurementRate KEYWORD2
|
||||||
setNavigationRate KEYWORD2
|
setNavigationRate KEYWORD2
|
||||||
getNavigationRate KEYWORD2
|
getNavigationRate KEYWORD2
|
||||||
|
flushCFGRATE KEYWORD2
|
||||||
|
|
||||||
getGeometricDOP KEYWORD2
|
getGeometricDOP KEYWORD2
|
||||||
getPositionDOP KEYWORD2
|
getPositionDOP KEYWORD2
|
||||||
@@ -543,16 +555,41 @@ UBX_NMEA_GLQ LITERAL1
|
|||||||
UBX_NMEA_GNQ LITERAL1
|
UBX_NMEA_GNQ LITERAL1
|
||||||
UBX_NMEA_GNS LITERAL1
|
UBX_NMEA_GNS LITERAL1
|
||||||
UBX_NMEA_GPQ LITERAL1
|
UBX_NMEA_GPQ LITERAL1
|
||||||
|
UBX_NMEA_GQQ LITERAL1
|
||||||
UBX_NMEA_GRS LITERAL1
|
UBX_NMEA_GRS LITERAL1
|
||||||
UBX_NMEA_GSA LITERAL1
|
UBX_NMEA_GSA LITERAL1
|
||||||
UBX_NMEA_GST LITERAL1
|
UBX_NMEA_GST LITERAL1
|
||||||
UBX_NMEA_GSV LITERAL1
|
UBX_NMEA_GSV LITERAL1
|
||||||
|
UBX_NMEA_RLM LITERAL1
|
||||||
UBX_NMEA_RMC LITERAL1
|
UBX_NMEA_RMC LITERAL1
|
||||||
UBX_NMEA_TXT LITERAL1
|
UBX_NMEA_TXT LITERAL1
|
||||||
UBX_NMEA_VLW LITERAL1
|
UBX_NMEA_VLW LITERAL1
|
||||||
UBX_NMEA_VTG LITERAL1
|
UBX_NMEA_VTG LITERAL1
|
||||||
UBX_NMEA_ZDA LITERAL1
|
UBX_NMEA_ZDA LITERAL1
|
||||||
|
|
||||||
|
SFE_UBLOX_FILTER_NMEA_ALL LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_DTM LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GAQ LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GBQ LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GBS LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GGA LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GLL LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GLQ LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GNQ LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GNS LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GPQ LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GQQ LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GRS LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GSA LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GST LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GSV LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_RLM LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_RMC LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_TXT LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_VLW LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_VTG LITERAL1
|
||||||
|
SFE_UBLOX_FILTER_NMEA_ZDA LITERAL1
|
||||||
|
|
||||||
UBX_NAV_ATT LITERAL1
|
UBX_NAV_ATT LITERAL1
|
||||||
UBX_NAV_CLOCK LITERAL1
|
UBX_NAV_CLOCK LITERAL1
|
||||||
UBX_NAV_DOP LITERAL1
|
UBX_NAV_DOP LITERAL1
|
||||||
@@ -566,6 +603,7 @@ UBX_NAV_RELPOSNED LITERAL1
|
|||||||
UBX_NAV_RESETODO LITERAL1
|
UBX_NAV_RESETODO LITERAL1
|
||||||
UBX_NAV_STATUS LITERAL1
|
UBX_NAV_STATUS LITERAL1
|
||||||
UBX_NAV_SVIN LITERAL1
|
UBX_NAV_SVIN LITERAL1
|
||||||
|
UBX_NAV_TIMELS LITERAL1
|
||||||
UBX_NAV_VELECEF LITERAL1
|
UBX_NAV_VELECEF LITERAL1
|
||||||
UBX_NAV_VELNED LITERAL1
|
UBX_NAV_VELNED LITERAL1
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
name=SparkFun u-blox GNSS Arduino Library
|
name=SparkFun u-blox GNSS Arduino Library
|
||||||
version=2.0.5
|
version=2.0.6
|
||||||
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 and Serial Communication with u-blox GNSS modules<br/><br/>
|
sentence=Library for I2C and Serial Communication with u-blox GNSS modules<br/><br/>
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ SFE_UBLOX_GNSS::SFE_UBLOX_GNSS(void)
|
|||||||
pinMode((uint8_t)debugPin, OUTPUT);
|
pinMode((uint8_t)debugPin, OUTPUT);
|
||||||
digitalWrite((uint8_t)debugPin, HIGH);
|
digitalWrite((uint8_t)debugPin, HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_logNMEA.all = 0; // Default to passing no NMEA messages to the file buffer
|
||||||
|
_processNMEA.all = SFE_UBLOX_FILTER_NMEA_ALL; // Default to passing all NMEA messages to processNMEA
|
||||||
}
|
}
|
||||||
|
|
||||||
//Stop all automatic message processing. Free all used RAM
|
//Stop all automatic message processing. Free all used RAM
|
||||||
@@ -83,6 +86,12 @@ void SFE_UBLOX_GNSS::end(void)
|
|||||||
currentGeofenceParams = NULL; // Redundant?
|
currentGeofenceParams = NULL; // Redundant?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (packetUBXNAVTIMELS != NULL)
|
||||||
|
{
|
||||||
|
delete[] packetUBXNAVTIMELS;
|
||||||
|
packetUBXNAVTIMELS = NULL; // Redundant?
|
||||||
|
}
|
||||||
|
|
||||||
if (packetUBXNAVPOSECEF != NULL)
|
if (packetUBXNAVPOSECEF != NULL)
|
||||||
{
|
{
|
||||||
if (packetUBXNAVPOSECEF->callbackData != NULL)
|
if (packetUBXNAVPOSECEF->callbackData != NULL)
|
||||||
@@ -789,6 +798,9 @@ boolean SFE_UBLOX_GNSS::checkAutomatic(uint8_t Class, uint8_t ID)
|
|||||||
case UBX_NAV_CLOCK:
|
case UBX_NAV_CLOCK:
|
||||||
if (packetUBXNAVCLOCK != NULL) result = true;
|
if (packetUBXNAVCLOCK != NULL) result = true;
|
||||||
break;
|
break;
|
||||||
|
case UBX_NAV_TIMELS:
|
||||||
|
if (packetUBXNAVTIMELS != NULL) result = true;
|
||||||
|
break;
|
||||||
case UBX_NAV_SVIN:
|
case UBX_NAV_SVIN:
|
||||||
if (packetUBXNAVSVIN != NULL) result = true;
|
if (packetUBXNAVSVIN != NULL) result = true;
|
||||||
break;
|
break;
|
||||||
@@ -916,6 +928,9 @@ uint16_t SFE_UBLOX_GNSS::getMaxPayloadSize(uint8_t Class, uint8_t ID)
|
|||||||
case UBX_NAV_CLOCK:
|
case UBX_NAV_CLOCK:
|
||||||
maxSize = UBX_NAV_CLOCK_LEN;
|
maxSize = UBX_NAV_CLOCK_LEN;
|
||||||
break;
|
break;
|
||||||
|
case UBX_NAV_TIMELS:
|
||||||
|
maxSize = UBX_NAV_TIMELS_LEN;
|
||||||
|
break;
|
||||||
case UBX_NAV_SVIN:
|
case UBX_NAV_SVIN:
|
||||||
maxSize = UBX_NAV_SVIN_LEN;
|
maxSize = UBX_NAV_SVIN_LEN;
|
||||||
break;
|
break;
|
||||||
@@ -1020,6 +1035,7 @@ void SFE_UBLOX_GNSS::process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t r
|
|||||||
}
|
}
|
||||||
else if (incoming == '$')
|
else if (incoming == '$')
|
||||||
{
|
{
|
||||||
|
nmeaByteCounter = 0; // Reset the NMEA byte counter
|
||||||
currentSentence = NMEA;
|
currentSentence = NMEA;
|
||||||
}
|
}
|
||||||
else if (incoming == 0xD3) //RTCM frames start with 0xD3
|
else if (incoming == 0xD3) //RTCM frames start with 0xD3
|
||||||
@@ -1241,9 +1257,58 @@ void SFE_UBLOX_GNSS::process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t r
|
|||||||
//Finally, increment the frame counter
|
//Finally, increment the frame counter
|
||||||
ubxFrameCounter++;
|
ubxFrameCounter++;
|
||||||
}
|
}
|
||||||
else if (currentSentence == NMEA)
|
else if (currentSentence == NMEA) // Process incoming NMEA mesages. Selectively log if desired.
|
||||||
{
|
{
|
||||||
processNMEA(incoming); //Process each NMEA character
|
if ((nmeaByteCounter == 0) && (incoming != '$'))
|
||||||
|
{
|
||||||
|
currentSentence = NONE; //Something went wrong. Reset. (Almost certainly redundant!)
|
||||||
|
}
|
||||||
|
else if ((nmeaByteCounter == 1) && (incoming != 'G'))
|
||||||
|
{
|
||||||
|
currentSentence = NONE; //Something went wrong. Reset.
|
||||||
|
}
|
||||||
|
else if ((nmeaByteCounter >= 0) && (nmeaByteCounter <= 5))
|
||||||
|
{
|
||||||
|
nmeaAddressField[nmeaByteCounter] = incoming; // Store the start character and NMEA address field
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nmeaByteCounter == 5)
|
||||||
|
{
|
||||||
|
// We've just received the end of the address field. Check if it is selected for logging
|
||||||
|
if (logThisNMEA())
|
||||||
|
{
|
||||||
|
storeFileBytes(&nmeaAddressField[0], 6); // Add start character and address field to the file buffer
|
||||||
|
}
|
||||||
|
// Check if it should be passed to processNMEA
|
||||||
|
if (processThisNMEA())
|
||||||
|
{
|
||||||
|
processNMEA(nmeaAddressField[0]); //Process the start character and address field
|
||||||
|
processNMEA(nmeaAddressField[1]);
|
||||||
|
processNMEA(nmeaAddressField[2]);
|
||||||
|
processNMEA(nmeaAddressField[3]);
|
||||||
|
processNMEA(nmeaAddressField[4]);
|
||||||
|
processNMEA(nmeaAddressField[5]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((nmeaByteCounter > 5) || (nmeaByteCounter < 0)) // Should we add incoming to the file buffer and/or pass it to processNMEA?
|
||||||
|
{
|
||||||
|
if (logThisNMEA())
|
||||||
|
storeFileBytes(&incoming, 1); // Add incoming to the file buffer
|
||||||
|
if (processThisNMEA())
|
||||||
|
processNMEA(incoming); // Pass incoming to processNMEA
|
||||||
|
}
|
||||||
|
|
||||||
|
if (incoming == '*')
|
||||||
|
nmeaByteCounter = -5; // We are expecting * plus two checksum bytes plus CR and LF
|
||||||
|
|
||||||
|
nmeaByteCounter++; // Increment the byte counter
|
||||||
|
|
||||||
|
if (nmeaByteCounter == maxNMEAByteCount) // Check if we have processed too many bytes
|
||||||
|
currentSentence = NONE; //Something went wrong. Reset.
|
||||||
|
|
||||||
|
if (nmeaByteCounter == 0) // Check if we are done
|
||||||
|
currentSentence = NONE; // All done!
|
||||||
}
|
}
|
||||||
else if (currentSentence == RTCM)
|
else if (currentSentence == RTCM)
|
||||||
{
|
{
|
||||||
@@ -1251,6 +1316,68 @@ void SFE_UBLOX_GNSS::process(uint8_t incoming, ubxPacket *incomingUBX, uint8_t r
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PRIVATE: Return true if we should add this NMEA message to the file buffer for logging
|
||||||
|
boolean SFE_UBLOX_GNSS::logThisNMEA()
|
||||||
|
{
|
||||||
|
if (_logNMEA.bits.all == 1) return (true);
|
||||||
|
if ((nmeaAddressField[3] == 'D') && (nmeaAddressField[4] == 'T') && (nmeaAddressField[5] == 'M') && (_logNMEA.bits.UBX_NMEA_DTM == 1)) return (true);
|
||||||
|
if (nmeaAddressField[3] == 'G')
|
||||||
|
{
|
||||||
|
if ((nmeaAddressField[4] == 'A') && (nmeaAddressField[5] == 'Q') && (_logNMEA.bits.UBX_NMEA_GAQ == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'B') && (nmeaAddressField[5] == 'Q') && (_logNMEA.bits.UBX_NMEA_GBQ == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'B') && (nmeaAddressField[5] == 'S') && (_logNMEA.bits.UBX_NMEA_GBS == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'G') && (nmeaAddressField[5] == 'A') && (_logNMEA.bits.UBX_NMEA_GGA == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'L') && (_logNMEA.bits.UBX_NMEA_GLL == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'Q') && (_logNMEA.bits.UBX_NMEA_GLQ == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'N') && (nmeaAddressField[5] == 'Q') && (_logNMEA.bits.UBX_NMEA_GNQ == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'N') && (nmeaAddressField[5] == 'S') && (_logNMEA.bits.UBX_NMEA_GNS == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'P') && (nmeaAddressField[5] == 'Q') && (_logNMEA.bits.UBX_NMEA_GPQ == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'Q') && (nmeaAddressField[5] == 'Q') && (_logNMEA.bits.UBX_NMEA_GQQ == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'R') && (nmeaAddressField[5] == 'S') && (_logNMEA.bits.UBX_NMEA_GRS == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'A') && (_logNMEA.bits.UBX_NMEA_GSA == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'T') && (_logNMEA.bits.UBX_NMEA_GST == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'V') && (_logNMEA.bits.UBX_NMEA_GSV == 1)) return (true);
|
||||||
|
}
|
||||||
|
if ((nmeaAddressField[3] == 'R') && (nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'M') && (_logNMEA.bits.UBX_NMEA_RLM == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[3] == 'R') && (nmeaAddressField[4] == 'M') && (nmeaAddressField[5] == 'C') && (_logNMEA.bits.UBX_NMEA_RMC == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[3] == 'T') && (nmeaAddressField[4] == 'X') && (nmeaAddressField[5] == 'T') && (_logNMEA.bits.UBX_NMEA_TXT == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[3] == 'V') && (nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'W') && (_logNMEA.bits.UBX_NMEA_VLW == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[3] == 'V') && (nmeaAddressField[4] == 'T') && (nmeaAddressField[5] == 'G') && (_logNMEA.bits.UBX_NMEA_VTG == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[3] == 'Z') && (nmeaAddressField[4] == 'D') && (nmeaAddressField[5] == 'A') && (_logNMEA.bits.UBX_NMEA_ZDA == 1)) return (true);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PRIVATE: Return true if we should pass this NMEA message to processNMEA
|
||||||
|
boolean SFE_UBLOX_GNSS::processThisNMEA()
|
||||||
|
{
|
||||||
|
if (_processNMEA.bits.all == 1) return (true);
|
||||||
|
if ((nmeaAddressField[3] == 'D') && (nmeaAddressField[4] == 'T') && (nmeaAddressField[5] == 'M') && (_processNMEA.bits.UBX_NMEA_DTM == 1)) return (true);
|
||||||
|
if (nmeaAddressField[3] == 'G')
|
||||||
|
{
|
||||||
|
if ((nmeaAddressField[4] == 'A') && (nmeaAddressField[5] == 'Q') && (_processNMEA.bits.UBX_NMEA_GAQ == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'B') && (nmeaAddressField[5] == 'Q') && (_processNMEA.bits.UBX_NMEA_GBQ == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'B') && (nmeaAddressField[5] == 'S') && (_processNMEA.bits.UBX_NMEA_GBS == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'G') && (nmeaAddressField[5] == 'A') && (_processNMEA.bits.UBX_NMEA_GGA == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'L') && (_processNMEA.bits.UBX_NMEA_GLL == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'Q') && (_processNMEA.bits.UBX_NMEA_GLQ == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'N') && (nmeaAddressField[5] == 'Q') && (_processNMEA.bits.UBX_NMEA_GNQ == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'N') && (nmeaAddressField[5] == 'S') && (_processNMEA.bits.UBX_NMEA_GNS == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'P') && (nmeaAddressField[5] == 'Q') && (_processNMEA.bits.UBX_NMEA_GPQ == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'Q') && (nmeaAddressField[5] == 'Q') && (_processNMEA.bits.UBX_NMEA_GQQ == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'R') && (nmeaAddressField[5] == 'S') && (_processNMEA.bits.UBX_NMEA_GRS == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'A') && (_processNMEA.bits.UBX_NMEA_GSA == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'T') && (_processNMEA.bits.UBX_NMEA_GST == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[4] == 'S') && (nmeaAddressField[5] == 'V') && (_processNMEA.bits.UBX_NMEA_GSV == 1)) return (true);
|
||||||
|
}
|
||||||
|
if ((nmeaAddressField[3] == 'R') && (nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'M') && (_processNMEA.bits.UBX_NMEA_RLM == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[3] == 'R') && (nmeaAddressField[4] == 'M') && (nmeaAddressField[5] == 'C') && (_processNMEA.bits.UBX_NMEA_RMC == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[3] == 'T') && (nmeaAddressField[4] == 'X') && (nmeaAddressField[5] == 'T') && (_processNMEA.bits.UBX_NMEA_TXT == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[3] == 'V') && (nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'W') && (_processNMEA.bits.UBX_NMEA_VLW == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[3] == 'V') && (nmeaAddressField[4] == 'T') && (nmeaAddressField[5] == 'G') && (_processNMEA.bits.UBX_NMEA_VTG == 1)) return (true);
|
||||||
|
if ((nmeaAddressField[3] == 'Z') && (nmeaAddressField[4] == 'D') && (nmeaAddressField[5] == 'A') && (_processNMEA.bits.UBX_NMEA_ZDA == 1)) return (true);
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
//This is the default or generic NMEA processor. We're only going to pipe the data to serial port so we can see it.
|
//This is the default or generic NMEA processor. We're only going to pipe the data to serial port so we can see it.
|
||||||
//User could overwrite this function to pipe characters to nmea.process(c) of tinyGPS or MicroNMEA
|
//User could overwrite this function to pipe characters to nmea.process(c) of tinyGPS or MicroNMEA
|
||||||
//Or user could pipe each character to a buffer, radio, etc.
|
//Or user could pipe each character to a buffer, radio, etc.
|
||||||
@@ -1945,6 +2072,26 @@ void SFE_UBLOX_GNSS::processUBXpacket(ubxPacket *msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (msg->id == UBX_NAV_TIMELS && msg->len == UBX_NAV_TIMELS_LEN)
|
||||||
|
{
|
||||||
|
//Parse various byte fields into storage - but only if we have memory allocated for it
|
||||||
|
if (packetUBXNAVTIMELS != NULL)
|
||||||
|
{
|
||||||
|
packetUBXNAVTIMELS->data.iTOW = extractLong(msg, 0);
|
||||||
|
packetUBXNAVTIMELS->data.version = extractByte(msg, 4);
|
||||||
|
packetUBXNAVTIMELS->data.srcOfCurrLs = extractByte(msg, 8);
|
||||||
|
packetUBXNAVTIMELS->data.currLs = extractSignedChar(msg, 9);
|
||||||
|
packetUBXNAVTIMELS->data.srcOfLsChange = extractByte(msg, 10);
|
||||||
|
packetUBXNAVTIMELS->data.lsChange = extractSignedChar(msg, 11);
|
||||||
|
packetUBXNAVTIMELS->data.timeToLsEvent = extractSignedLong(msg, 12);
|
||||||
|
packetUBXNAVTIMELS->data.dateOfLsGpsWn = extractInt(msg, 16);
|
||||||
|
packetUBXNAVTIMELS->data.dateOfLsGpsDn = extractInt(msg, 18);
|
||||||
|
packetUBXNAVTIMELS->data.valid.all = extractSignedChar(msg, 23);
|
||||||
|
|
||||||
|
//Mark all datums as fresh (not read before)
|
||||||
|
packetUBXNAVTIMELS->moduleQueried.moduleQueried.all = 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (msg->id == UBX_NAV_SVIN && msg->len == UBX_NAV_SVIN_LEN)
|
else if (msg->id == UBX_NAV_SVIN && msg->len == UBX_NAV_SVIN_LEN)
|
||||||
{
|
{
|
||||||
//Parse various byte fields into storage - but only if we have memory allocated for it
|
//Parse various byte fields into storage - but only if we have memory allocated for it
|
||||||
@@ -6858,6 +7005,53 @@ void SFE_UBLOX_GNSS::logNAVCLOCK(boolean enabled)
|
|||||||
packetUBXNAVCLOCK->automaticFlags.flags.bits.addToFileBuffer = (uint8_t)enabled;
|
packetUBXNAVCLOCK->automaticFlags.flags.bits.addToFileBuffer = (uint8_t)enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ***** NAV TIMELS automatic support
|
||||||
|
|
||||||
|
//Reads leap second event information and sets the global variables
|
||||||
|
//for future leap second change and number of leap seconds since GPS epoch
|
||||||
|
//Returns true if commands was successful
|
||||||
|
boolean SFE_UBLOX_GNSS::getLeapSecondEvent(uint16_t maxWait)
|
||||||
|
{
|
||||||
|
if (packetUBXNAVTIMELS == NULL) initPacketUBXNAVTIMELS(); //Check that RAM has been allocated for the TIMELS data
|
||||||
|
if (packetUBXNAVTIMELS == NULL) // Abort if the RAM allocation failed
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
packetCfg.cls = UBX_CLASS_NAV;
|
||||||
|
packetCfg.id = UBX_NAV_TIMELS;
|
||||||
|
packetCfg.len = 0;
|
||||||
|
packetCfg.startingSpot = 0;
|
||||||
|
|
||||||
|
//The data is parsed as part of processing the response
|
||||||
|
sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait);
|
||||||
|
|
||||||
|
if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED)
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN)
|
||||||
|
{
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PRIVATE: Allocate RAM for packetUBXNAVTIMELS and initialize it
|
||||||
|
boolean SFE_UBLOX_GNSS::initPacketUBXNAVTIMELS()
|
||||||
|
{
|
||||||
|
packetUBXNAVTIMELS = new UBX_NAV_TIMELS_t; //Allocate RAM for the main struct
|
||||||
|
if (packetUBXNAVTIMELS == NULL)
|
||||||
|
{
|
||||||
|
if ((_printDebug == true) || (_printLimitedDebug == true)) // This is important. Print this if doing limited debugging
|
||||||
|
_debugSerial->println(F("initPacketUBXNAVTIMELS: PANIC! RAM allocation failed!"));
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
packetUBXNAVTIMELS->automaticFlags.flags.all = 0;
|
||||||
|
packetUBXNAVTIMELS->callbackPointer = NULL;
|
||||||
|
packetUBXNAVTIMELS->callbackData = NULL;
|
||||||
|
packetUBXNAVTIMELS->moduleQueried.moduleQueried.all = 0;
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
// ***** NAV SVIN automatic support
|
// ***** NAV SVIN automatic support
|
||||||
|
|
||||||
//Reads survey in status and sets the global variables
|
//Reads survey in status and sets the global variables
|
||||||
@@ -7387,38 +7581,25 @@ boolean SFE_UBLOX_GNSS::getNavigationFrequencyInternal(uint16_t maxWait)
|
|||||||
if (packetUBXCFGRATE == NULL) //Bail if the RAM allocation failed
|
if (packetUBXCFGRATE == NULL) //Bail if the RAM allocation failed
|
||||||
return (false);
|
return (false);
|
||||||
|
|
||||||
if (packetUBXCFGRATE->automaticFlags.flags.bits.automatic && packetUBXCFGRATE->automaticFlags.flags.bits.implicitUpdate)
|
// The CFG RATE message will never be produced automatically - that would be pointless.
|
||||||
|
// There is no setAutoCFGRATE function. We always need to poll explicitly.
|
||||||
|
packetCfg.cls = UBX_CLASS_CFG;
|
||||||
|
packetCfg.id = UBX_CFG_RATE;
|
||||||
|
packetCfg.len = 0;
|
||||||
|
packetCfg.startingSpot = 0;
|
||||||
|
|
||||||
|
//The data is parsed as part of processing the response
|
||||||
|
sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait);
|
||||||
|
|
||||||
|
if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED)
|
||||||
|
return (true);
|
||||||
|
|
||||||
|
if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN)
|
||||||
{
|
{
|
||||||
//The GPS is automatically reporting, we just check whether we got unread data
|
return (true);
|
||||||
checkUbloxInternal(&packetCfg, UBX_CLASS_CFG, UBX_CFG_RATE);
|
|
||||||
return packetUBXCFGRATE->moduleQueried.moduleQueried.bits.all;
|
|
||||||
}
|
}
|
||||||
else if (packetUBXCFGRATE->automaticFlags.flags.bits.automatic && !packetUBXCFGRATE->automaticFlags.flags.bits.implicitUpdate)
|
|
||||||
{
|
|
||||||
//Someone else has to call checkUblox for us...
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//The GPS is not automatically reporting navigation rate so we have to poll explicitly
|
|
||||||
packetCfg.cls = UBX_CLASS_CFG;
|
|
||||||
packetCfg.id = UBX_CFG_RATE;
|
|
||||||
packetCfg.len = 0;
|
|
||||||
packetCfg.startingSpot = 0;
|
|
||||||
|
|
||||||
//The data is parsed as part of processing the response
|
return (false);
|
||||||
sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait);
|
|
||||||
|
|
||||||
if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED)
|
|
||||||
return (true);
|
|
||||||
|
|
||||||
if (retVal == SFE_UBLOX_STATUS_DATA_OVERWRITTEN)
|
|
||||||
{
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PRIVATE: Allocate RAM for packetUBXCFGRATE and initialize it
|
// PRIVATE: Allocate RAM for packetUBXCFGRATE and initialize it
|
||||||
@@ -7431,10 +7612,10 @@ boolean SFE_UBLOX_GNSS::initPacketUBXCFGRATE()
|
|||||||
_debugSerial->println(F("initPacketUBXCFGRATE: PANIC! RAM allocation failed!"));
|
_debugSerial->println(F("initPacketUBXCFGRATE: PANIC! RAM allocation failed!"));
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
packetUBXCFGRATE->automaticFlags.flags.all = 0;
|
packetUBXCFGRATE->automaticFlags.flags.all = 0; // Redundant
|
||||||
packetUBXCFGRATE->callbackPointer = NULL;
|
packetUBXCFGRATE->callbackPointer = NULL; // Redundant
|
||||||
packetUBXCFGRATE->callbackData = NULL;
|
packetUBXCFGRATE->callbackData = NULL; // Redundant
|
||||||
packetUBXCFGRATE->moduleQueried.moduleQueried.all = 0;
|
packetUBXCFGRATE->moduleQueried.moduleQueried.all = 0; // Mark all data as stale/read
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9086,6 +9267,29 @@ void SFE_UBLOX_GNSS::logHNRPVT(boolean enabled)
|
|||||||
packetUBXHNRPVT->automaticFlags.flags.bits.addToFileBuffer = (uint8_t)enabled;
|
packetUBXHNRPVT->automaticFlags.flags.bits.addToFileBuffer = (uint8_t)enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ***** Helper Functions for NMEA Logging / Processing
|
||||||
|
|
||||||
|
// Log selected NMEA messages to file buffer - if the messages are enabled and if the file buffer exists
|
||||||
|
// User needs to call setFileBufferSize before .begin
|
||||||
|
void SFE_UBLOX_GNSS::setNMEALoggingMask(uint32_t messages)
|
||||||
|
{
|
||||||
|
_logNMEA.all = messages;
|
||||||
|
}
|
||||||
|
uint32_t SFE_UBLOX_GNSS::getNMEALoggingMask()
|
||||||
|
{
|
||||||
|
return (_logNMEA.all);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass selected NMEA messages to processNMEA
|
||||||
|
void SFE_UBLOX_GNSS::setProcessNMEAMask(uint32_t messages)
|
||||||
|
{
|
||||||
|
_processNMEA.all = messages;
|
||||||
|
}
|
||||||
|
uint32_t SFE_UBLOX_GNSS::getProcessNMEAMask()
|
||||||
|
{
|
||||||
|
return (_processNMEA.all);
|
||||||
|
}
|
||||||
|
|
||||||
// ***** CFG RATE Helper Functions
|
// ***** CFG RATE Helper Functions
|
||||||
|
|
||||||
//Set the rate at which the module will give us an updated navigation solution
|
//Set the rate at which the module will give us an updated navigation solution
|
||||||
@@ -9114,7 +9318,11 @@ boolean SFE_UBLOX_GNSS::setNavigationFrequency(uint8_t navFreq, uint16_t maxWait
|
|||||||
payloadCfg[0] = measurementRate & 0xFF; //measRate LSB
|
payloadCfg[0] = measurementRate & 0xFF; //measRate LSB
|
||||||
payloadCfg[1] = measurementRate >> 8; //measRate MSB
|
payloadCfg[1] = measurementRate >> 8; //measRate MSB
|
||||||
|
|
||||||
return ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
|
boolean result = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
|
||||||
|
|
||||||
|
flushCFGRATE(); // Mark the polled measurement and navigation rate data as stale
|
||||||
|
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get the rate at which the module is outputting nav solutions
|
//Get the rate at which the module is outputting nav solutions
|
||||||
@@ -9155,7 +9363,11 @@ boolean SFE_UBLOX_GNSS::setMeasurementRate(uint16_t rate, uint16_t maxWait)
|
|||||||
payloadCfg[0] = rate & 0xFF; //measRate LSB
|
payloadCfg[0] = rate & 0xFF; //measRate LSB
|
||||||
payloadCfg[1] = rate >> 8; //measRate MSB
|
payloadCfg[1] = rate >> 8; //measRate MSB
|
||||||
|
|
||||||
return ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
|
boolean result = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
|
||||||
|
|
||||||
|
flushCFGRATE(); // Mark the polled measurement and navigation rate data as stale
|
||||||
|
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Return the elapsed time between GNSS measurements in milliseconds, which defines the rate
|
//Return the elapsed time between GNSS measurements in milliseconds, which defines the rate
|
||||||
@@ -9190,7 +9402,11 @@ boolean SFE_UBLOX_GNSS::setNavigationRate(uint16_t rate, uint16_t maxWait)
|
|||||||
payloadCfg[2] = rate & 0xFF; //navRate LSB
|
payloadCfg[2] = rate & 0xFF; //navRate LSB
|
||||||
payloadCfg[3] = rate >> 8; //navRate MSB
|
payloadCfg[3] = rate >> 8; //navRate MSB
|
||||||
|
|
||||||
return ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
|
boolean result = ((sendCommand(&packetCfg, maxWait)) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
|
||||||
|
|
||||||
|
flushCFGRATE(); // Mark the polled measurement and navigation rate data as stale
|
||||||
|
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Return the ratio between the number of measurements and the number of navigation solutions. Unit is cycles
|
//Return the ratio between the number of measurements and the number of navigation solutions. Unit is cycles
|
||||||
@@ -9208,6 +9424,13 @@ uint16_t SFE_UBLOX_GNSS::getNavigationRate(uint16_t maxWait)
|
|||||||
return (packetUBXCFGRATE->data.navRate);
|
return (packetUBXCFGRATE->data.navRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Mark the CFG RATE data as read/stale
|
||||||
|
void SFE_UBLOX_GNSS::flushCFGRATE()
|
||||||
|
{
|
||||||
|
if (packetUBXCFGRATE == NULL) return; // Bail if RAM has not been allocated (otherwise we could be writing anywhere!)
|
||||||
|
packetUBXCFGRATE->moduleQueried.moduleQueried.all = 0; //Mark all datums as stale (read before)
|
||||||
|
}
|
||||||
|
|
||||||
// ***** DOP Helper Functions
|
// ***** DOP Helper Functions
|
||||||
|
|
||||||
uint16_t SFE_UBLOX_GNSS::getGeometricDOP(uint16_t maxWait)
|
uint16_t SFE_UBLOX_GNSS::getGeometricDOP(uint16_t maxWait)
|
||||||
@@ -10160,6 +10383,45 @@ float SFE_UBLOX_GNSS::getSurveyInMeanAccuracy(uint16_t maxWait) // Returned as m
|
|||||||
return (((float)tempFloat) / 10000.0); //Convert 0.1mm to m
|
return (((float)tempFloat) / 10000.0); //Convert 0.1mm to m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ***** TIMELS Helper Functions
|
||||||
|
|
||||||
|
uint8_t SFE_UBLOX_GNSS::getLeapIndicator(int32_t& timeToLsEvent, uint16_t maxWait)
|
||||||
|
{
|
||||||
|
if (packetUBXNAVTIMELS == NULL) initPacketUBXNAVTIMELS(); //Check that RAM has been allocated for the TIMELS data
|
||||||
|
if (packetUBXNAVTIMELS == NULL) //Bail if the RAM allocation failed
|
||||||
|
return 3;
|
||||||
|
|
||||||
|
if (packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.validTimeToLsEvent == false)
|
||||||
|
getLeapSecondEvent(maxWait);
|
||||||
|
packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.validTimeToLsEvent = false; //Since we are about to give this to user, mark this data as stale
|
||||||
|
packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.lsChange = false;
|
||||||
|
packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.timeToLsEvent = false;
|
||||||
|
packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.all = false;
|
||||||
|
timeToLsEvent = packetUBXNAVTIMELS->data.timeToLsEvent;
|
||||||
|
// returns NTP Leap Indicator
|
||||||
|
// 0 -no warning
|
||||||
|
// 1 -last minute of the day has 61 seconds
|
||||||
|
// 2 -last minute of the day has 59 seconds
|
||||||
|
// 3 -unknown (clock unsynchronized)
|
||||||
|
return ((boolean)packetUBXNAVTIMELS->data.valid.bits.validTimeToLsEvent ? (uint8_t)(packetUBXNAVTIMELS->data.lsChange == -1 ? 2 : packetUBXNAVTIMELS->data.lsChange) : 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t SFE_UBLOX_GNSS::getCurrentLeapSeconds(sfe_ublox_ls_src_e& source, uint16_t maxWait)
|
||||||
|
{
|
||||||
|
if (packetUBXNAVTIMELS == NULL) initPacketUBXNAVTIMELS(); //Check that RAM has been allocated for the TIMELS data
|
||||||
|
if (packetUBXNAVTIMELS == NULL) //Bail if the RAM allocation failed
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.validCurrLs == false)
|
||||||
|
getLeapSecondEvent(maxWait);
|
||||||
|
packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.validCurrLs = false; //Since we are about to give this to user, mark this data as stale
|
||||||
|
packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.srcOfCurrLs = false;
|
||||||
|
packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.currLs = false;
|
||||||
|
packetUBXNAVTIMELS->moduleQueried.moduleQueried.bits.all = false;
|
||||||
|
source = ((sfe_ublox_ls_src_e)packetUBXNAVTIMELS->data.srcOfCurrLs);
|
||||||
|
return ((int8_t)packetUBXNAVTIMELS->data.currLs);
|
||||||
|
}
|
||||||
|
|
||||||
// ***** RELPOSNED Helper Functions and automatic support
|
// ***** RELPOSNED Helper Functions and automatic support
|
||||||
|
|
||||||
float SFE_UBLOX_GNSS::getRelPosN(uint16_t maxWait) // Returned as m
|
float SFE_UBLOX_GNSS::getRelPosN(uint16_t maxWait) // Returned as m
|
||||||
|
|||||||
@@ -99,6 +99,69 @@ typedef enum
|
|||||||
SFE_UBLOX_PACKET_PACKETAUTO
|
SFE_UBLOX_PACKET_PACKETAUTO
|
||||||
} sfe_ublox_packet_buffer_e;
|
} sfe_ublox_packet_buffer_e;
|
||||||
|
|
||||||
|
// Define a struct to allow selective logging / processing of NMEA messages
|
||||||
|
// Set the individual bits to pass the NMEA messages to the file buffer and/or processNMEA
|
||||||
|
// Setting bits.all will pass all messages to the file buffer and processNMEA
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_t all;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t all : 1;
|
||||||
|
uint32_t UBX_NMEA_DTM : 1;
|
||||||
|
uint32_t UBX_NMEA_GAQ : 1;
|
||||||
|
uint32_t UBX_NMEA_GBQ : 1;
|
||||||
|
uint32_t UBX_NMEA_GBS : 1;
|
||||||
|
uint32_t UBX_NMEA_GGA : 1;
|
||||||
|
uint32_t UBX_NMEA_GLL : 1;
|
||||||
|
uint32_t UBX_NMEA_GLQ : 1;
|
||||||
|
uint32_t UBX_NMEA_GNQ : 1;
|
||||||
|
uint32_t UBX_NMEA_GNS : 1;
|
||||||
|
uint32_t UBX_NMEA_GPQ : 1;
|
||||||
|
uint32_t UBX_NMEA_GQQ : 1;
|
||||||
|
uint32_t UBX_NMEA_GRS : 1;
|
||||||
|
uint32_t UBX_NMEA_GSA : 1;
|
||||||
|
uint32_t UBX_NMEA_GST : 1;
|
||||||
|
uint32_t UBX_NMEA_GSV : 1;
|
||||||
|
uint32_t UBX_NMEA_RLM : 1;
|
||||||
|
uint32_t UBX_NMEA_RMC : 1;
|
||||||
|
uint32_t UBX_NMEA_TXT : 1;
|
||||||
|
uint32_t UBX_NMEA_VLW : 1;
|
||||||
|
uint32_t UBX_NMEA_VTG : 1;
|
||||||
|
uint32_t UBX_NMEA_ZDA : 1;
|
||||||
|
} bits;
|
||||||
|
};
|
||||||
|
} sfe_ublox_nmea_filtering_t;
|
||||||
|
|
||||||
|
// Define an enum to make it easy to enable/disable selected NMEA messages for logging / processing
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
SFE_UBLOX_FILTER_NMEA_ALL = 0x00000001,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_DTM = 0x00000002,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GAQ = 0x00000004,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GBQ = 0x00000008,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GBS = 0x00000010,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GGA = 0x00000020,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GLL = 0x00000040,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GLQ = 0x00000080,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GNQ = 0x00000100,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GNS = 0x00000200,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GPQ = 0x00000400,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GQQ = 0x00000800,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GRS = 0x00001000,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GSA = 0x00002000,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GST = 0x00004000,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_GSV = 0x00008000,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_RLM = 0x00010000,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_RMC = 0x00020000,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_TXT = 0x00040000,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_VLW = 0x00080000,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_VTG = 0x00100000,
|
||||||
|
SFE_UBLOX_FILTER_NMEA_ZDA = 0x00200000
|
||||||
|
} sfe_ublox_nmea_filtering_e;
|
||||||
|
|
||||||
//Registers
|
//Registers
|
||||||
const uint8_t UBX_SYNCH_1 = 0xB5;
|
const uint8_t UBX_SYNCH_1 = 0xB5;
|
||||||
const uint8_t UBX_SYNCH_2 = 0x62;
|
const uint8_t UBX_SYNCH_2 = 0x62;
|
||||||
@@ -159,7 +222,7 @@ const uint8_t UBX_CFG_VALSET = 0x8A; //Used for config of higher version u-blox
|
|||||||
|
|
||||||
//Class: NMEA
|
//Class: NMEA
|
||||||
//The following are used to enable NMEA messages. Descriptions come from the NMEA messages overview in the ZED-F9P Interface Description
|
//The following are used to enable NMEA messages. Descriptions come from the NMEA messages overview in the ZED-F9P Interface Description
|
||||||
const uint8_t UBX_NMEA_MSB = 0xF0; //All NMEA enable commands have 0xF0 as MSB
|
const uint8_t UBX_NMEA_MSB = 0xF0; //All NMEA enable commands have 0xF0 as MSB. Equal to UBX_CLASS_NMEA
|
||||||
const uint8_t UBX_NMEA_DTM = 0x0A; //GxDTM (datum reference)
|
const uint8_t UBX_NMEA_DTM = 0x0A; //GxDTM (datum reference)
|
||||||
const uint8_t UBX_NMEA_GAQ = 0x45; //GxGAQ (poll a standard message (if the current talker ID is GA))
|
const uint8_t UBX_NMEA_GAQ = 0x45; //GxGAQ (poll a standard message (if the current talker ID is GA))
|
||||||
const uint8_t UBX_NMEA_GBQ = 0x44; //GxGBQ (poll a standard message (if the current Talker ID is GB))
|
const uint8_t UBX_NMEA_GBQ = 0x44; //GxGBQ (poll a standard message (if the current Talker ID is GB))
|
||||||
@@ -169,11 +232,13 @@ const uint8_t UBX_NMEA_GLL = 0x01; //GxGLL (latitude and long, whith time of pos
|
|||||||
const uint8_t UBX_NMEA_GLQ = 0x43; //GxGLQ (poll a standard message (if the current Talker ID is GL))
|
const uint8_t UBX_NMEA_GLQ = 0x43; //GxGLQ (poll a standard message (if the current Talker ID is GL))
|
||||||
const uint8_t UBX_NMEA_GNQ = 0x42; //GxGNQ (poll a standard message (if the current Talker ID is GN))
|
const uint8_t UBX_NMEA_GNQ = 0x42; //GxGNQ (poll a standard message (if the current Talker ID is GN))
|
||||||
const uint8_t UBX_NMEA_GNS = 0x0D; //GxGNS (GNSS fix data)
|
const uint8_t UBX_NMEA_GNS = 0x0D; //GxGNS (GNSS fix data)
|
||||||
const uint8_t UBX_NMEA_GPQ = 0x040; //GxGPQ (poll a standard message (if the current Talker ID is GP))
|
const uint8_t UBX_NMEA_GPQ = 0x40; //GxGPQ (poll a standard message (if the current Talker ID is GP))
|
||||||
|
const uint8_t UBX_NMEA_GQQ = 0x47; //GxGQQ (poll a standard message (if the current Talker ID is GQ))
|
||||||
const uint8_t UBX_NMEA_GRS = 0x06; //GxGRS (GNSS range residuals)
|
const uint8_t UBX_NMEA_GRS = 0x06; //GxGRS (GNSS range residuals)
|
||||||
const uint8_t UBX_NMEA_GSA = 0x02; //GxGSA (GNSS DOP and Active satellites)
|
const uint8_t UBX_NMEA_GSA = 0x02; //GxGSA (GNSS DOP and Active satellites)
|
||||||
const uint8_t UBX_NMEA_GST = 0x07; //GxGST (GNSS Pseudo Range Error Statistics)
|
const uint8_t UBX_NMEA_GST = 0x07; //GxGST (GNSS Pseudo Range Error Statistics)
|
||||||
const uint8_t UBX_NMEA_GSV = 0x03; //GxGSV (GNSS satellites in view)
|
const uint8_t UBX_NMEA_GSV = 0x03; //GxGSV (GNSS satellites in view)
|
||||||
|
const uint8_t UBX_NMEA_RLM = 0x0B; //GxRMC (Return link message (RLM))
|
||||||
const uint8_t UBX_NMEA_RMC = 0x04; //GxRMC (Recommended minimum data)
|
const uint8_t UBX_NMEA_RMC = 0x04; //GxRMC (Recommended minimum data)
|
||||||
const uint8_t UBX_NMEA_TXT = 0x41; //GxTXT (text transmission)
|
const uint8_t UBX_NMEA_TXT = 0x41; //GxTXT (text transmission)
|
||||||
const uint8_t UBX_NMEA_VLW = 0x0F; //GxVLW (dual ground/water distance)
|
const uint8_t UBX_NMEA_VLW = 0x0F; //GxVLW (dual ground/water distance)
|
||||||
@@ -407,6 +472,20 @@ enum sfe_ublox_gnss_ids_e
|
|||||||
SFE_UBLOX_GNSS_ID_GLONASS
|
SFE_UBLOX_GNSS_ID_GLONASS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The GNSS identifiers of leap second event info source - used by UBX-NAV-TIMELS
|
||||||
|
enum sfe_ublox_ls_src_e
|
||||||
|
{
|
||||||
|
SFE_UBLOX_LS_SRC_DEFAULT,
|
||||||
|
SFE_UBLOX_LS_SRC_GLONASS,
|
||||||
|
SFE_UBLOX_LS_SRC_GPS,
|
||||||
|
SFE_UBLOX_LS_SRC_SBAS,
|
||||||
|
SFE_UBLOX_LS_SRC_BEIDOU,
|
||||||
|
SFE_UBLOX_LS_SRC_GALILEO,
|
||||||
|
SFE_UBLOX_LS_SRC_AIDED,
|
||||||
|
SFE_UBLOX_LS_SRC_CONFIGURED,
|
||||||
|
SFE_UBLOX_LS_SRC_UNKNOWN = 255
|
||||||
|
};
|
||||||
|
|
||||||
#ifndef MAX_PAYLOAD_SIZE
|
#ifndef MAX_PAYLOAD_SIZE
|
||||||
// v2.0: keep this for backwards-compatibility, but this is largely superseded by setPacketCfgPayloadSize
|
// v2.0: keep this for backwards-compatibility, but this is largely superseded by setPacketCfgPayloadSize
|
||||||
#define MAX_PAYLOAD_SIZE 256 //We need ~220 bytes for getProtocolVersion on most ublox modules
|
#define MAX_PAYLOAD_SIZE 256 //We need ~220 bytes for getProtocolVersion on most ublox modules
|
||||||
@@ -580,15 +659,15 @@ public:
|
|||||||
boolean setPortOutput(uint8_t portID, uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure a given port to output UBX, NMEA, RTCM3 or a combination thereof
|
boolean setPortOutput(uint8_t portID, uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure a given port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||||
boolean setPortInput(uint8_t portID, uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure a given port to input UBX, NMEA, RTCM3 or a combination thereof
|
boolean setPortInput(uint8_t portID, uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure a given port to input UBX, NMEA, RTCM3 or a combination thereof
|
||||||
|
|
||||||
boolean setI2CAddress(uint8_t deviceAddress, uint16_t maxTime = defaultMaxWait); //Changes the I2C address of the u-blox module
|
boolean setI2CAddress(uint8_t deviceAddress, uint16_t maxTime = defaultMaxWait); //Changes the I2C address of the u-blox module
|
||||||
void setSerialRate(uint32_t baudrate, uint8_t uartPort = COM_PORT_UART1, uint16_t maxTime = defaultMaxWait); //Changes the serial baud rate of the u-blox module, uartPort should be COM_PORT_UART1/2
|
void setSerialRate(uint32_t baudrate, uint8_t uartPort = COM_PORT_UART1, uint16_t maxTime = defaultMaxWait); //Changes the serial baud rate of the u-blox module, uartPort should be COM_PORT_UART1/2
|
||||||
|
|
||||||
boolean setI2COutput(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure I2C port to output UBX, NMEA, RTCM3 or a combination thereof
|
boolean setI2COutput(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure I2C port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||||
boolean setUART1Output(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure UART1 port to output UBX, NMEA, RTCM3 or a combination thereof
|
boolean setUART1Output(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure UART1 port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||||
boolean setUART2Output(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure UART2 port to output UBX, NMEA, RTCM3 or a combination thereof
|
boolean setUART2Output(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure UART2 port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||||
boolean setUSBOutput(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure USB port to output UBX, NMEA, RTCM3 or a combination thereof
|
boolean setUSBOutput(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure USB port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||||
boolean setSPIOutput(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure SPI port to output UBX, NMEA, RTCM3 or a combination thereof
|
boolean setSPIOutput(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure SPI port to output UBX, NMEA, RTCM3 or a combination thereof
|
||||||
void setNMEAOutputPort(Stream &nmeaOutputPort); //Sets the internal variable for the port to direct NMEA characters to
|
void setNMEAOutputPort(Stream &nmeaOutputPort); //Sets the internal variable for the port to direct NMEA characters to
|
||||||
|
|
||||||
//Reset to defaults
|
//Reset to defaults
|
||||||
|
|
||||||
@@ -800,6 +879,9 @@ public:
|
|||||||
// Add "auto" support for NAV SVIN - to avoid needing 'global' storage
|
// Add "auto" support for NAV SVIN - to avoid needing 'global' storage
|
||||||
boolean getSurveyStatus(uint16_t maxWait); //Reads survey in status
|
boolean getSurveyStatus(uint16_t maxWait); //Reads survey in status
|
||||||
|
|
||||||
|
// Add "auto" support for NAV TIMELS - to avoid needing 'global' storage
|
||||||
|
boolean getLeapSecondEvent(uint16_t maxWait); //Reads leap second event info
|
||||||
|
|
||||||
boolean getRELPOSNED(uint16_t maxWait = defaultMaxWait); //Get Relative Positioning Information of the NED frame
|
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, 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 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
|
||||||
@@ -928,6 +1010,14 @@ public:
|
|||||||
void flushHNRPVT(); //Mark all the data as read/stale
|
void flushHNRPVT(); //Mark all the data as read/stale
|
||||||
void logHNRPVT(boolean enabled = true); // Log data to file buffer
|
void logHNRPVT(boolean enabled = true); // Log data to file buffer
|
||||||
|
|
||||||
|
// Helper functions for NMEA logging
|
||||||
|
void setNMEALoggingMask(uint32_t messages = SFE_UBLOX_FILTER_NMEA_ALL); // Add selected NMEA messages to file buffer - if enabled. Default to adding ALL messages to the file buffer
|
||||||
|
uint32_t getNMEALoggingMask(); // Return which NMEA messages are selected for logging to the file buffer - if enabled
|
||||||
|
|
||||||
|
// Helper functions to control which NMEA messages are passed to processNMEA
|
||||||
|
void setProcessNMEAMask(uint32_t messages = SFE_UBLOX_FILTER_NMEA_ALL); // Control which NMEA messages are passed to processNMEA. Default to passing ALL messages
|
||||||
|
uint32_t getProcessNMEAMask(); // Return which NMEA messages are passed to processNMEA
|
||||||
|
|
||||||
// Helper functions for CFG RATE
|
// Helper functions for CFG RATE
|
||||||
|
|
||||||
boolean setNavigationFrequency(uint8_t navFreq, uint16_t maxWait = defaultMaxWait); //Set the number of nav solutions sent per second
|
boolean setNavigationFrequency(uint8_t navFreq, uint16_t maxWait = defaultMaxWait); //Set the number of nav solutions sent per second
|
||||||
@@ -936,6 +1026,7 @@ public:
|
|||||||
uint16_t getMeasurementRate(uint16_t maxWait = defaultMaxWait); //Return the elapsed time between GNSS measurements in milliseconds
|
uint16_t getMeasurementRate(uint16_t maxWait = defaultMaxWait); //Return the elapsed time between GNSS measurements in milliseconds
|
||||||
boolean setNavigationRate(uint16_t rate, uint16_t maxWait = defaultMaxWait); //Set the ratio between the number of measurements and the number of navigation solutions. Unit is cycles. Max is 127
|
boolean setNavigationRate(uint16_t rate, uint16_t maxWait = defaultMaxWait); //Set the ratio between the number of measurements and the number of navigation solutions. Unit is cycles. Max is 127
|
||||||
uint16_t getNavigationRate(uint16_t maxWait = defaultMaxWait); //Return the ratio between the number of measurements and the number of navigation solutions. Unit is cycles
|
uint16_t getNavigationRate(uint16_t maxWait = defaultMaxWait); //Return the ratio between the number of measurements and the number of navigation solutions. Unit is cycles
|
||||||
|
void flushCFGRATE(); // Mark the measurement and navigation rate data as stale - used by the set rate functions
|
||||||
|
|
||||||
// Helper functions for DOP
|
// Helper functions for DOP
|
||||||
|
|
||||||
@@ -1028,6 +1119,11 @@ public:
|
|||||||
uint16_t getSurveyInObservationTime(uint16_t maxWait = defaultMaxWait); // Truncated to 65535 seconds
|
uint16_t getSurveyInObservationTime(uint16_t maxWait = defaultMaxWait); // Truncated to 65535 seconds
|
||||||
float getSurveyInMeanAccuracy(uint16_t maxWait = defaultMaxWait); // Returned as m
|
float getSurveyInMeanAccuracy(uint16_t maxWait = defaultMaxWait); // Returned as m
|
||||||
|
|
||||||
|
// Helper functions for TIMELS
|
||||||
|
|
||||||
|
uint8_t getLeapIndicator(int32_t& timeToLsEvent, uint16_t maxWait = defaultMaxWait);
|
||||||
|
int8_t getCurrentLeapSeconds(sfe_ublox_ls_src_e& source, uint16_t maxWait = defaultMaxWait);
|
||||||
|
|
||||||
// Helper functions for RELPOSNED
|
// Helper functions for RELPOSNED
|
||||||
|
|
||||||
float getRelPosN(uint16_t maxWait = defaultMaxWait); // Returned as m
|
float getRelPosN(uint16_t maxWait = defaultMaxWait); // Returned as m
|
||||||
@@ -1080,6 +1176,7 @@ public:
|
|||||||
UBX_NAV_HPPOSECEF_t *packetUBXNAVHPPOSECEF = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
|
UBX_NAV_HPPOSECEF_t *packetUBXNAVHPPOSECEF = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
|
||||||
UBX_NAV_HPPOSLLH_t *packetUBXNAVHPPOSLLH = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
|
UBX_NAV_HPPOSLLH_t *packetUBXNAVHPPOSLLH = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
|
||||||
UBX_NAV_CLOCK_t *packetUBXNAVCLOCK = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
|
UBX_NAV_CLOCK_t *packetUBXNAVCLOCK = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
|
||||||
|
UBX_NAV_TIMELS_t *packetUBXNAVTIMELS = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
|
||||||
UBX_NAV_SVIN_t *packetUBXNAVSVIN = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
|
UBX_NAV_SVIN_t *packetUBXNAVSVIN = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
|
||||||
UBX_NAV_RELPOSNED_t *packetUBXNAVRELPOSNED = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
|
UBX_NAV_RELPOSNED_t *packetUBXNAVRELPOSNED = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
|
||||||
|
|
||||||
@@ -1153,6 +1250,7 @@ private:
|
|||||||
boolean initPacketUBXNAVHPPOSECEF(); // Allocate RAM for packetUBXNAVHPPOSECEF and initialize it
|
boolean initPacketUBXNAVHPPOSECEF(); // Allocate RAM for packetUBXNAVHPPOSECEF and initialize it
|
||||||
boolean initPacketUBXNAVHPPOSLLH(); // Allocate RAM for packetUBXNAVHPPOSLLH and initialize it
|
boolean initPacketUBXNAVHPPOSLLH(); // Allocate RAM for packetUBXNAVHPPOSLLH and initialize it
|
||||||
boolean initPacketUBXNAVCLOCK(); // Allocate RAM for packetUBXNAVCLOCK and initialize it
|
boolean initPacketUBXNAVCLOCK(); // Allocate RAM for packetUBXNAVCLOCK and initialize it
|
||||||
|
boolean initPacketUBXNAVTIMELS(); // Allocate RAM for packetUBXNAVTIMELS and initialize it
|
||||||
boolean initPacketUBXNAVSVIN(); // Allocate RAM for packetUBXNAVSVIN and initialize it
|
boolean initPacketUBXNAVSVIN(); // Allocate RAM for packetUBXNAVSVIN and initialize it
|
||||||
boolean initPacketUBXNAVRELPOSNED(); // Allocate RAM for packetUBXNAVRELPOSNED and initialize it
|
boolean initPacketUBXNAVRELPOSNED(); // Allocate RAM for packetUBXNAVRELPOSNED and initialize it
|
||||||
boolean initPacketUBXRXMSFRBX(); // Allocate RAM for packetUBXRXMSFRBX and initialize it
|
boolean initPacketUBXRXMSFRBX(); // Allocate RAM for packetUBXRXMSFRBX and initialize it
|
||||||
@@ -1182,6 +1280,9 @@ private:
|
|||||||
|
|
||||||
boolean ubx7FcheckDisabled = false; // Flag to indicate if the "7F" check should be ignored in checkUbloxI2C
|
boolean ubx7FcheckDisabled = false; // Flag to indicate if the "7F" check should be ignored in checkUbloxI2C
|
||||||
|
|
||||||
|
sfe_ublox_nmea_filtering_t _logNMEA; // Flags to indicate which NMEA messages should be added to the file buffer for logging
|
||||||
|
sfe_ublox_nmea_filtering_t _processNMEA; // Flags to indicate which NMEA messages should be passed to processNMEA
|
||||||
|
|
||||||
//The packet buffers
|
//The packet buffers
|
||||||
//These are pointed at from within the ubxPacket
|
//These are pointed at from within the ubxPacket
|
||||||
uint8_t payloadAck[2]; // Holds the requested ACK/NACK
|
uint8_t payloadAck[2]; // Holds the requested ACK/NACK
|
||||||
@@ -1212,11 +1313,16 @@ private:
|
|||||||
|
|
||||||
unsigned long lastCheck = 0;
|
unsigned long lastCheck = 0;
|
||||||
|
|
||||||
uint16_t ubxFrameCounter; //It counts all UBX frame. [Fixed header(2bytes), CLS(1byte), ID(1byte), length(2bytes), payload(x bytes), checksums(2bytes)]
|
uint16_t ubxFrameCounter; //Count all UBX frame bytes. [Fixed header(2bytes), CLS(1byte), ID(1byte), length(2bytes), payload(x bytes), checksums(2bytes)]
|
||||||
|
|
||||||
uint8_t rollingChecksumA; //Rolls forward as we receive incoming bytes. Checked against the last two A/B checksum bytes
|
uint8_t rollingChecksumA; //Rolls forward as we receive incoming bytes. Checked against the last two A/B checksum bytes
|
||||||
uint8_t rollingChecksumB; //Rolls forward as we receive incoming bytes. Checked against the last two A/B checksum bytes
|
uint8_t rollingChecksumB; //Rolls forward as we receive incoming bytes. Checked against the last two A/B checksum bytes
|
||||||
|
|
||||||
|
int8_t nmeaByteCounter; //Count all NMEA message bytes.
|
||||||
|
const int8_t maxNMEAByteCount = 82; // Abort NMEA message reception if nmeaByteCounter exceeds this (https://en.wikipedia.org/wiki/NMEA_0183#Message_structure)
|
||||||
|
uint8_t nmeaAddressField[6]; // NMEA Address Field - includes the start character (*)
|
||||||
|
boolean logThisNMEA(); // Return true if we should log this NMEA message
|
||||||
|
boolean processThisNMEA(); // Return true if we should pass this NMEA message to processNMEA
|
||||||
|
|
||||||
uint16_t rtcmLen = 0;
|
uint16_t rtcmLen = 0;
|
||||||
|
|
||||||
// Flag to prevent reentry into checkCallbacks
|
// Flag to prevent reentry into checkCallbacks
|
||||||
|
|||||||
@@ -854,6 +854,66 @@ typedef struct
|
|||||||
UBX_NAV_CLOCK_data_t *callbackData;
|
UBX_NAV_CLOCK_data_t *callbackData;
|
||||||
} UBX_NAV_CLOCK_t;
|
} UBX_NAV_CLOCK_t;
|
||||||
|
|
||||||
|
// UBX-NAV-TIMELS (0x01 0x26): Leap second event information
|
||||||
|
const uint16_t UBX_NAV_TIMELS_LEN = 24;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t iTOW; // GPS time of week of the navigation epoch: ms
|
||||||
|
uint8_t version; // Message version (0x00 for this version)
|
||||||
|
uint8_t reserved1[3];
|
||||||
|
uint8_t srcOfCurrLs; //Information source for the current number of leap seconds
|
||||||
|
int8_t currLs; //Current number of leap seconds since start of GPS (Jan 6, 1980), s
|
||||||
|
uint8_t srcOfLsChange; //Information source for the future leap second event
|
||||||
|
int8_t lsChange; //Future leap second change if one is scheduled, +1, 0, -1s
|
||||||
|
int32_t timeToLsEvent; //Num of secs until the next or from the last leap second, s
|
||||||
|
uint16_t dateOfLsGpsWn; //GPS week num (WN) of the next or the last leap second event
|
||||||
|
uint16_t dateOfLsGpsDn; //GPS day of week num (DN) for the next or last leap second event
|
||||||
|
uint8_t reserved2[3];
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint8_t all;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8_t validCurrLs : 1; // 1 = Valid current number of leap seconds value
|
||||||
|
uint8_t validTimeToLsEvent : 1; // 1 = Valid time to next leap second event or from the last leap second event if no future event scheduled
|
||||||
|
} bits;
|
||||||
|
} valid;
|
||||||
|
} UBX_NAV_TIMELS_data_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint32_t all;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t all : 1;
|
||||||
|
|
||||||
|
uint32_t iTOW : 1;
|
||||||
|
uint32_t version : 1;
|
||||||
|
uint32_t srcOfCurrLs : 1;
|
||||||
|
uint32_t currLs : 1;
|
||||||
|
uint32_t srcOfLsChange : 1;
|
||||||
|
uint32_t lsChange : 1;
|
||||||
|
uint32_t timeToLsEvent : 1;
|
||||||
|
uint32_t dateOfLsGpsWn : 1;
|
||||||
|
uint32_t dateOfLsGpsDn : 1;
|
||||||
|
uint32_t validCurrLs : 1;
|
||||||
|
uint32_t validTimeToLsEvent : 1;
|
||||||
|
} bits;
|
||||||
|
} moduleQueried;
|
||||||
|
} UBX_NAV_TIMELS_moduleQueried_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ubxAutomaticFlags automaticFlags;
|
||||||
|
UBX_NAV_TIMELS_data_t data;
|
||||||
|
UBX_NAV_TIMELS_moduleQueried_t moduleQueried;
|
||||||
|
void (*callbackPointer)(UBX_NAV_TIMELS_data_t);
|
||||||
|
UBX_NAV_TIMELS_data_t *callbackData;
|
||||||
|
} UBX_NAV_TIMELS_t;
|
||||||
|
|
||||||
// UBX-NAV-SVIN (0x01 0x3B): Survey-in data
|
// UBX-NAV-SVIN (0x01 0x3B): Survey-in data
|
||||||
const uint16_t UBX_NAV_SVIN_LEN = 40;
|
const uint16_t UBX_NAV_SVIN_LEN = 40;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user