Arduino freezes randomly using MPU6050 and SD shield

Hello!

I’m trying to log the acceleration measured by a MPU6050 on a GY-521 breakout board on a microSD card using a microSD shield made by Sparkfun.

Because the MPU6050_DMP6 sketch from the MPU6050 library of Jeff Rowberg (also using his I2Cdev lib) and the dataLogger sketch from the SDfat library both worked very good (when runnning alone) i thought i could combine them to achieve my goal.
I deleted the (for my use) unnecessary code and instead of printing the acceleration data to the serial monitor i print it to the logfile.
But this is not working so great. The sketch stops working completely random. Sometimes it runs for a couple of minutes, sometimes only for a few seconds. When it freezes i have to reset the arduino and it runs again for some time.
I just can’t figure out what the problem is.

Here is what i already tried:

  1. check the connections
    SD shield is just put on top of the arduino
    MPU → Arduino
    VCC → 5V
    GND → GND
    SCL → Analog 5
    SDA → Analog 4
    INT → Digital 2
    solder points look good

  2. check memory usage
    don’t remember the exact value but it was stable and there was enough free memory

  3. a LOT of different approaches how to handle the data
    all with pretty much the same results, i will spare you the details because mostly it was “try and error”

Here is the loop-function of the described basic sketch (due to character limit per post the full code is attached to this post):

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

void loop() 
{
  // if programming failed, don't try to do anything
  if (!dmpReady) return;
    
  // wait for MPU interrupt
  while (!mpuInterrupt && fifoCount < packetSize) 
  {
   // other program behavior stuff here
        // .
        // .
        // .
        // if you are really paranoid you can frequently test in between other
        // stuff to see if mpuInterrupt is true, and if so, "break;" from the
        // while() loop to immediately process the MPU data
        // .
        // .
        // .
  }

    // reset interrupt flag and get INT_STATUS byte
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count
    fifoCount = mpu.getFIFOCount();

    // check for overflow (this should never happen unless our code is too inefficient)
    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
        // reset so we can continue cleanly
        mpu.resetFIFO();
        Serial.println(F("FIFO overflow!"));

    // otherwise, check for DMP data ready interrupt (this should happen frequently)
    } else if (mpuIntStatus & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

        // read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);
        
        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;

        // get real acceleration, adjusted to remove gravity
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetAccel(&aa, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
        
        file.print(aaReal.x);
        file.write(tab);
        file.print(aaReal.y);
        file.write(tab);
        file.println(aaReal.z);
 
        // Force data to SD and update the directory entry to avoid data loss.
        if (!file.sync() || file.getWriteError()) Serial.println(F("write error"));
        
        if (!digitalRead(BUTTON_PIN)) 
        {
          // Close file and stop.
          file.close();
          Serial.println(F("Done"));
          while(1) {}
        }
    }
}

If you have any ideas how to solve this issue, any help will be greatly appreciated.
wambo

MPU_dataLOGGER.ino (9.07 KB)

No ideas?

Some wild guesses what the problem could be would also be good. I will try everything. Getting pretty desperate at this point.

Scotty, we need more power to the warp drive!!

Capin, I'm kicking her as hard as I kin.

You're not driveing your setup with a 9Volt brick are you? Obviously, my first guess is a power issue.

Next, look for sources of spurious input signals.

Good luck.

thanks for your reply!

tried it usb powered and with a 9V block. same result.

power doesn't seem to be the problem. i tried a sketch where i'm just polling the sensorvalues from the analog pins (so DMP is disabled) and save them to a CSV exactly like in this sketch. runs as long as power is on. according to the datasheet of the mpu6050 uses only 0.1mA more if you use the DMP additionally to the gyro and the acceleerometer. since this is such a small difference i don't think it's the cause of the problem.

what do you mean with "look for sources of spurious input signals"? usually the recorded values are good.

oh and btw i'm aware that the code i posted here produces a lot of FIFO overflows but those are handled well and should not cause any problems. except for missed datapoints maybe. but i can live with that for now. and i also tried a sketch which produces not one overflow but nevertheless it freezes at some point.

its really not because of the power supply. i hooked the arduino up with a 9v battery and even put a capacitor parallel to it to compensate peaks. same result

It's because Wire library hangs, when there is a problem with I2C communication. And this problem here is created by a time sensitive MPU6050. Look here :

http://forum.arduino.cc/index.php?topic=254984.msg1809585#msg1809585

thanks for your reply waski!

i already tried this (with 0x09). doesn'T really help except for fifo overflows. also a sample rate lower 20Hz would be pretty useless for this application.

i don't understand how the FIFO rate would in any way cause or solve problems with I2C communication... could you explain, please?