Arduino stops logging data too early [RocketScience]

Hello guys,

We are couple of students making parachute deployment system and sensor value(pressure, height, gyro, temperature and time) logging for our rocket.

We are using Arduino DUE, BMP 085 barometer, MPU 6050 accel/gyro (but using only gyro data), and logging everything to mSD card using sparkfun mSD card shield.

THE PROBLEM: Our sketch works normally and prints data lines to serial monitor and to the microSD card parallel til some time (usually around 600s) and then it just stops logging data (like even when it was in the middle of the line ). It produce no errors or anything, it just stops. Also, pretty much always it spits out few weird values before completely stopping (see screenshot attached). When we reset the arduino, it does the same thing: it works okay for approximately 600 seconds (and we need more, at least 15-20mins/900-1200s) and it stops again. We have tried many ideas trying to determine the cause of this, but the closest we got was, when we commented the line (disabled) where arduino writes data line to sd card, but we left untouched where it outputs the same data line to serial monitor only. In this configuration (outputs only to serial monitor, but not to sd card) our code works without problems for like 4 hours straight without any hiccups.
We have tried few different SD cards, we have changed the SD card shield/adapter, but the problem of stopping still remained when logging to serial and to the card.

We would really appreciate any tips or ideas what could be causing this.

P.S. We are just learning and experimenting with everything, so our code at the moment looks like one big draft.

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <I2Cdev.h>   //""
#include <MPU6050.h>  //''
#include <SimpleTimer.h>
#include <Math.h>   //""

// =========================================
// ===              VARIABLES               ===
// =========================================
int a=1;  // Drogue deploy height (m) below Apogee 
int b=2;  //Main deploy height (m) below Apogee
int angl=70;  //Drogue deploy when rockets angle greater than degrees
int anglPin = 12; //Pins for various I/O
int drogPin = 11;   
int mainPin = 10; 

int gndIgnPin = 7;
int TCPin = 6;
int ardIgnPin =5;

//_______________________________________________

//File dataFile;
MPU6050 akcelerometr;
Adafruit_BMP085 bmp;
#define LED_PIN 13
bool blinkState = false;
bool drogueFired = true;
bool mainFired = true;
bool angleReached = true;
float apogee = 0;
float alt = 0;
const int chipSelect = 8; //SD card CS
int sent_time = 1;


// Enter constant numbers 
// For later calculations
const float pi = 3.1415;
// Number of measurement samples will be conducted
const int number_of_samples = 20;  // const int count = 100 sample
// Variable naming
int16_t ax, ay, az;
float x, y, z;
int  number;
float _angle_x, angle_x, _angle_y, angle_y;
long ax_p, ay_p, az_p;

float groundAltitude;
float maxHeight;


//________________TIMER______________________

SimpleTimer timer;
void repeatMe() {
//   Serial.print("(ms): ");
  // Serial.print(millis()/10);
   //Serial.print("\t");
   sent_time = 1;   
}

// ==========================================
// ===                      INITIAL SETUP                       ===
// ==========================================

void setup() 
 {
    // initialise I2C
    Wire.begin();
    // Select the higher speed serial port
    Serial.begin(115200);
    timer.setInterval(200, repeatMe); // How often data line will be printed (ms)

 //Initialize SD card
    Serial.println(F("Initializing data storage..."));
    pinMode(chipSelect, OUTPUT);
    pinMode(8, OUTPUT);
    digitalWrite(8,HIGH);  
  if (!SD.begin(chipSelect))
        {
        Serial.println("Card failed, or not present");
        }
         Serial.println("MicroSD storage initialized!");

       //connecting barometer
    if (!bmp.begin()) 
        {
        Serial.println("Could not find a valid BMP085 sensor, check wiring!");
    //    while (1) {}
        }
        groundAltitude = (bmp.readAltitude());
    
       // Initialize the accelerometer 
    akcelerometr.initialize();
   // If it throws an error displays a message
    if (akcelerometr.testConnection());
    Serial.println("Accelerometer initialized");
// ==========================================
// ===                   PYRO INITIALISATION                 ===
// ==========================================

    // configure Arduino LED for

    pinMode(LED_PIN, OUTPUT);
    pinMode(mainPin, OUTPUT);// 2m drop
    pinMode(drogPin, OUTPUT);// 1m drop
    pinMode(anglPin, OUTPUT); // angle
    
    
    pinMode(gndIgnPin, INPUT);// Ignition from ground signal
    pinMode(TCPin, INPUT);// Tower clear 
    pinMode(ardIgnPin, OUTPUT);// Ignition signal from arduino to thruster through OPTO
    
    
     // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
//    dataFile = SD.open("Data.txt", FILE_WRITE);

}

// =====================================
// ===                    MAIN PROGRAM LOOP       ===
// =====================================

void loop() {
  
timer.run();
// Finds all the values from the accelerometer
    akcelerometr.getAcceleration(&ax, &ay, &az);
    // We add the necessary number of values
    ax_p = ax_p + ax;
    ay_p = ay_p + ay;
    az_p = az_p + az;
    // Auxiliary determine the number of samples
    number++;
    // When it reaches a certain number of samples 
    if (number == number_of_samples)   // count == the number of samples)
    {
     // Find average values
     x = ax_p/number_of_samples;
     y = ay_p/number_of_samples;
     z = az_p/number_of_samples;
    // Calculate the slope and tilt
     angle_x = atan2(x, sqrt((y)*(y) + (z)*(z))      )/(pi/180);
     angle_y = atan2(y, sqrt((x)*(x) + (z)*(z))      )/(pi/180);
     // Reset the value for further use  
     number = 0;
     ax_p = 0;
     ay_p = 0;
     az_p = 0;
      
    
    if (millis()<100) // time needed for filter to start working
    {
       alt=(bmp.readAltitude());
    }
    else
    {
       alt=(6*alt+bmp.readAltitude())/7; // low freq filter 
    }
    //Serial.print(alt); Serial.print("\t"); 
    digitalWrite(10,LOW);  // main
    digitalWrite(11,LOW);  //drogue
    digitalWrite(12,LOW);  //angle
    if  (alt>apogee) apogee=alt;// remember max. apogee value  
    {
       
     //  Serial.print(apogee); Serial.print("\t"); 
    }
       
    if(drogueFired && (apogee - alt >= a)) // when altitude drops 1 meter for drougue
    {
      digitalWrite(11,HIGH);
    drogueFired = !drogueFired;
    }

    if(mainFired && (apogee - alt >= b)) // when altitude drops 2 meter for main
    {
      digitalWrite(10,HIGH);
    

     mainFired = !mainFired;
    }
      if(angle_x > angl  ||  angle_x < -angl || angle_y > angl  ||  angle_y  < -angl) // for angle
   
     digitalWrite(12,HIGH);
     /*
      if( angleReached && (angle_x > angl  ||  angle_x < -angl || angle_y > angl  ||  angle_y  < -angl))
   {
     digitalWrite(12,HIGH);

    angleReached = !angleReached;
   }
   */
//   ____________________________________________________________________________

      // blink LED to indicate activity
    blinkState = !blinkState;
    digitalWrite(LED_PIN, blinkState);  
     
maxHeight = apogee - groundAltitude;
  
// ===============================================
// ===                   WRITING TO SERIAL AND SD CARD          ===
// ===============================================

 File dataFile = SD.open("Data1.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (sent_time == 1)
  {
     sent_time = 0;

 // make a string for assembling the data to log:
  String dataString = "ms: ";
  dataString += String(millis()/10);
  dataString += ("\t");
  dataString += ("C/Pa\t");
  dataString += String(bmp.readTemperature());
  dataString += ("\t");
  dataString += String(bmp.readPressure());
  dataString += ("\t");
  dataString += ("Raw/alti/apogee/diff\t");
  dataString += String(bmp.readAltitude());
  dataString += ("\t");
  dataString += String(alt);
  dataString += ("\t");
  dataString += String(apogee);
  dataString += ("\t");
  dataString += String(maxHeight);
  dataString += ("\t");
  dataString += ("pitch/roll \t");
  dataString += String(angle_x);
  dataString += ("\t");
  dataString += String(angle_y-3.1);
  dataString += ("\t");
  
  Serial.println(dataString);
  dataFile.println(dataString);
  
  dataFile.close();
   
}
    }
}

Look at what you find on the sd card. Are you sure it is doing what you want it to do in the first 600s? I don’t understand many things in your code, for example:

if (millis() < 100) // time needed for filter to start working
    {
      alt = (bmp.readAltitude());
    }

This will be executed only within the first 100ms after powering up the arduino and never again after that. Are you sure that’s what you want to do?

I would try a different SD library and cutting down the length of the log entries as a first step.

lg, couka

Your use of String variables is a problem. You are very likely running out of memory.
Don't use Strings. Use a single, reusable character array, together with sprintf() to format your data.

String dataString = "ms: ";
  dataString += String(millis()/10);
  dataString += ("\t");
  dataString += ("C/Pa\t");
  dataString += String(bmp.readTemperature());
  dataString += ("\t");
  dataString += String(bmp.readPressure());