I am using a teensy 3.5 to log data from two serial devices. After an hour or two of successful logging, the teensy appears to freeze. If I unplug/replug it starts working again. I'm hoping someone might have some advice on what I can change about the code to make the system more robust.
Below is the full source code. Essentially it loops through the operations of reading serial data and saving to the SD card, and there's some diagnostic code to flash the LED so I can see what state it is in. It should be writing a new line of data at about 10-11 Hz. When the file it is writing to gets larger than 100 kb it creates a new unique filename to write to.
The two things I think could be happening are:
1. The way I'm opening / writing to / closing the file might not be the "right" way.. advice on how to improve that would be great
2. Perhaps the serial communication is freezing - is that possible, and if so, is there something I can do to skip a read if it is holding things up for too long?
Below is the full source code. Essentially it loops through the operations of reading serial data and saving to the SD card, and there's some diagnostic code to flash the LED so I can see what state it is in. It should be writing a new line of data at about 10-11 Hz. When the file it is writing to gets larger than 100 kb it creates a new unique filename to write to.
The two things I think could be happening are:
1. The way I'm opening / writing to / closing the file might not be the "right" way.. advice on how to improve that would be great
2. Perhaps the serial communication is freezing - is that possible, and if so, is there something I can do to skip a read if it is holding things up for too long?
Code:
#include <Chrono.h> //Sketch > Include Library, and add the file downloaded from here: https://www.arduinolibraries.info/libraries/chrono
#include <TinyGPS.h>
#include <SoftwareSerial.h>
#include <SD.h>
#include <HardwareSerial.h>
#include <Arduino.h>
File myFile;// Creates "myFile" as the SD card related commands.
TinyGPS gps;
Chrono GPSTimer;
Chrono LEDLoop;
Chrono LEDGPS;
int good = 13; // LED pin on Teensy
String wind; // variable to hold wind data
float flat, flon;
unsigned long fix_age, time, date; //Date can be added in very easily.
unsigned long age;
unsigned long time_wind_read = 0;
unsigned int LEDstatus = 0;
unsigned int LEDperiod = 100;
unsigned int max_file_size = 100000;
char date_char[6];
char time_char[8];
char fileNameGPS[33];
void setup(){
pinMode(good, OUTPUT); // sets pin 13 as LED OUTPUT pin
Serial3.begin(115200);//, SERIAL_8N1, RX, TX); //BAUD rate of Trisonica mini.
Serial4.begin(9600);// Baud rate of GPS (GP20U7)
while (!SD.begin(BUILTIN_SDCARD)){ //Checks if there is an SD card.
delay(2000);
digitalWrite(good, HIGH);
delay(200);// Blinks and waits until SD card is connected.
digitalWrite(good, LOW);
}
strcpy(date_char, "unknown");
strcpy(time_char, "unknown");
strcpy(fileNameGPS, "unknown.TXT");
}
void loop(){
// LED flashing for diagnostics
if (LEDLoop.hasPassed(LEDperiod)) {
LEDLoop.restart();
if (LEDstatus==0) {
LEDstatus = 1;
digitalWrite(good, HIGH);
}
else {
LEDstatus = 0;
digitalWrite(good, LOW);
}
}
// open file to write
myFile = SD.open(fileNameGPS, FILE_WRITE); //Open most recently created file.
// save data from wind sensor serial device
if (Serial3.available()){
wind = Serial3.readStringUntil('\n');//updates wind data when new data is available
myFile.print("WIND:: ");
myFile.print(" millis: ");
myFile.print(millis());
myFile.print(" " + wind);
myFile.print("\n");
time_wind_read = millis();
}
//save GPS data with Teensy time-stamp
if (Serial4.available()){
char c = Serial4.read();
gps.encode(c); //GPS parser.
if (GPSTimer.hasPassed(500)){
GPSTimer.restart();
gps.f_get_position(&flat, &flon, &age);
// time in hhmmsscc, date in ddmmyy
gps.get_datetime(&date, &time, &fix_age);
myFile.print("GPS:: ");
myFile.print(" millis: ");
myFile.print(millis());
myFile.print(" UTCTime: ");
myFile.print(time);//UTC Time stamp 7 hours ahead of Reno time.
myFile.print(" UTCDate: ");
myFile.print(date);
myFile.print(" Latitude: ");
myFile.print(flat, 6);//Latitude
myFile.print(" Longitude: ");
myFile.print(flon, 6);//Longitude
myFile.print(" Satellite: ");
myFile.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
myFile.print("\n");
// LED flashing for diagnostics
if ((millis() - time_wind_read) < 100) {
if (date!=0) {
LEDperiod = 25; // GPS and wind are writing
}
else {
LEDperiod = 100; // wind is writing, but not GPS
}
}
else {
if (date!=0) {
LEDperiod = 200; // GPS writing, but not wind
}
else {
LEDperiod = 1000; // nothing is writing
}
}
}
}
// as soon as GPS date available switch to new file
if (strcmp(fileNameGPS, "unknown.TXT")==0) {
if (date!=0) {
ltoa(time/100, time_char, 10);
strcpy(fileNameGPS, "W"); // can only have 8 characters in filename!!!
strcat(fileNameGPS, time_char);
strcat(fileNameGPS, ".TXT");
}
}
// every time file too big, make new file
else {
if (myFile.size() > max_file_size){
ltoa(time/100, time_char, 10);
strcpy(fileNameGPS, "W"); // can only have 8 characters in filename!!!
strcat(fileNameGPS, time_char);
strcat(fileNameGPS, ".TXT");
}
}
//Save the data to the file.
myFile.close();
}