Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

Thread: teensy 3.5 freezes when data logging

  1. #1
    Junior Member
    Join Date
    Jul 2020
    Posts
    3

    teensy 3.5 freezes when data logging

    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?


    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(); 
    
           
        }

  2. #2
    Junior Member
    Join Date
    Jul 2020
    Posts
    3
    I think I may have resolved this issue by moving the file open and close commands to right before/after the print commands. This ensures that the file is only being accessed if there is in fact data to write. As the code was written before, every loop would result in a file open/close command, even when it was not necessary!

    That said, I would love to hear any suggestions for improving writing the data to the SD card, if there is a better way.

  3. #3
    Open and close each file exactly once. If you want to make sure data is being written, use flush. Not too often as it can be really slow.

  4. #4
    Junior Member
    Join Date
    Jul 2020
    Posts
    3
    Quote Originally Posted by UhClem View Post
    Open and close each file exactly once.
    Are you suggesting to never add data to an existing file? Like build up a buffer, write that, and never open the file again?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •