#include "TinyGPSPlus.h" #include "SoftwareSerial.h" #include "LittleFS.h" #include "Arduino.h" #include #include #include #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels #define BUFFER_SIZE 32 #define SCREEN_ADDRESS 0x3C // 0x3D or 0x3C depending on brand Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1, 1700000UL, 1700000UL); SoftwareSerial serial_connection (1, 0); // RX pin, TX pin TinyGPSPlus gps; // GPS object #define button_pin 14 #define led_pin LED_BUILTIN // set up logfile and memory handling File logFile; unsigned long lastWriteFlushMs = 0; unsigned long lastLoggedSecond = 99999; // set up time tracking for GPS String isoTimeUTC() { if (gps.date.isValid() && gps.time.isValid()) { char buf[25]; // YYYY-MM-DDThh:mm:ssZ snprintf(buf, sizeof(buf), "%04d-%02d-%02dT%02d:%02d:%02dZ", (int)gps.date.year(), (int)gps.date.month(), (int)gps.date.day(), (int)gps.time.hour(), (int)gps.time.minute(), (int)gps.time.second()); return String(buf); } return String(""); // unknown yet } // set up header for CSV void writeCSVHeader() { if (!logFile) return; logFile.println(F("time_utc,lat,lon")); } // dump flash memory into CSV and print it to serial monitor void dumpFile() { Serial.println(F("\n----- BEGIN walk.csv -----")); File f = LittleFS.open("/walk.csv", "r"); if (!f) { Serial.println(F("No /walk.csv file found.")); return; } while (f.available()) { Serial.write(f.read()); } f.close(); Serial.println(F("\n----- END walk.csv -----\n")); } void setup() { pinMode(button_pin,INPUT_PULLUP); Serial.begin(9600); // open serial monitor delay(200); Serial.setTimeout(10); serial_connection.begin(9600); // open communication to GPS Serial.println("GPS Start"); // sketch starting // init flash memory if (!LittleFS.begin()) { Serial.println(F("LittleFS mount failed. Did you select a Flash Size with FS? (Tools > Flash Size)")); // You can still run, but logging won't work. } // Open /walk.csv for write (overwrite each run) logFile = LittleFS.open("/walk.csv", "w"); if (!logFile) { Serial.println(F("Failed to open /walk.csv for writing")); } else { writeCSVHeader(); Serial.println(F("Logging to /walk.csv")); } // initialize display display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS); display.clearDisplay(); display.display(); // text settings display.setTextSize(1); display.setTextColor(SSD1306_WHITE); } bool button_up = true; void loop() { // first check for file dump command if (Serial.available()) { char c = Serial.read(); if (c == 'D' || c == 'd') { if (logFile) { Serial.println("dumping logfile"); logFile.flush(); logFile.close(); } dumpFile(); Serial.println("reopening logfile"); // Reopen for continued logging afterward logFile = LittleFS.open("/walk.csv", "a"); } } // clear the buffer display.clearDisplay(); display.setCursor(5, 25); display.print("Waiting for \n coordinates"); display.display(); // while connection is available, encode GPS feedback while(serial_connection.available()) { gps.encode(serial_connection.read()); } // sense if button is down, and record + print full GPS Message if ((digitalRead(button_pin) == LOW) && button_up) { digitalWrite(led_pin,HIGH); Serial.println("BUTTON DOWN_______________ RECORDING"); // if we get a valid location, print it: if (gps.location.isValid()) { double lat = gps.location.lat(); double lon = gps.location.lng(); String tiso = isoTimeUTC(); // print the location to serial Serial.println("Latitude:"); Serial.println(lat, 6); Serial.println("Longitude"); Serial.println(lon, 6); // print the location to display display.clearDisplay(); display.setCursor(5, 25); display.print(lat); display.print(", "); display.print(lon); display.display(); delay(2000); // if the log file is there, print data to the log file if (logFile) { Serial.println("writing to walk.csv"); // CSV: time_utc,lat,lon, logFile.print(tiso); logFile.print(','); logFile.print(lat, 6); logFile.print(','); logFile.print(lon, 6); logFile.print(','); logFile.println(); } else { Serial.println("did not find logfile"); } } else { // print error to serial Serial.println("GPS Location Invalid"); // print error to display display.clearDisplay(); display.setCursor(5, 25); display.print("invalid GPS feedback"); display.display(); delay(1000); } button_up = false; } // when the button goes back up, flush the log file data and turn off the LED else if ((digitalRead(button_pin) == HIGH) && !button_up) { digitalWrite(led_pin,LOW); button_up = true; logFile.flush(); } // print status every time GPS location is updated //if(gps.location.isUpdated()) //{ //Serial.println("gotlat"); //Serial.println(gps.location.lat(), 6); //Serial.println("gotlong"); //Serial.println(gps.location.lng(), 6); //Serial.println("gotalt"); //Serial.println(gps.altitude.feet()); //} }