Skip to content

Commit 2c71ab7

Browse files
authoredApr 26, 2021
Merge pull request #26 from sparkfun/release_candidate
v2.0.6
·
v2.2.28v2.0.6
2 parents b20579e + 36fe93e commit 2c71ab7

File tree

9 files changed

+903
-52
lines changed

9 files changed

+903
-52
lines changed
 
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
/*
2+
Demonstrate how to log NMEA and UBX data simultaneously
3+
By: Paul Clark
4+
SparkFun Electronics
5+
Date: April 13th, 2021
6+
License: MIT. See license file for more information but you can
7+
basically do whatever you want with this code.
8+
9+
This example shows how to configure the u-blox GNSS to send PVT reports automatically
10+
and log those and any incoming NMEA messages to SD card in UBX format
11+
12+
** Please note: this example will only work on processors like the Artemis which have plenty of RAM available **
13+
14+
This code is intended to be run on the MicroMod Data Logging Carrier Board using the Artemis Processor
15+
but can be adapted by changing the chip select pin and SPI definitions:
16+
https://www.sparkfun.com/products/16829
17+
https://www.sparkfun.com/products/16401
18+
19+
Hardware Connections:
20+
Please see: https://learn.sparkfun.com/tutorials/micromod-data-logging-carrier-board-hookup-guide
21+
Insert the Artemis Processor into the MicroMod Data Logging Carrier Board and secure with the screw.
22+
Connect your GNSS breakout to the Carrier Board using a Qwiic cable.
23+
Connect an antenna to your GNSS board if required.
24+
Insert a formatted micro-SD card into the socket on the Carrier Board.
25+
Connect the Carrier Board to your computer using a USB-C cable.
26+
Ensure you have the SparkFun Apollo3 boards installed: http://boardsmanager/All#SparkFun_Apollo3
27+
This code has been tested using version 1.2.1 of the Apollo3 boards on Arduino IDE 1.8.13.
28+
Select "SparkFun Artemis MicroMod" as the board type.
29+
Press upload to upload the code onto the Artemis.
30+
Open the Serial Monitor at 115200 baud to see the output.
31+
32+
To minimise I2C bus errors, it is a good idea to open the I2C pull-up split pad links on
33+
both the MicroMod Data Logging Carrier Board and the u-blox module breakout.
34+
35+
Feel like supporting open source hardware?
36+
Buy a board from SparkFun!
37+
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
38+
NEO-M8P RTK: https://www.sparkfun.com/products/15005
39+
ZOE-M8Q: https://www.sparkfun.com/products/15193
40+
SAM-M8Q: https://www.sparkfun.com/products/15210
41+
*/
42+
43+
#include <SPI.h>
44+
#include <SD.h>
45+
#include <Wire.h> //Needed for I2C to GNSS
46+
47+
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_GNSS
48+
SFE_UBLOX_GNSS myGNSS;
49+
50+
File myFile; //File that all GNSS data is written to
51+
52+
#define sdChipSelect CS //Primary SPI Chip Select is CS for the MicroMod Artemis Processor. Adjust for your processor if necessary.
53+
54+
#define sdWriteSize 512 // Write data to the SD card in blocks of 512 bytes
55+
#define fileBufferSize 16384 // Allocate 16KBytes of RAM for UBX message storage
56+
57+
unsigned long lastPrint; // Record when the last Serial print took place
58+
unsigned long bytesWritten = 0; // Record how many bytes have been written to SD card
59+
60+
void setup()
61+
{
62+
Serial.begin(115200);
63+
while (!Serial); //Wait for user to open terminal
64+
Serial.println("SparkFun u-blox Example");
65+
66+
pinMode(LED_BUILTIN, OUTPUT); // Flash LED_BUILTIN each time we write to the SD card
67+
digitalWrite(LED_BUILTIN, LOW);
68+
69+
Wire.begin(); // Start I2C communication
70+
71+
#if defined(AM_PART_APOLLO3)
72+
Wire.setPullups(0); // On the Artemis, we can disable the internal I2C pull-ups too to help reduce bus errors
73+
#endif
74+
75+
while (Serial.available()) // Make sure the Serial buffer is empty
76+
{
77+
Serial.read();
78+
}
79+
80+
Serial.println(F("Press any key to start logging."));
81+
82+
while (!Serial.available()) // Wait for the user to press a key
83+
{
84+
; // Do nothing
85+
}
86+
87+
delay(100); // Wait, just in case multiple characters were sent
88+
89+
while (Serial.available()) // Empty the Serial buffer
90+
{
91+
Serial.read();
92+
}
93+
94+
Serial.println("Initializing SD card...");
95+
96+
// See if the card is present and can be initialized:
97+
if (!SD.begin(sdChipSelect))
98+
{
99+
Serial.println("Card failed, or not present. Freezing...");
100+
// don't do anything more:
101+
while (1);
102+
}
103+
Serial.println("SD card initialized.");
104+
105+
// Create or open a file called "PVT_NMEA.ubx" on the SD card.
106+
// If the file already exists, the new data is appended to the end of the file.
107+
myFile = SD.open("PVT_NMEA.ubx", FILE_WRITE);
108+
if(!myFile)
109+
{
110+
Serial.println(F("Failed to create UBX data file! Freezing..."));
111+
while (1);
112+
}
113+
114+
//myGNSS.enableDebugging(); // Uncomment this line to enable lots of helpful GNSS debug messages on Serial
115+
//myGNSS.enableDebugging(Serial, true); // Or, uncomment this line to enable only the important GNSS debug messages on Serial
116+
117+
//myGNSS.disableUBX7Fcheck(); // RAWX data can legitimately contain 0x7F. Uncomment this line to disable the "7F" check in checkUbloxI2C
118+
119+
// SD cards can occasionally 'hiccup' and a write takes much longer than usual. The buffer needs to be big enough
120+
// to hold the backlog of data if/when this happens.
121+
// getMaxFileBufferAvail will tell us the maximum number of bytes which the file buffer has contained.
122+
myGNSS.setFileBufferSize(fileBufferSize); // setFileBufferSize must be called _before_ .begin
123+
124+
if (myGNSS.begin() == false) //Connect to the u-blox module using Wire port
125+
{
126+
Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing..."));
127+
while (1);
128+
}
129+
130+
// Uncomment the next line if you want to reset your module back to the default settings with 1Hz navigation rate
131+
// This will (re)enable the standard NMEA messages too
132+
// This will also disable any "auto" UBX messages that were enabled and saved by other examples and reduce the load on the I2C bus
133+
//myGNSS.factoryDefault(); delay(5000);
134+
135+
myGNSS.setI2COutput(COM_TYPE_UBX | COM_TYPE_NMEA); //Set the I2C port to output both UBX and NMEA messages
136+
137+
//myGNSS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Optional: save (only) the communications port settings to flash and BBR
138+
139+
myGNSS.setNavigationFrequency(1); //Produce one navigation solution per second
140+
141+
myGNSS.setAutoPVT(true, false); // Enable automatic NAV PVT messages: without callback; without implicit update
142+
myGNSS.logNAVPVT(); // Enable NAV PVT data logging
143+
144+
myGNSS.enableNMEAMessage(UBX_NMEA_GGA, COM_PORT_I2C, 1); // Ensure the GxGGA (Global positioning system fix data) message is enabled. Send every measurement.
145+
myGNSS.enableNMEAMessage(UBX_NMEA_GSA, COM_PORT_I2C, 1); // Ensure the GxGSA (GNSS DOP and Active satellites) message is enabled. Send every measurement.
146+
myGNSS.enableNMEAMessage(UBX_NMEA_GSV, COM_PORT_I2C, 1); // Ensure the GxGSV (GNSS satellites in view) message is enabled. Send every measurement.
147+
148+
myGNSS.setNMEALoggingMask(SFE_UBLOX_FILTER_NMEA_ALL); // Enable logging of all enabled NMEA messages
149+
//myGNSS.setNMEALoggingMask(SFE_UBLOX_FILTER_NMEA_GGA | SFE_UBLOX_FILTER_NMEA_GSA); // Or we can, for example, log only GxGGA & GxGSA and ignore GxGSV
150+
151+
Serial.println(F("Press any key to stop logging."));
152+
153+
lastPrint = millis(); // Initialize lastPrint
154+
}
155+
156+
void loop()
157+
{
158+
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
159+
160+
myGNSS.checkUblox(); // Check for the arrival of new data and process it.
161+
162+
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
163+
164+
while (myGNSS.fileBufferAvailable() >= sdWriteSize) // Check to see if we have at least sdWriteSize waiting in the buffer
165+
{
166+
digitalWrite(LED_BUILTIN, HIGH); // Flash LED_BUILTIN each time we write to the SD card
167+
168+
uint8_t myBuffer[sdWriteSize]; // Create our own buffer to hold the data while we write it to SD card
169+
170+
myGNSS.extractFileBufferData((uint8_t *)&myBuffer, sdWriteSize); // Extract exactly sdWriteSize bytes from the UBX file buffer and put them into myBuffer
171+
172+
myFile.write(myBuffer, sdWriteSize); // Write exactly sdWriteSize bytes from myBuffer to the ubxDataFile on the SD card
173+
174+
bytesWritten += sdWriteSize; // Update bytesWritten
175+
176+
// In case the SD writing is slow or there is a lot of data to write, keep checking for the arrival of new data
177+
myGNSS.checkUblox(); // Check for the arrival of new data and process it.
178+
179+
digitalWrite(LED_BUILTIN, LOW); // Turn LED_BUILTIN off again
180+
}
181+
182+
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
183+
184+
if (millis() > (lastPrint + 1000)) // Print bytesWritten once per second
185+
{
186+
Serial.print(F("The number of bytes written to SD card is ")); // Print how many bytes have been written to SD card
187+
Serial.println(bytesWritten);
188+
189+
uint16_t maxBufferBytes = myGNSS.getMaxFileBufferAvail(); // Get how full the file buffer has been (not how full it is now)
190+
191+
//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
192+
//Serial.println(maxBufferBytes);
193+
194+
if (maxBufferBytes > ((fileBufferSize / 5) * 4)) // Warn the user if fileBufferSize was more than 80% full
195+
{
196+
Serial.println(F("Warning: the file buffer has been over 80% full. Some data may have been lost."));
197+
}
198+
199+
lastPrint = millis(); // Update lastPrint
200+
}
201+
202+
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
203+
204+
if (Serial.available()) // Check if the user wants to stop logging
205+
{
206+
uint16_t remainingBytes = myGNSS.fileBufferAvailable(); // Check if there are any bytes remaining in the file buffer
207+
208+
while (remainingBytes > 0) // While there is still data in the file buffer
209+
{
210+
digitalWrite(LED_BUILTIN, HIGH); // Flash LED_BUILTIN while we write to the SD card
211+
212+
uint8_t myBuffer[sdWriteSize]; // Create our own buffer to hold the data while we write it to SD card
213+
214+
uint16_t bytesToWrite = remainingBytes; // Write the remaining bytes to SD card sdWriteSize bytes at a time
215+
if (bytesToWrite > sdWriteSize)
216+
{
217+
bytesToWrite = sdWriteSize;
218+
}
219+
220+
myGNSS.extractFileBufferData((uint8_t *)&myBuffer, bytesToWrite); // Extract bytesToWrite bytes from the UBX file buffer and put them into myBuffer
221+
222+
myFile.write(myBuffer, bytesToWrite); // Write bytesToWrite bytes from myBuffer to the ubxDataFile on the SD card
223+
224+
bytesWritten += bytesToWrite; // Update bytesWritten
225+
226+
remainingBytes -= bytesToWrite; // Decrement remainingBytes
227+
}
228+
229+
digitalWrite(LED_BUILTIN, LOW); // Turn LED_BUILTIN off
230+
231+
Serial.print(F("The total number of bytes written to SD card is ")); // Print how many bytes have been written to SD card
232+
Serial.println(bytesWritten);
233+
234+
myFile.close(); // Close the data file
235+
236+
Serial.println(F("Logging stopped. Freezing..."));
237+
while(1); // Do nothing more
238+
}
239+
240+
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
241+
}

‎examples/Example25_MeasurementAndNavigationRate/Example25_MeasurementAndNavigationRate.ino

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,6 @@ void setup()
8181
while (1);
8282
}
8383

84-
// Another trick we can use is to mark the CFG RATE data as stale so we can be sure we read fresh data
85-
myGNSS.packetUBXCFGRATE->moduleQueried.moduleQueried.all = 0; // Mark all of the CFG RATE data as stale
86-
8784
// Read and print the updated measurement rate and navigation rate
8885

8986
rate = myGNSS.getMeasurementRate(); //Get the measurement rate of this module
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
Getting leap second event info as SNTP Leap Indicator, time to a leap second event and the number of leap seconds since GPS epoch
3+
By: UT2UH
4+
Date: April 14th, 2021
5+
License: MIT. See license file for more information but you can
6+
basically do whatever you want with this code.
7+
8+
This example shows how to query a u-blox module for the leap second event info to cast to SNTP Leap Indicator enumeration.
9+
We also turn off the NMEA output on the I2C port. This decreases the amount of I2C traffic dramatically.
10+
11+
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
12+
13+
Feel like supporting open source hardware?
14+
Buy a board from SparkFun!
15+
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
16+
NEO-M8P RTK: https://www.sparkfun.com/products/15005
17+
SAM-M8Q: https://www.sparkfun.com/products/15106
18+
19+
Hardware Connections:
20+
Plug a Qwiic cable into the GNSS and a BlackBoard
21+
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
22+
Open the serial monitor at 115200 baud to see the output
23+
*/
24+
25+
#include <Wire.h> //Needed for I2C to GNSS
26+
27+
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
28+
SFE_UBLOX_GNSS myGNSS;
29+
30+
typedef enum {
31+
LI_NO_WARNING, //Time leaping not scheduled
32+
LI_LAST_MINUTE_61_SEC, //Last minute has 61 seconds
33+
LI_LAST_MINUTE_59_SEC, //Last minute has 59 seconds
34+
LI_ALARM_CONDITION //The NTP server's clock not synchronized
35+
} ntp_LI_e;
36+
37+
38+
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to u-blox module.
39+
40+
void setup()
41+
{
42+
Serial.begin(115200);
43+
while (!Serial)
44+
; //Wait for user to open terminal
45+
Serial.println("SparkFun u-blox Example");
46+
47+
Wire.begin();
48+
49+
if (myGNSS.begin() == false) //Connect to the u-blox module using Wire port
50+
{
51+
Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing."));
52+
while (1)
53+
;
54+
}
55+
56+
// Uncomment the next line if you need to completely reset your module
57+
//myGNSS.factoryDefault(); delay(5000); // Reset everything and wait while the module restarts
58+
59+
myGNSS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
60+
myGNSS.saveConfiguration(); //Optional: Save the current settings to flash and BBR
61+
62+
Serial.println("Compare Unix Epoch given with reference one from https://www.epochconverter.com/");
63+
64+
}
65+
66+
void loop()
67+
{
68+
//Query module only every second. Doing it more often will just cause I2C traffic.
69+
//The module only responds when a new position is available
70+
if (millis() - lastTime > 1000)
71+
{
72+
lastTime = millis(); //Update the timer
73+
74+
// getUnixEpoch marks the PVT data as stale so you will get Unix time and PVT time on alternate seconds
75+
76+
uint32_t us; //microseconds returned by getUnixEpoch()
77+
uint32_t epoch = myGNSS.getUnixEpoch();
78+
Serial.print("Unix Epoch rounded: ");
79+
Serial.print(epoch, DEC);
80+
epoch = myGNSS.getUnixEpoch(us);
81+
Serial.print(" Exact Unix Epoch: ");
82+
Serial.print(epoch, DEC);
83+
Serial.print(" micros: ");
84+
Serial.println(us, DEC);
85+
int32_t timeToLeapSecEvent;
86+
ntp_LI_e leapIndicator = (ntp_LI_e)myGNSS.getLeapIndicator(timeToLeapSecEvent);
87+
Serial.print("NTP LI: ");
88+
Serial.print(leapIndicator, DEC);
89+
switch (leapIndicator){
90+
case LI_NO_WARNING:
91+
Serial.print(" - No event scheduled");
92+
break;
93+
case LI_LAST_MINUTE_61_SEC:
94+
Serial.print(" - last minute will end at 23:60");
95+
break;
96+
case LI_LAST_MINUTE_59_SEC:
97+
Serial.print(" - last minute will end at 23:58");
98+
break;
99+
case LI_ALARM_CONDITION:
100+
default:
101+
Serial.print(" - Unknown (clock not synchronized)");
102+
break;
103+
}
104+
Serial.print(". Time to the next leap second event: ");
105+
Serial.println(timeToLeapSecEvent, DEC);
106+
107+
sfe_ublox_ls_src_e leapSecSource;
108+
Serial.print("Leap seconds since GPS Epoch (Jan 6th, 1980): ");
109+
Serial.print(myGNSS.getCurrentLeapSeconds(leapSecSource), DEC);
110+
switch (leapSecSource){
111+
case SFE_UBLOX_LS_SRC_DEFAULT:
112+
Serial.print(" - hardcoded");
113+
break;
114+
case SFE_UBLOX_LS_SRC_GLONASS:
115+
Serial.print(" - derived from GPS and GLONASS time difference");
116+
break;
117+
case SFE_UBLOX_LS_SRC_GPS:
118+
Serial.print(" - according to GPS");
119+
break;
120+
case SFE_UBLOX_LS_SRC_SBAS:
121+
Serial.print(" - according to SBAS");
122+
break;
123+
case SFE_UBLOX_LS_SRC_BEIDOU:
124+
Serial.print(" - according to BeiDou");
125+
break;
126+
case SFE_UBLOX_LS_SRC_GALILEO:
127+
Serial.print(" - according to Galileo");
128+
break;
129+
case SFE_UBLOX_LS_SRC_AIDED:
130+
Serial.print(" - last minute will end at 23:58");
131+
break;
132+
case SFE_UBLOX_LS_SRC_CONFIGURED:
133+
Serial.print(" - as configured)");
134+
break;
135+
case SFE_UBLOX_LS_SRC_UNKNOWN:
136+
default:
137+
Serial.print(" - source unknown");
138+
break;
139+
}
140+
Serial.println();
141+
}
142+
Serial.println();
143+
}

‎examples/Example2_NMEAParsing/Example2_NMEAParsing.ino

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ void setup()
4545
Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing."));
4646
while (1);
4747
}
48+
49+
myGNSS.setProcessNMEAMask(SFE_UBLOX_FILTER_NMEA_ALL); // Make sure the library is passing all NMEA messages to processNMEA
50+
51+
myGNSS.setProcessNMEAMask(SFE_UBLOX_FILTER_NMEA_GGA); // Or, we can be kind to MicroNMEA and _only_ pass the GGA messages to it
4852
}
4953

5054
void loop()
@@ -60,12 +64,12 @@ void loop()
6064
Serial.println(latitude_mdeg / 1000000., 6);
6165
Serial.print("Longitude (deg): ");
6266
Serial.println(longitude_mdeg / 1000000., 6);
67+
68+
nmea.clear(); // Clear the MicroNMEA storage to make sure we are getting fresh data
6369
}
6470
else
6571
{
66-
Serial.print("No Fix - ");
67-
Serial.print("Num. satellites: ");
68-
Serial.println(nmea.getNumSatellites());
72+
Serial.println("Waiting for fresh data");
6973
}
7074

7175
delay(250); //Don't pound too hard on the I2C bus

‎keywords.txt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ UBX_NAV_HPPOSECEF_data_t KEYWORD1
2828
UBX_NAV_HPPOSLLH_data_t KEYWORD1
2929
UBX_NAV_CLOCK_data_t KEYWORD1
3030
UBX_NAV_RELPOSNED_data_t KEYWORD1
31+
UBX_NAV_TIMELS_data_t KEYWORD1
3132

3233
UBX_RXM_SFRBX_data_t KEYWORD1
3334
UBX_RXM_RAWX_data_t KEYWORD1
@@ -264,6 +265,11 @@ initPacketUBXNAVCLOCK KEYWORD2
264265
flushNAVCLOCK KEYWORD2
265266
logNAVCLOCK KEYWORD2
266267

268+
getLeapSecondEvent KEYWORD2
269+
getLeapIndicator KEYWORD2
270+
getCurrentLeapSeconds KEYWORD2
271+
initPacketUBXNAVTIMELS KEYWORD2
272+
267273
getSurveyStatus KEYWORD2
268274
initPacketUBXNAVSVIN KEYWORD2
269275

@@ -382,12 +388,18 @@ initPacketUBXHNRPVT KEYWORD2
382388
flushHNRPVT KEYWORD2
383389
logHNRPVT KEYWORD2
384390

391+
setNMEALoggingMask KEYWORD2
392+
getNMEALoggingMask KEYWORD2
393+
setProcessNMEAMask KEYWORD2
394+
getProcessNMEAMask KEYWORD2
395+
385396
setNavigationFrequency KEYWORD2
386397
getNavigationFrequency KEYWORD2
387398
setMeasurementRate KEYWORD2
388399
getMeasurementRate KEYWORD2
389400
setNavigationRate KEYWORD2
390401
getNavigationRate KEYWORD2
402+
flushCFGRATE KEYWORD2
391403

392404
getGeometricDOP KEYWORD2
393405
getPositionDOP KEYWORD2
@@ -543,16 +555,41 @@ UBX_NMEA_GLQ LITERAL1
543555
UBX_NMEA_GNQ LITERAL1
544556
UBX_NMEA_GNS LITERAL1
545557
UBX_NMEA_GPQ LITERAL1
558+
UBX_NMEA_GQQ LITERAL1
546559
UBX_NMEA_GRS LITERAL1
547560
UBX_NMEA_GSA LITERAL1
548561
UBX_NMEA_GST LITERAL1
549562
UBX_NMEA_GSV LITERAL1
563+
UBX_NMEA_RLM LITERAL1
550564
UBX_NMEA_RMC LITERAL1
551565
UBX_NMEA_TXT LITERAL1
552566
UBX_NMEA_VLW LITERAL1
553567
UBX_NMEA_VTG LITERAL1
554568
UBX_NMEA_ZDA LITERAL1
555569

570+
SFE_UBLOX_FILTER_NMEA_ALL LITERAL1
571+
SFE_UBLOX_FILTER_NMEA_DTM LITERAL1
572+
SFE_UBLOX_FILTER_NMEA_GAQ LITERAL1
573+
SFE_UBLOX_FILTER_NMEA_GBQ LITERAL1
574+
SFE_UBLOX_FILTER_NMEA_GBS LITERAL1
575+
SFE_UBLOX_FILTER_NMEA_GGA LITERAL1
576+
SFE_UBLOX_FILTER_NMEA_GLL LITERAL1
577+
SFE_UBLOX_FILTER_NMEA_GLQ LITERAL1
578+
SFE_UBLOX_FILTER_NMEA_GNQ LITERAL1
579+
SFE_UBLOX_FILTER_NMEA_GNS LITERAL1
580+
SFE_UBLOX_FILTER_NMEA_GPQ LITERAL1
581+
SFE_UBLOX_FILTER_NMEA_GQQ LITERAL1
582+
SFE_UBLOX_FILTER_NMEA_GRS LITERAL1
583+
SFE_UBLOX_FILTER_NMEA_GSA LITERAL1
584+
SFE_UBLOX_FILTER_NMEA_GST LITERAL1
585+
SFE_UBLOX_FILTER_NMEA_GSV LITERAL1
586+
SFE_UBLOX_FILTER_NMEA_RLM LITERAL1
587+
SFE_UBLOX_FILTER_NMEA_RMC LITERAL1
588+
SFE_UBLOX_FILTER_NMEA_TXT LITERAL1
589+
SFE_UBLOX_FILTER_NMEA_VLW LITERAL1
590+
SFE_UBLOX_FILTER_NMEA_VTG LITERAL1
591+
SFE_UBLOX_FILTER_NMEA_ZDA LITERAL1
592+
556593
UBX_NAV_ATT LITERAL1
557594
UBX_NAV_CLOCK LITERAL1
558595
UBX_NAV_DOP LITERAL1
@@ -566,6 +603,7 @@ UBX_NAV_RELPOSNED LITERAL1
566603
UBX_NAV_RESETODO LITERAL1
567604
UBX_NAV_STATUS LITERAL1
568605
UBX_NAV_SVIN LITERAL1
606+
UBX_NAV_TIMELS LITERAL1
569607
UBX_NAV_VELECEF LITERAL1
570608
UBX_NAV_VELNED LITERAL1
571609

‎library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=SparkFun u-blox GNSS Arduino Library
2-
version=2.0.5
2+
version=2.0.6
33
author=SparkFun Electronics <techsupport@sparkfun.com>
44
maintainer=SparkFun Electronics <sparkfun.com>
55
sentence=Library for I2C and Serial Communication with u-blox GNSS modules<br/><br/>

‎src/SparkFun_u-blox_GNSS_Arduino_Library.cpp

Lines changed: 299 additions & 37 deletions
Large diffs are not rendered by default.

‎src/SparkFun_u-blox_GNSS_Arduino_Library.h

Lines changed: 114 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,69 @@ typedef enum
9999
SFE_UBLOX_PACKET_PACKETAUTO
100100
} sfe_ublox_packet_buffer_e;
101101

102+
// Define a struct to allow selective logging / processing of NMEA messages
103+
// Set the individual bits to pass the NMEA messages to the file buffer and/or processNMEA
104+
// Setting bits.all will pass all messages to the file buffer and processNMEA
105+
typedef struct
106+
{
107+
union
108+
{
109+
uint32_t all;
110+
struct
111+
{
112+
uint32_t all : 1;
113+
uint32_t UBX_NMEA_DTM : 1;
114+
uint32_t UBX_NMEA_GAQ : 1;
115+
uint32_t UBX_NMEA_GBQ : 1;
116+
uint32_t UBX_NMEA_GBS : 1;
117+
uint32_t UBX_NMEA_GGA : 1;
118+
uint32_t UBX_NMEA_GLL : 1;
119+
uint32_t UBX_NMEA_GLQ : 1;
120+
uint32_t UBX_NMEA_GNQ : 1;
121+
uint32_t UBX_NMEA_GNS : 1;
122+
uint32_t UBX_NMEA_GPQ : 1;
123+
uint32_t UBX_NMEA_GQQ : 1;
124+
uint32_t UBX_NMEA_GRS : 1;
125+
uint32_t UBX_NMEA_GSA : 1;
126+
uint32_t UBX_NMEA_GST : 1;
127+
uint32_t UBX_NMEA_GSV : 1;
128+
uint32_t UBX_NMEA_RLM : 1;
129+
uint32_t UBX_NMEA_RMC : 1;
130+
uint32_t UBX_NMEA_TXT : 1;
131+
uint32_t UBX_NMEA_VLW : 1;
132+
uint32_t UBX_NMEA_VTG : 1;
133+
uint32_t UBX_NMEA_ZDA : 1;
134+
} bits;
135+
};
136+
} sfe_ublox_nmea_filtering_t;
137+
138+
// Define an enum to make it easy to enable/disable selected NMEA messages for logging / processing
139+
typedef enum
140+
{
141+
SFE_UBLOX_FILTER_NMEA_ALL = 0x00000001,
142+
SFE_UBLOX_FILTER_NMEA_DTM = 0x00000002,
143+
SFE_UBLOX_FILTER_NMEA_GAQ = 0x00000004,
144+
SFE_UBLOX_FILTER_NMEA_GBQ = 0x00000008,
145+
SFE_UBLOX_FILTER_NMEA_GBS = 0x00000010,
146+
SFE_UBLOX_FILTER_NMEA_GGA = 0x00000020,
147+
SFE_UBLOX_FILTER_NMEA_GLL = 0x00000040,
148+
SFE_UBLOX_FILTER_NMEA_GLQ = 0x00000080,
149+
SFE_UBLOX_FILTER_NMEA_GNQ = 0x00000100,
150+
SFE_UBLOX_FILTER_NMEA_GNS = 0x00000200,
151+
SFE_UBLOX_FILTER_NMEA_GPQ = 0x00000400,
152+
SFE_UBLOX_FILTER_NMEA_GQQ = 0x00000800,
153+
SFE_UBLOX_FILTER_NMEA_GRS = 0x00001000,
154+
SFE_UBLOX_FILTER_NMEA_GSA = 0x00002000,
155+
SFE_UBLOX_FILTER_NMEA_GST = 0x00004000,
156+
SFE_UBLOX_FILTER_NMEA_GSV = 0x00008000,
157+
SFE_UBLOX_FILTER_NMEA_RLM = 0x00010000,
158+
SFE_UBLOX_FILTER_NMEA_RMC = 0x00020000,
159+
SFE_UBLOX_FILTER_NMEA_TXT = 0x00040000,
160+
SFE_UBLOX_FILTER_NMEA_VLW = 0x00080000,
161+
SFE_UBLOX_FILTER_NMEA_VTG = 0x00100000,
162+
SFE_UBLOX_FILTER_NMEA_ZDA = 0x00200000
163+
} sfe_ublox_nmea_filtering_e;
164+
102165
//Registers
103166
const uint8_t UBX_SYNCH_1 = 0xB5;
104167
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
159222

160223
//Class: NMEA
161224
//The following are used to enable NMEA messages. Descriptions come from the NMEA messages overview in the ZED-F9P Interface Description
162-
const uint8_t UBX_NMEA_MSB = 0xF0; //All NMEA enable commands have 0xF0 as MSB
225+
const uint8_t UBX_NMEA_MSB = 0xF0; //All NMEA enable commands have 0xF0 as MSB. Equal to UBX_CLASS_NMEA
163226
const uint8_t UBX_NMEA_DTM = 0x0A; //GxDTM (datum reference)
164227
const uint8_t UBX_NMEA_GAQ = 0x45; //GxGAQ (poll a standard message (if the current talker ID is GA))
165228
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
169232
const uint8_t UBX_NMEA_GLQ = 0x43; //GxGLQ (poll a standard message (if the current Talker ID is GL))
170233
const uint8_t UBX_NMEA_GNQ = 0x42; //GxGNQ (poll a standard message (if the current Talker ID is GN))
171234
const uint8_t UBX_NMEA_GNS = 0x0D; //GxGNS (GNSS fix data)
172-
const uint8_t UBX_NMEA_GPQ = 0x040; //GxGPQ (poll a standard message (if the current Talker ID is GP))
235+
const uint8_t UBX_NMEA_GPQ = 0x40; //GxGPQ (poll a standard message (if the current Talker ID is GP))
236+
const uint8_t UBX_NMEA_GQQ = 0x47; //GxGQQ (poll a standard message (if the current Talker ID is GQ))
173237
const uint8_t UBX_NMEA_GRS = 0x06; //GxGRS (GNSS range residuals)
174238
const uint8_t UBX_NMEA_GSA = 0x02; //GxGSA (GNSS DOP and Active satellites)
175239
const uint8_t UBX_NMEA_GST = 0x07; //GxGST (GNSS Pseudo Range Error Statistics)
176240
const uint8_t UBX_NMEA_GSV = 0x03; //GxGSV (GNSS satellites in view)
241+
const uint8_t UBX_NMEA_RLM = 0x0B; //GxRMC (Return link message (RLM))
177242
const uint8_t UBX_NMEA_RMC = 0x04; //GxRMC (Recommended minimum data)
178243
const uint8_t UBX_NMEA_TXT = 0x41; //GxTXT (text transmission)
179244
const uint8_t UBX_NMEA_VLW = 0x0F; //GxVLW (dual ground/water distance)
@@ -407,6 +472,20 @@ enum sfe_ublox_gnss_ids_e
407472
SFE_UBLOX_GNSS_ID_GLONASS
408473
};
409474

475+
// The GNSS identifiers of leap second event info source - used by UBX-NAV-TIMELS
476+
enum sfe_ublox_ls_src_e
477+
{
478+
SFE_UBLOX_LS_SRC_DEFAULT,
479+
SFE_UBLOX_LS_SRC_GLONASS,
480+
SFE_UBLOX_LS_SRC_GPS,
481+
SFE_UBLOX_LS_SRC_SBAS,
482+
SFE_UBLOX_LS_SRC_BEIDOU,
483+
SFE_UBLOX_LS_SRC_GALILEO,
484+
SFE_UBLOX_LS_SRC_AIDED,
485+
SFE_UBLOX_LS_SRC_CONFIGURED,
486+
SFE_UBLOX_LS_SRC_UNKNOWN = 255
487+
};
488+
410489
#ifndef MAX_PAYLOAD_SIZE
411490
// v2.0: keep this for backwards-compatibility, but this is largely superseded by setPacketCfgPayloadSize
412491
#define MAX_PAYLOAD_SIZE 256 //We need ~220 bytes for getProtocolVersion on most ublox modules
@@ -580,15 +659,15 @@ class SFE_UBLOX_GNSS
580659
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
581660
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
582661

583-
boolean setI2CAddress(uint8_t deviceAddress, uint16_t maxTime = defaultMaxWait); //Changes the I2C address of the u-blox module
662+
boolean setI2CAddress(uint8_t deviceAddress, uint16_t maxTime = defaultMaxWait); //Changes the I2C address of the u-blox module
584663
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
585664

586665
boolean setI2COutput(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure I2C port to output UBX, NMEA, RTCM3 or a combination thereof
587-
boolean setUART1Output(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure UART1 port to output UBX, NMEA, RTCM3 or a combination thereof
588-
boolean setUART2Output(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure UART2 port to output UBX, NMEA, RTCM3 or a combination thereof
666+
boolean setUART1Output(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure UART1 port to output UBX, NMEA, RTCM3 or a combination thereof
667+
boolean setUART2Output(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure UART2 port to output UBX, NMEA, RTCM3 or a combination thereof
589668
boolean setUSBOutput(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure USB port to output UBX, NMEA, RTCM3 or a combination thereof
590669
boolean setSPIOutput(uint8_t comSettings, uint16_t maxWait = defaultMaxWait); //Configure SPI port to output UBX, NMEA, RTCM3 or a combination thereof
591-
void setNMEAOutputPort(Stream &nmeaOutputPort); //Sets the internal variable for the port to direct NMEA characters to
670+
void setNMEAOutputPort(Stream &nmeaOutputPort); //Sets the internal variable for the port to direct NMEA characters to
592671

593672
//Reset to defaults
594673

@@ -800,6 +879,9 @@ class SFE_UBLOX_GNSS
800879
// Add "auto" support for NAV SVIN - to avoid needing 'global' storage
801880
boolean getSurveyStatus(uint16_t maxWait); //Reads survey in status
802881

882+
// Add "auto" support for NAV TIMELS - to avoid needing 'global' storage
883+
boolean getLeapSecondEvent(uint16_t maxWait); //Reads leap second event info
884+
803885
boolean getRELPOSNED(uint16_t maxWait = defaultMaxWait); //Get Relative Positioning Information of the NED frame
804886
boolean setAutoRELPOSNED(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic RELPOSNED reports
805887
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 @@ class SFE_UBLOX_GNSS
9281010
void flushHNRPVT(); //Mark all the data as read/stale
9291011
void logHNRPVT(boolean enabled = true); // Log data to file buffer
9301012

1013+
// Helper functions for NMEA logging
1014+
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
1015+
uint32_t getNMEALoggingMask(); // Return which NMEA messages are selected for logging to the file buffer - if enabled
1016+
1017+
// Helper functions to control which NMEA messages are passed to processNMEA
1018+
void setProcessNMEAMask(uint32_t messages = SFE_UBLOX_FILTER_NMEA_ALL); // Control which NMEA messages are passed to processNMEA. Default to passing ALL messages
1019+
uint32_t getProcessNMEAMask(); // Return which NMEA messages are passed to processNMEA
1020+
9311021
// Helper functions for CFG RATE
9321022

9331023
boolean setNavigationFrequency(uint8_t navFreq, uint16_t maxWait = defaultMaxWait); //Set the number of nav solutions sent per second
@@ -936,6 +1026,7 @@ class SFE_UBLOX_GNSS
9361026
uint16_t getMeasurementRate(uint16_t maxWait = defaultMaxWait); //Return the elapsed time between GNSS measurements in milliseconds
9371027
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
9381028
uint16_t getNavigationRate(uint16_t maxWait = defaultMaxWait); //Return the ratio between the number of measurements and the number of navigation solutions. Unit is cycles
1029+
void flushCFGRATE(); // Mark the measurement and navigation rate data as stale - used by the set rate functions
9391030

9401031
// Helper functions for DOP
9411032

@@ -1028,6 +1119,11 @@ class SFE_UBLOX_GNSS
10281119
uint16_t getSurveyInObservationTime(uint16_t maxWait = defaultMaxWait); // Truncated to 65535 seconds
10291120
float getSurveyInMeanAccuracy(uint16_t maxWait = defaultMaxWait); // Returned as m
10301121

1122+
// Helper functions for TIMELS
1123+
1124+
uint8_t getLeapIndicator(int32_t& timeToLsEvent, uint16_t maxWait = defaultMaxWait);
1125+
int8_t getCurrentLeapSeconds(sfe_ublox_ls_src_e& source, uint16_t maxWait = defaultMaxWait);
1126+
10311127
// Helper functions for RELPOSNED
10321128

10331129
float getRelPosN(uint16_t maxWait = defaultMaxWait); // Returned as m
@@ -1080,6 +1176,7 @@ class SFE_UBLOX_GNSS
10801176
UBX_NAV_HPPOSECEF_t *packetUBXNAVHPPOSECEF = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
10811177
UBX_NAV_HPPOSLLH_t *packetUBXNAVHPPOSLLH = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
10821178
UBX_NAV_CLOCK_t *packetUBXNAVCLOCK = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
1179+
UBX_NAV_TIMELS_t *packetUBXNAVTIMELS = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
10831180
UBX_NAV_SVIN_t *packetUBXNAVSVIN = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
10841181
UBX_NAV_RELPOSNED_t *packetUBXNAVRELPOSNED = NULL; // Pointer to struct. RAM will be allocated for this if/when necessary
10851182

@@ -1153,6 +1250,7 @@ class SFE_UBLOX_GNSS
11531250
boolean initPacketUBXNAVHPPOSECEF(); // Allocate RAM for packetUBXNAVHPPOSECEF and initialize it
11541251
boolean initPacketUBXNAVHPPOSLLH(); // Allocate RAM for packetUBXNAVHPPOSLLH and initialize it
11551252
boolean initPacketUBXNAVCLOCK(); // Allocate RAM for packetUBXNAVCLOCK and initialize it
1253+
boolean initPacketUBXNAVTIMELS(); // Allocate RAM for packetUBXNAVTIMELS and initialize it
11561254
boolean initPacketUBXNAVSVIN(); // Allocate RAM for packetUBXNAVSVIN and initialize it
11571255
boolean initPacketUBXNAVRELPOSNED(); // Allocate RAM for packetUBXNAVRELPOSNED and initialize it
11581256
boolean initPacketUBXRXMSFRBX(); // Allocate RAM for packetUBXRXMSFRBX and initialize it
@@ -1182,6 +1280,9 @@ class SFE_UBLOX_GNSS
11821280

11831281
boolean ubx7FcheckDisabled = false; // Flag to indicate if the "7F" check should be ignored in checkUbloxI2C
11841282

1283+
sfe_ublox_nmea_filtering_t _logNMEA; // Flags to indicate which NMEA messages should be added to the file buffer for logging
1284+
sfe_ublox_nmea_filtering_t _processNMEA; // Flags to indicate which NMEA messages should be passed to processNMEA
1285+
11851286
//The packet buffers
11861287
//These are pointed at from within the ubxPacket
11871288
uint8_t payloadAck[2]; // Holds the requested ACK/NACK
@@ -1212,11 +1313,16 @@ class SFE_UBLOX_GNSS
12121313

12131314
unsigned long lastCheck = 0;
12141315

1215-
uint16_t ubxFrameCounter; //It counts all UBX frame. [Fixed header(2bytes), CLS(1byte), ID(1byte), length(2bytes), payload(x bytes), checksums(2bytes)]
1216-
1316+
uint16_t ubxFrameCounter; //Count all UBX frame bytes. [Fixed header(2bytes), CLS(1byte), ID(1byte), length(2bytes), payload(x bytes), checksums(2bytes)]
12171317
uint8_t rollingChecksumA; //Rolls forward as we receive incoming bytes. Checked against the last two A/B checksum bytes
12181318
uint8_t rollingChecksumB; //Rolls forward as we receive incoming bytes. Checked against the last two A/B checksum bytes
12191319

1320+
int8_t nmeaByteCounter; //Count all NMEA message bytes.
1321+
const int8_t maxNMEAByteCount = 82; // Abort NMEA message reception if nmeaByteCounter exceeds this (https://en.wikipedia.org/wiki/NMEA_0183#Message_structure)
1322+
uint8_t nmeaAddressField[6]; // NMEA Address Field - includes the start character (*)
1323+
boolean logThisNMEA(); // Return true if we should log this NMEA message
1324+
boolean processThisNMEA(); // Return true if we should pass this NMEA message to processNMEA
1325+
12201326
uint16_t rtcmLen = 0;
12211327

12221328
// Flag to prevent reentry into checkCallbacks

‎src/u-blox_structs.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,66 @@ typedef struct
854854
UBX_NAV_CLOCK_data_t *callbackData;
855855
} UBX_NAV_CLOCK_t;
856856

857+
// UBX-NAV-TIMELS (0x01 0x26): Leap second event information
858+
const uint16_t UBX_NAV_TIMELS_LEN = 24;
859+
860+
typedef struct
861+
{
862+
uint32_t iTOW; // GPS time of week of the navigation epoch: ms
863+
uint8_t version; // Message version (0x00 for this version)
864+
uint8_t reserved1[3];
865+
uint8_t srcOfCurrLs; //Information source for the current number of leap seconds
866+
int8_t currLs; //Current number of leap seconds since start of GPS (Jan 6, 1980), s
867+
uint8_t srcOfLsChange; //Information source for the future leap second event
868+
int8_t lsChange; //Future leap second change if one is scheduled, +1, 0, -1s
869+
int32_t timeToLsEvent; //Num of secs until the next or from the last leap second, s
870+
uint16_t dateOfLsGpsWn; //GPS week num (WN) of the next or the last leap second event
871+
uint16_t dateOfLsGpsDn; //GPS day of week num (DN) for the next or last leap second event
872+
uint8_t reserved2[3];
873+
union
874+
{
875+
uint8_t all;
876+
struct
877+
{
878+
uint8_t validCurrLs : 1; // 1 = Valid current number of leap seconds value
879+
uint8_t validTimeToLsEvent : 1; // 1 = Valid time to next leap second event or from the last leap second event if no future event scheduled
880+
} bits;
881+
} valid;
882+
} UBX_NAV_TIMELS_data_t;
883+
884+
typedef struct
885+
{
886+
union
887+
{
888+
uint32_t all;
889+
struct
890+
{
891+
uint32_t all : 1;
892+
893+
uint32_t iTOW : 1;
894+
uint32_t version : 1;
895+
uint32_t srcOfCurrLs : 1;
896+
uint32_t currLs : 1;
897+
uint32_t srcOfLsChange : 1;
898+
uint32_t lsChange : 1;
899+
uint32_t timeToLsEvent : 1;
900+
uint32_t dateOfLsGpsWn : 1;
901+
uint32_t dateOfLsGpsDn : 1;
902+
uint32_t validCurrLs : 1;
903+
uint32_t validTimeToLsEvent : 1;
904+
} bits;
905+
} moduleQueried;
906+
} UBX_NAV_TIMELS_moduleQueried_t;
907+
908+
typedef struct
909+
{
910+
ubxAutomaticFlags automaticFlags;
911+
UBX_NAV_TIMELS_data_t data;
912+
UBX_NAV_TIMELS_moduleQueried_t moduleQueried;
913+
void (*callbackPointer)(UBX_NAV_TIMELS_data_t);
914+
UBX_NAV_TIMELS_data_t *callbackData;
915+
} UBX_NAV_TIMELS_t;
916+
857917
// UBX-NAV-SVIN (0x01 0x3B): Survey-in data
858918
const uint16_t UBX_NAV_SVIN_LEN = 40;
859919

0 commit comments

Comments
 (0)
Please sign in to comment.