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