Skip to content

Commit 0ee1b2a

Browse files
authored
Merge pull request #10 from sparkfun/master
Update
2 parents 09d1c08 + 2c71ab7 commit 0ee1b2a

File tree

9 files changed

+903
-52
lines changed

9 files changed

+903
-52
lines changed
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+
}

Diff for: examples/Example25_MeasurementAndNavigationRate/Example25_MeasurementAndNavigationRate.ino

-3
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
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+
}

0 commit comments

Comments
 (0)