SD card fails after random amount of time

Hello-

I am trying to log data from multiple sensors (10dof IMU and pitot tube) to a SD card. However I have run into a problem of the SD card failing to be recognized after a certain amount of time. I have run many tests and the time at which this happens seems to be very random, with the shortest occurring at less than a minute and the longest occurring at almost 10 minutes. One note here is that I am logging data at a relatively high rate (131 hz), though I don't know if that is the cause. I am using a class 4 SD card. There is also a button to start the data logging and a light to show when it is still logging data. I have tried to force it to reconnect to the SD card by making it create a new file when it encounters an error (shown by the new addition section), but it changed nothing. I have also monitored the memory usage and it is decreasing, but extremely slowly (1 byte per 2 minutes or so) and the free memory has never gotten below 503 bytes. Does anyone have any ideas to help me solve this issue?

Thanks for your help!

Below is my code:

const int buttonPin = 2;
#include <Wire.h>
//#include <SPI.h>
#include <SD.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_LSM303_U.h>
#include <Adafruit_BMP085_U.h>
#include <Adafruit_L3GD20_U.h>
#include <Adafruit_10DOF.h>
#include <MemoryFree.h>

/* Assign a unique ID to the sensors */
Adafruit_10DOF                dof   = Adafruit_10DOF();
Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(30301);
Adafruit_LSM303_Mag_Unified   mag   = Adafruit_LSM303_Mag_Unified(30302);
Adafruit_L3GD20_Unified       gyro  = Adafruit_L3GD20_Unified(20);
Adafruit_BMP085_Unified       bmp   = Adafruit_BMP085_Unified(18001);

/* Update this with the correct SLP for accurate altitude measurements */
//float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;

int chipSelect = 4; // select the CS port
File dataFile;
unsigned int time;
int A_in;
unsigned long TimeStart;
char filename[] = "FLIGHT00.csv"; // set the default filename

/**************************************************************************/
/*!
    @brief  Initialises all the sensors used by this example
*/
/**************************************************************************/
void initSensors()
{
  if (!accel.begin())
  {
    /* There was a problem detecting the LSM303 ... check your connections */
    //Serial.println(F("Ooops, no LSM303 detected ... Check your wiring!"));
    while (1);
  }
  if (!mag.begin())
  {
    /* There was a problem detecting the LSM303 ... check your connections */
    //Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
    while (1);
  }
  if (!bmp.begin())
  {
    /* There was a problem detecting the BMP180 ... check your connections */
    //Serial.println("Ooops, no BMP180 detected ... Check your wiring!");
    while (1);
  }

  gyro.enableAutoRange(true);
  if (!gyro.begin())
  {
    //Serial.println("There was a problem with the gyro you dipshit");
    while (1);
  }
  TimeStart = millis();
}

/**************************************************************************/
/*!

*/
/**************************************************************************/
void setup(void)
{
  pinMode(buttonPin, INPUT);
  pinMode(8, OUTPUT);
  pinMode(A3, INPUT);
  while (digitalRead(buttonPin) == LOW) {
    delay(1000);
  };
  Serial.begin(9600);
  //Serial.println(F("Adafruit 10 DOF Pitch/Roll/Heading Example")); Serial.println("");

  /* Initialise the sensors */
  initSensors();
  /*
    while (!Serial) {
    ;
    }
  */

  //Serial.print("Initializing SD card...");
  //SD.begin(4);
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    //Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  //Serial.println("card initialized.");

  for (byte i = 1; i <= 99; i++)
  {
    if (SD.exists(filename))
    {
      //filename exists so we need to change the filename
      filename[6] = i / 10 + '0';
      filename[7] = i % 10 + '0';
    } else {
      break; // the filename doesnt exist so we can move on
    }
  }

}



/**************************************************************************/
/*!
    @brief  Constantly check the roll/pitch/heading/altitude/temperature
*/
/**************************************************************************/
void loop(void)
{

  dataFile = SD.open(filename, FILE_WRITE);



  sensors_event_t accel_event;
  sensors_event_t mag_event;
  sensors_event_t bmp_event;
  sensors_vec_t   orientation;
  sensors_event_t gyro_event;

  String dataString;
  //dataString.reserve(62);

  //while(1)
  for (int i = 0; i < 10; ++i)
  {
    dataString = "";
    dataString += millis() - TimeStart;
    dataString += ";";

    //Gets x, y, and z data from gyro
    gyro.getEvent(&gyro_event);
    dataString += gyro_event.gyro.x;
    dataString += ";";
    dataString += gyro_event.gyro.y;
    dataString += ";";
    dataString += gyro_event.gyro.z;
    dataString += ";";

    //Gets x, y, and z data from accelerometer
    accel.getEvent(&accel_event);
    dataString += accel_event.acceleration.x;
    dataString += ";";
    dataString += accel_event.acceleration.y;
    dataString += ";";
    dataString += accel_event.acceleration.z;
    dataString += ";";

    //Gets x, y, and z data from magnetometer
    mag.getEvent(&mag_event);
    dataString += mag_event.magnetic.x;
    dataString += ";";
    dataString += mag_event.magnetic.y;
    dataString += ";";
    dataString += mag_event.magnetic.z;
    dataString += ";";






    dataString += analogRead(A3);
    dataString += ";";
    //Gets pressure, temp, and altitude
    //  bmp.getEvent(&bmp_event);
    //  dataString += bmp_event.pressure;
    //  dataString += ",";
    //  float temperature;
    //  bmp.getTemperature(&temperature);
    //  dataString += bmp.pressureToAltitude(seaLevelPressure, bmp_event.pressure, temperature);
    //  dataString += ",";

    //  dataString += temperature;



    // if the file is available, write to it:
    if (dataFile) {
      dataFile.println(dataString);
      digitalWrite(8, HIGH);
      //dataFile.flush();
      //Serial.println(dataString);

    }

    // if the file isn't open, pop up an error:
    else {
      //Serial.println("error opening datalogs.txt");
      //Serial.println(dataString);
      digitalWrite(8, LOW); // turn off LED

      //New addition
      if (!SD.begin(chipSelect)) {
        Serial.println("Card failed, or not present");  // Try to reconnect the SD card
        // don't do anything more:
        return;
      }
      for (byte i = 1; i <= 99; i++) //the file isn't open so we make a new one
      {
        if (SD.exists(filename))
        {
          //filename exists so we need to create a new file
          filename[6] = i / 10 + '0';
          filename[7] = i % 10 + '0';
        } else {
          break; // the filename doesnt exist so we can move on
        }
      }
      break; //the file isn't open so exit the for loop

      // end new addition

    }

  }
  if (dataFile)
  {
    dataFile.close();
  }
}

Try a simulation of writing dummy datat to your SD card just as quickly. See what happens. That is how I would start troubleshooting.

From SD.h documentation: "Note that even if you don't use the hardware SS pin, it must be left as an output or the SD library won't work."

Uno: pinMode(10, OUTPUT);
Mega: pinMode(53, OUTPUT);