Thanks to chatGPT I finally got a working sketch for a GPS data logger that saves each start/stop button activated session into a single GPX file containing all the data for that session.
But each file/session is saved to the card with an incremental number . What I would achieve is to save each file/session with a date/time stamp coming from the GPS NEMEA data.
I really appreciate any input from somebody.
Following is the code
#include <SPI.h>
#include <SD.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
SoftwareSerial gpsSerial(4, 3); // GPS module on pins 4 (RX) and 3 (TX)
TinyGPSPlus gps;
const int chipSelect = 10;
const int startStopButtonPin = 7;
const int saveWaypointButtonPin = 8;
const int gpsFixLedPin = 6; // LED pin
bool logging = false;
bool buttonState = false; // State of the start/stop button
File logFile;
int logFileIndex = 0; // Log file counter
void setup() {
Serial.begin(9600);
gpsSerial.begin(9600);
pinMode(startStopButtonPin, INPUT_PULLUP);
pinMode(saveWaypointButtonPin, INPUT_PULLUP);
pinMode(gpsFixLedPin, OUTPUT);
digitalWrite(gpsFixLedPin, LOW);
if (!SD.begin(chipSelect)) {
Serial.println("SD card initialization failed!");
while (true); // Stop execution
}
Serial.println("SD card is ready.");
}
void loop() {
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
// Update LED based on GPS fix status and logging status
if (gps.location.isValid()) {
if (logging) {
digitalWrite(gpsFixLedPin, millis() % 1000 < 500 ? HIGH : LOW); // Blink LED
} else {
digitalWrite(gpsFixLedPin, HIGH); // Solid LED
}
} else {
digitalWrite(gpsFixLedPin, LOW); // LED off
}
// Read the state of the start/stop button
bool currentButtonState = digitalRead(startStopButtonPin);
// If the button state has changed
if (currentButtonState != buttonState) {
delay(50); // Button debounce
// If the new button state is pressed
if (currentButtonState == LOW) {
if (!logging && gps.location.isValid()) {
startLogging();
} else {
stopLogging();
}
}
buttonState = currentButtonState; // Update button state
}
// Handle Save Waypoint Button
if (digitalRead(saveWaypointButtonPin) == LOW && logging) {
delay(100); // Button debounce
if (digitalRead(saveWaypointButtonPin) == LOW && gps.location.isValid()) {
saveWaypoint();
}
}
if (logging && gps.location.isUpdated()) {
logGPSData();
}
}
void startLogging() {
char filename[25];
sprintf(filename, "/LOG%03d.GPX", logFileIndex++);
logFile = SD.open(filename, FILE_WRITE);
if (logFile) {
logFile.println("<?xml version=\"1.0\"?>");
logFile.println("<gpx version=\"1.1\" creator=\"Arduino GPS Logger\">");
logFile.println("<trk><name>GPS Track</name><trkseg>");
Serial.println("Started logging GPS data to file: " + String(filename));
logging = true;
} else {
Serial.println("Failed to open log file: " + String(filename));
}
}
void stopLogging() {
if (logFile) {
logFile.println("</trkseg></trk></gpx>");
logFile.close();
Serial.println("Stopped logging GPS data.");
logging = false;
}
}
void saveWaypoint() {
logFile.print("<wpt lat=\"");
logFile.print(gps.location.lat(), 6);
logFile.print("\" lon=\"");
logFile.print(gps.location.lng(), 6);
logFile.print("\"><ele>");
logFile.print(gps.altitude.meters());
logFile.print("</ele><time>");
logFile.print(gps.date.year());
logFile.print("-");
logFile.print(gps.date.month());
logFile.print("-");
logFile.print(gps.date.day());
logFile.print("T");
logFile.print(gps.time.hour());
logFile.print(":");
logFile.print(gps.time.minute());
logFile.print(":");
logFile.print(gps.time.second());
logFile.print("Z</time><sat>");
logFile.print(gps.satellites.value());
logFile.println("</sat></wpt>");
Serial.println("Saved waypoint.");
}
void logGPSData() {
logFile.print("<trkpt lat=\"");
logFile.print(gps.location.lat(), 6);
logFile.print("\" lon=\"");
logFile.print(gps.location.lng(), 6);
logFile.print("\"><ele>");
logFile.print(gps.altitude.meters());
logFile.print("</ele><time>");
logFile.print(gps.date.year());
logFile.print("-");
logFile.print(gps.date.month());
logFile.print("-");
logFile.print(gps.date.day());
logFile.print("T");
logFile.print(gps.time.hour());
logFile.print(":");
logFile.print(gps.time.minute());
logFile.print(":");
logFile.print(gps.time.second());
logFile.print("Z</time><sat>");
logFile.print(gps.satellites.value());
logFile.println("</sat></trkpt>");
Serial.println("Logged GPS data.");
}
P.S.: Pardon for my English .