Hey Guys
I want to implement PPK for a project at my university, where we want to analyze the movement of avalanches. Which requires us to just safe the data locally on the Arduino board.
For this, I have a custom Arduino board with a SD card to store the data and a ZED F9P GPS module. I can’t figure out how to safe the .uxb logs(The ones from the U-Center) to my SD card.
So I could convert the ubx logs to NAV and OBS Data in RTCONV and then use RTKPOST for PPK.
My Code so far only safes simple GPS-Data to the SD Card, which was needed for the first test.
Any help would be greatly appreciated. Thanks guys
#include <Arduino.h>
#include <SPI.h>
#include <SdFat.h>
#include <SparkFun_u-blox_GNSS_v3.h>
#define SPI_SD_CS_PIN 5
#define SPI_SD_MOSI_PIN 9
#define SPI_SD_MISO_PIN 6
#define SPI_SD_SCK_PIN 28
SPIClass SD_SPI(&sercom1, SPI_SD_MISO_PIN, SPI_SD_SCK_PIN, SPI_SD_MOSI_PIN, SPI_PAD_3_SCK_1, SERCOM_RX_PAD_2);
#define SD_CONFIG SdSpiConfig(SPI_SD_CS_PIN, DEDICATED_SPI, SD_SCK_MHZ(4), &SD_SPI) // test with 4 MHZ was 16
SdFat sd;
File dataFile;
File rinexFile;
TwoWire SYS_I2C(&sercom5, 3, 2);
TwoWire GPS_I2C(&sercom4, 16, 17);
SFE_UBLOX_GNSS myGNSS;
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to u-blox module.
uint8_t interruptPin = 28;
volatile int repetitions = 1;
struct GNSSTime {
uint8_t hour;
uint8_t minute;
uint8_t second;
uint16_t millisecond;
uint8_t day;
uint8_t month;
uint16_t year;
};
void setup()
{
pinMode(interruptPin, INPUT_PULLUP);
pinMode(43, OUTPUT); // 43 SD-Card
digitalWrite(43, HIGH);
pinMode(45, OUTPUT); //45 Z9P | 41 M10Q
digitalWrite(45, HIGH);
GPS_I2C.begin();
delay(2000);
Serial.begin(115200);
unsigned long startTime = millis();
while(!Serial && (millis() - startTime < 1000)) // Wait max 1 seconds
{
delay(10);
}
Serial.println("Start");
if(!sd.begin(SD_CONFIG))
{
Serial.println("SD card initialization failed");
sd.initErrorHalt(&Serial);
}
Serial.println("SD card initialized!");
sd.ls(&Serial, LS_SIZE);
Serial.println("End");
if (myGNSS.begin(GPS_I2C, 0x42) == false)
{
Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing."));
while (1)
;
}
}
String formatGNSSDate(const GNSSTime& time) {
char buffer[20];
snprintf(buffer, sizeof(buffer), "%02d/%02d/%d",
time.day, time.month, time.year);
return String(buffer);
}
String formatGNSSTime(const GNSSTime& time) {
char buffer[20];
snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d.%u",
time.hour, time.minute, time.second, time.millisecond);
return String(buffer);
}
void saveGPSDataToSD(const GNSSTime& time,long latitude, long longitude, long altitude, byte fixType, byte RTK)
{
// Open the file. Only one file can be open at a time,
// so you have to close this one before opening another.
dataFile = sd.open("gps_data.txt", FILE_WRITE);
// If the file is available, write to it:
if (dataFile) {
// Write time data first
dataFile.print(time.year);
dataFile.print("/");
dataFile.print(time.month);
dataFile.print("/");
dataFile.print(time.day);
dataFile.print(" ");
dataFile.print(time.hour);
dataFile.print(":");
dataFile.print(time.minute);
dataFile.print(":");
dataFile.print(time.second);
dataFile.print(".");
dataFile.print(time.millisecond);
dataFile.print(",");
dataFile.print(millis());
dataFile.print(",");
dataFile.print(latitude);
dataFile.print(",");
dataFile.print(longitude);
dataFile.print(",");
dataFile.print(altitude);
dataFile.print(",");
dataFile.print(fixType);
dataFile.print(",");
dataFile.println(RTK);
dataFile.close();
Serial.println("Data saved to SD card");
}
// If the file isn't open, pop up an error:
else {
Serial.println("Error opening gps_data.txt");
}
}
void loop()
{
//Query module only every second. Doing it more often will just cause I2C traffic.
if (millis() - lastTime > 1000)
{
lastTime = millis(); //Update the timer
// Get GNSS time
GNSSTime time;
if (myGNSS.getPVT()) { // Get time from PVT data
time.hour = myGNSS.getHour();
time.minute = myGNSS.getMinute();
time.second = myGNSS.getSecond();
time.millisecond = myGNSS.getMillisecond();
time.day = myGNSS.getDay();
time.month = myGNSS.getMonth();
time.year = myGNSS.getYear();
// Print time to console
Serial.print("Date: ");
Serial.print(formatGNSSDate(time));
Serial.print(" Time: ");
Serial.print(formatGNSSTime(time));
Serial.print(" | ");
}
long latitude = myGNSS.getLatitude();
Serial.print(F("Lat: "));
Serial.print(latitude);
long longitude = myGNSS.getLongitude();
Serial.print(F(" Long: "));
Serial.print(longitude);
long altitude = myGNSS.getAltitude();
Serial.print(F(" Alt: "));
Serial.print(altitude);
byte fixType = myGNSS.getFixType();
Serial.print(F(" Fix: "));
if(fixType == 0) Serial.print(F("No fix"));
else if(fixType == 1) Serial.print(F("Dead reckoning"));
else if(fixType == 2) Serial.print(F("2D"));
else if(fixType == 3) Serial.print(F("3D"));
else if(fixType == 4) Serial.print(F("GNSS + Dead reckoning"));
else if(fixType == 5) Serial.print(F("Time only"));
byte RTK = myGNSS.getCarrierSolutionType();
Serial.print(" RTK: ");
Serial.print(RTK);
if (RTK == 0) Serial.print(F(" (No solution)"));
else if (RTK == 1) Serial.print(F(" (High precision floating fix)"));
else if (RTK == 2) Serial.print(F(" (High precision fix)"));
Serial.println();
// Save GPS data to SD card
saveGPSDataToSD(time, latitude, longitude, altitude, fixType, RTK);
}
}