Skip to content

Commit 991a63a

Browse files
committedOct 20, 2022
Create DataLoggingExample7_OpenLogESP32_SPI_SDIO.ino
1 parent 3a1d357 commit 991a63a

File tree

1 file changed

+322
-0
lines changed

1 file changed

+322
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
/*
2+
Configuring the GNSS to automatically send RXM SFRBX and RAWX reports over SPI and log them to file on SD card using full 4-bit SDIO
3+
By: Paul Clark
4+
SparkFun Electronics
5+
Date: October 20th, 2022
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 RXM SFRBX and RAWX reports automatically
10+
and log the data to SD card in UBX format.
11+
12+
This code is written for the OpenLog ESP32 (DEV-20594) - coming soon!
13+
14+
Hardware set-up:
15+
Close the DSEL jumper on the ZED-F9P breakout - to select SPI mode
16+
Connect:
17+
OpenLog ESP32 : ZED-F9P
18+
GND GND
19+
3V3_SW 3V3
20+
SCK (18) SCK
21+
PICO (23) PICO (MOSI)
22+
POCI (19) POCI (MISO)
23+
33 CS
24+
25+
** Please note: this example will only work on u-blox ADR or High Precision GNSS or Time Sync products **
26+
27+
Data is logged in u-blox UBX format.
28+
29+
Feel like supporting open source hardware?
30+
Buy a board from SparkFun!
31+
OpenLog ESP32: https://www.sparkfun.com/products/20594
32+
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
33+
NEO-M8P RTK: https://www.sparkfun.com/products/15005
34+
*/
35+
36+
#define GNSS_CS 33 // Connect the ZED-F9P CS pin to OpenLog ESP32 pin 33
37+
#define EN_3V3_SW 32 // The 3.3V_SW regulator Enable pin is connected to D32
38+
#define STAT_LED 25 // The OpenLog ESP32 STAT LED is connected to pin 25
39+
#define IMU_CS 5 // The ISM330 IMU CS is connected to pin 5
40+
#define MAG_CS 27 // The MMC5983 Mag CS is connected to pin 27
41+
42+
#include "FS.h"
43+
#include "SD_MMC.h"
44+
File myFile;
45+
46+
#include <SPI.h>
47+
#define spiPort SPI
48+
49+
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_GNSS
50+
SFE_UBLOX_GNSS myGNSS;
51+
52+
#define sdWriteSize 512 // Write data to the SD card in blocks of 512 bytes
53+
#define fileBufferSize 16384 // Allocate 16KBytes of RAM for UBX message storage
54+
uint8_t *myBuffer; // Use myBuffer to hold the data while we write it to SD card
55+
56+
unsigned long lastPrint; // Record when the last Serial print took place
57+
58+
// Note: we'll keep a count of how many SFRBX and RAWX messages arrive - but the count will not be completely accurate.
59+
// If two or more SFRBX messages arrive together as a group and are processed by one call to checkUblox, the count will
60+
// only increase by one.
61+
62+
int numSFRBX = 0; // Keep count of how many SFRBX message groups have been received (see note above)
63+
int numRAWX = 0; // Keep count of how many RAWX message groups have been received (see note above)
64+
65+
// Callback: newSFRBX will be called when new RXM SFRBX data arrives
66+
// See u-blox_structs.h for the full definition of UBX_RXMSFRBX_data_t
67+
// _____ You can use any name you like for the callback. Use the same name when you call setAutoRXMSFRBXcallback
68+
// / _____ This _must_ be UBX_RXM_SFRBX_data_t
69+
// | / _____ You can use any name you like for the struct
70+
// | | /
71+
// | | |
72+
void newSFRBX(UBX_RXM_SFRBX_data_t *ubxDataStruct)
73+
{
74+
numSFRBX++; // Increment the count
75+
}
76+
77+
// Callback: newRAWX will be called when new RXM RAWX data arrives
78+
// See u-blox_structs.h for the full definition of UBX_RXMRAWX_data_t
79+
// _____ You can use any name you like for the callback. Use the same name when you call setAutoRXMRAWXcallback
80+
// / _____ This _must_ be UBX_RXM_RAWX_data_t
81+
// | / _____ You can use any name you like for the struct
82+
// | | /
83+
// | | |
84+
void newRAWX(UBX_RXM_RAWX_data_t *ubxDataStruct)
85+
{
86+
numRAWX++; // Increment the count
87+
}
88+
89+
void setup()
90+
{
91+
delay(1000);
92+
93+
Serial.begin(115200);
94+
Serial.println(F("SparkFun OpenLog ESP32 GNSS Logging : SPI and SDIO"));
95+
96+
pinMode(STAT_LED, OUTPUT); // Flash the STAT LED each time we write to the SD card
97+
digitalWrite(STAT_LED, LOW);
98+
99+
pinMode(GNSS_CS, OUTPUT);
100+
digitalWrite(GNSS_CS, HIGH);
101+
pinMode(IMU_CS, OUTPUT);
102+
digitalWrite(IMU_CS, HIGH);
103+
pinMode(MAG_CS, OUTPUT);
104+
digitalWrite(MAG_CS, HIGH);
105+
106+
pinMode(EN_3V3_SW, OUTPUT); // Enable power for the microSD card and GNSS
107+
digitalWrite(EN_3V3_SW, HIGH);
108+
109+
delay(1000); // Allow time for the SD card to start up
110+
111+
spiPort.begin();
112+
113+
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
114+
// Initialize the GNSS. Wait for a 3D fix. Get the date and time for the log file
115+
116+
Serial.println(F("Initializing the GNSS..."));
117+
118+
//myGNSS.enableDebugging(); // Uncomment this line to see helpful debug messages on Serial
119+
120+
myGNSS.setFileBufferSize(fileBufferSize); // setFileBufferSize must be called _before_ .begin
121+
122+
// Connect to the u-blox module using SPI port, csPin and speed setting
123+
// ublox devices generally work up to 5MHz. We'll use 4MHz for this example:
124+
bool begun = false;
125+
do
126+
{
127+
begun = myGNSS.begin(spiPort, GNSS_CS, 4000000);
128+
if (!begun)
129+
{
130+
Serial.println(F("u-blox GNSS not detected on SPI bus. Please check wiring."));
131+
delay(1000);
132+
}
133+
}
134+
while (!begun);
135+
136+
//myGNSS.factoryDefault(); delay(5000); // Uncomment this line to reset the module back to its factory defaults
137+
138+
myGNSS.setSPIOutput(COM_TYPE_UBX | COM_TYPE_NMEA); //Set the SPI port to output both UBX and NMEA messages
139+
140+
//myGNSS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Optional: save (only) the communications port settings to flash and BBR
141+
142+
Serial.print(F("Waiting for a 3D fix"));
143+
144+
uint8_t fix = 0;
145+
146+
do
147+
{
148+
fix = myGNSS.getFixType();
149+
delay(1000);
150+
Serial.print(F("."));
151+
}
152+
while ( fix != 3 ); // Wait for a 3D fix
153+
154+
Serial.println();
155+
156+
uint16_t y = myGNSS.getYear();
157+
uint8_t M = myGNSS.getMonth();
158+
uint8_t d = myGNSS.getDay();
159+
uint8_t h = myGNSS.getHour();
160+
uint8_t m = myGNSS.getMinute();
161+
uint8_t s = myGNSS.getSecond();
162+
163+
char szBuffer[40] = {'\0'};
164+
snprintf(szBuffer, sizeof(szBuffer), "/%04d%02d%02d%02d%02d%02d.ubx", y, M, d, h, m, s);
165+
166+
Serial.println(F("GNSS initialized."));
167+
168+
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
169+
// Initialize the SD card. Open the log file
170+
171+
Serial.println(F("Initializing SD card..."));
172+
173+
// Begin the SD card
174+
if(!SD_MMC.begin())
175+
{
176+
Serial.println(F("Card mount failed. Freezing..."));
177+
while(1);
178+
}
179+
180+
// Open the log file for writing
181+
Serial.printf("Log file is: %s\r\n", szBuffer);
182+
myFile = SD_MMC.open((const char *)szBuffer, FILE_WRITE);
183+
if(!myFile)
184+
{
185+
Serial.println(F("Failed to open log file for writing. Freezing..."));
186+
while(1);
187+
}
188+
189+
Serial.println(F("SD card initialized."));
190+
191+
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
192+
// Wait for a key press
193+
194+
while (Serial.available()) // Make sure the Serial buffer is empty
195+
{
196+
Serial.read();
197+
}
198+
199+
Serial.println(F("Press any key to start logging."));
200+
201+
while (!Serial.available()) // Wait for the user to press a key
202+
{
203+
; // Do nothing
204+
}
205+
206+
delay(100); // Wait, just in case multiple characters were sent
207+
208+
while (Serial.available()) // Empty the Serial buffer
209+
{
210+
Serial.read();
211+
}
212+
213+
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
214+
// Enable RAWX and SFRBX
215+
216+
myGNSS.setNavigationFrequency(4); // Set navigation rate to 4Hz
217+
218+
myGNSS.setAutoRXMSFRBXcallbackPtr(&newSFRBX); // Enable automatic RXM SFRBX messages with callback to newSFRBX
219+
220+
myGNSS.logRXMSFRBX(); // Enable RXM SFRBX data logging
221+
222+
myGNSS.setAutoRXMRAWXcallbackPtr(&newRAWX); // Enable automatic RXM RAWX messages with callback to newRAWX
223+
224+
myGNSS.logRXMRAWX(); // Enable RXM RAWX data logging
225+
226+
myGNSS.enableNMEAMessage(UBX_NMEA_GGA, COM_PORT_SPI, 1); // Ensure the GxGGA (Global positioning system fix data) message is enabled. Send every measurement.
227+
myGNSS.enableNMEAMessage(UBX_NMEA_GSA, COM_PORT_SPI, 1); // Ensure the GxGSA (GNSS DOP and Active satellites) message is enabled. Send every measurement.
228+
myGNSS.enableNMEAMessage(UBX_NMEA_GSV, COM_PORT_SPI, 1); // Ensure the GxGSV (GNSS satellites in view) message is enabled. Send every measurement.
229+
230+
myGNSS.setNMEALoggingMask(SFE_UBLOX_FILTER_NMEA_ALL); // Enable logging of all enabled NMEA messages
231+
232+
myBuffer = new uint8_t[sdWriteSize]; // Create our own buffer to hold the data while we write it to SD card
233+
234+
Serial.println(F("Press any key to stop logging."));
235+
236+
lastPrint = millis(); // Initialize lastPrint
237+
}
238+
239+
void loop()
240+
{
241+
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
242+
243+
myGNSS.checkUblox(); // Check for the arrival of new data and process it.
244+
myGNSS.checkCallbacks(); // Check if any callbacks are waiting to be processed.
245+
246+
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
247+
248+
while (myGNSS.fileBufferAvailable() >= sdWriteSize) // Check to see if we have at least sdWriteSize waiting in the buffer
249+
{
250+
digitalWrite(STAT_LED, HIGH); // Flash the STAT LED each time we write to the SD card
251+
252+
myGNSS.extractFileBufferData(myBuffer, sdWriteSize); // Extract exactly sdWriteSize bytes from the UBX file buffer and put them into myBuffer
253+
254+
myFile.write(myBuffer, sdWriteSize); // Write exactly sdWriteSize bytes from myBuffer to the ubxDataFile on the SD card
255+
256+
// In case the SD writing is slow or there is a lot of data to write, keep checking for the arrival of new data
257+
myGNSS.checkUblox(); // Check for the arrival of new data and process it.
258+
myGNSS.checkCallbacks(); // Check if any callbacks are waiting to be processed.
259+
260+
digitalWrite(STAT_LED, LOW); // Turn the STAT LED off again
261+
}
262+
263+
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
264+
265+
if (millis() > (lastPrint + 1000)) // Print the message count once per second
266+
{
267+
Serial.print(F("Number of message groups received: SFRBX: ")); // Print how many message groups have been received (see note above)
268+
Serial.print(numSFRBX);
269+
Serial.print(F(" RAWX: "));
270+
Serial.println(numRAWX);
271+
272+
uint16_t maxBufferBytes = myGNSS.getMaxFileBufferAvail(); // Get how full the file buffer has been (not how full it is now)
273+
274+
//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
275+
//Serial.println(maxBufferBytes);
276+
277+
if (maxBufferBytes > ((fileBufferSize / 5) * 4)) // Warn the user if fileBufferSize was more than 80% full
278+
{
279+
Serial.println(F("Warning: the file buffer has been over 80% full. Some data may have been lost."));
280+
}
281+
282+
lastPrint = millis(); // Update lastPrint
283+
}
284+
285+
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
286+
287+
if (Serial.available()) // Check if the user wants to stop logging
288+
{
289+
uint16_t remainingBytes = myGNSS.fileBufferAvailable(); // Check if there are any bytes remaining in the file buffer
290+
291+
while (remainingBytes > 0) // While there is still data in the file buffer
292+
{
293+
digitalWrite(STAT_LED, HIGH); // Flash the STAT LED while we write to the SD card
294+
295+
uint16_t bytesToWrite = remainingBytes; // Write the remaining bytes to SD card sdWriteSize bytes at a time
296+
if (bytesToWrite > sdWriteSize)
297+
{
298+
bytesToWrite = sdWriteSize;
299+
}
300+
301+
myGNSS.extractFileBufferData(myBuffer, bytesToWrite); // Extract bytesToWrite bytes from the UBX file buffer and put them into myBuffer
302+
303+
myFile.write(myBuffer, bytesToWrite); // Write bytesToWrite bytes from myBuffer to the ubxDataFile on the SD card
304+
305+
remainingBytes -= bytesToWrite; // Decrement remainingBytes
306+
}
307+
308+
digitalWrite(STAT_LED, LOW); // Turn the STAT LED off
309+
310+
myFile.close(); // Close the data file
311+
312+
myGNSS.setNavigationFrequency(1); // Set navigation rate to 1Hz
313+
314+
myGNSS.disableMessage(UBX_CLASS_RXM, UBX_RXM_RAWX, COM_PORT_SPI);
315+
myGNSS.disableMessage(UBX_CLASS_RXM, UBX_RXM_SFRBX, COM_PORT_SPI);
316+
317+
Serial.println(F("Logging stopped. Freezing..."));
318+
while(1); // Do nothing more
319+
}
320+
321+
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
322+
}

0 commit comments

Comments
 (0)
Please sign in to comment.