I'm using an accelerometer and magnetometer to take a tilt compensated heading and write it to a micro SD card. I originally tried with a delay of 100 and when the script continued to crash randomly I slowed it down to a delay of 250ms. I am still having the same issue. I am running the system on a Mini Pro 3.3v 8Mhz ATmega328 using an ADXL345 accelerometer and a HMC5883L Magnetometer connected via TWI. The SD card reader/writer is a sparkfun 3.3v version connected via SPI. Here is the code

if(areConnected) { compass.SetScale(1.3); // Set the scale of the compass. compass.SetMeasurementMode(Measurement_Continuous); // Set the measurement mode to Continuous

accel.SetRange(2, true); // Set the range of the accelerometer to a maximum of 2G. accel.EnableMeasurements(); // Tell the accelerometer to start taking measurements. } Serial.print("Initializing SD card..."); // **SD** make sure that the default chip select pin is set to output, even if you don't use it: pinMode(SS, OUTPUT);

// **SD** 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: digitalWrite(runningPin, LOW); digitalWrite(failurePin, HIGH); while (1); } Serial.println("card initialized.");

float CalculateHeadingTiltCompensated(MagnetometerScaled mag, AccelerometerScaled acc){ // We are swapping the accelerometers axis as they are opposite to the compass the way we have them mounted. // We are swapping the signs axis as they are opposite. // Configure this for your setup. float accX = -acc.XAxis; float accY = -acc.YAxis;

// Some of these are used twice, so rather than computing them twice in the algorithem we precompute them before hand. float cosRoll = cos(rollRadians); float sinRoll = sin(rollRadians); float cosPitch = cos(pitchRadians); float sinPitch = sin(pitchRadians);

accel.SetRange(2, true); // Set the range of the accelerometer to a maximum of 2G. accel.EnableMeasurements(); } Serial.print("Initializing SD card..."); // **SD** make sure that the default chip select pin is set to output, even if you don't use it: pinMode(SS, OUTPUT);

// **SD** see if the card is present and can be initialized: if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); digitalWrite(runningPin, LOW); digitalWrite(failurePin, HIGH); while (1); }

float CalculateHeadingTiltCompensated(MagnetometerScaled mag, AccelerometerScaled acc){ // We are swapping the accelerometers axis as they are opposite to the compass the way we have them mounted. // We are swapping the signs axis as they are opposite. float accX = -acc.XAxis; float accY = -acc.YAxis;

float rollRadians = asin(accY); float pitchRadians = asin(accX);

// We cannot correct for tilt over 40 degrees with this algorithm, if the board is tilted as such, return 0. if (rollRadians > 0.78 || rollRadians < -0.78 || pitchRadians > 0.78 || pitchRadians < -0.78) { return 0; ?? HOW TO DIFFERENTIATE BETWEEN A VALID 0 AND AN ERRONEOUS ZERO }

Serial.print("Error recording at "); Serial.println(recordCount); digitalWrite(runningPin, LOW); digitalWrite(failurePin, HIGH); // while(1); // <<<<<<<<<<<<<<<<<<<<<<<<<< I would remove this one so it can retry if the disk has one bad read. }}

your code has 3 places where it has a blocking stop. E.g. if the SD card does make one bad read (Exists), it blocks. You could rewrite it to have at least 3-5 retries there (log the number of retries! as it can indicate a bad disk.

I happened to experience the same thing with writing a sensor value every 5ms to SRAM (with a GSM shield attached on a arduino mega). In my case I solved it by attaching a 12V battery instead of just the USB cable.