ok:
* Get rid of dmpReady
. Just hang in setup
if it doesn't initialize:
} else {
// ERROR!
// 1 = initial memory load failed
// 2 = DMP configuration updates failed
// (if it's going to break, usually the code will be 1)
Serial.print(F("DMP Initialization failed (code "));
Serial.print(devStatus);
Serial.println(F(")"));
for (;;); // stop here
}
* Using the volatile bool mpuInterrupt
is the correct technique, but just test it at the top of loop instead of blocking. You may want to do other things when !mpuInterrupt
(hint, hint). Like check the Altimeter periodically, or toggle an LED periodically.
* You are using the MPU interrupt capability, but you also check the FIFO count. Don't you trust the chip to tell you the truth?
If it says DATA_READY, it really means DATA_READY. loop
should be something like this:
void loop () {
// reset interrupt flag and get INT_STATUS byte
if (mpuInterrupt) {
mpuInterrupt = false;
mpuIntStatus = mpu.getIntStatus();
// check for overflow (this should never happen unless our code is too inefficient)
if (mpuIntStatus & 0x10) {
// 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) {
do {
// read a packet from FIFO
mpu.getFIFOBytes(fifoBuffer, packetSize);
#ifdef OUTPUT_READABLE_YAWPITCHROLL
// display Euler angles in degrees
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
Serial.print("ypr\t");
Serial.print(ypr[0] * 180/M_PI);
Serial.print("\t");
Serial.print(ypr[1] * 180/M_PI);
Serial.print("\t");
Serial.println(ypr[2] * 180/M_PI);
#endif
#ifdef OUTPUT_READABLE_REALACCEL
// display real acceleration, adjusted to remove gravity
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetAccel(&aa, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
Serial.print("areal\t");
Serial.print(aaReal.x);
Serial.print("\t");
Serial.print(aaReal.y);
Serial.print("\t");
Serial.println(aaReal.z);
#endif
#ifdef OUTPUT_READABLE_WORLDACCEL
// display initial world-frame acceleration, adjusted to remove gravity
// and rotated based on known orientation from quaternion
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetAccel(&aa, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
Serial.print("aworld\t");
Serial.print(aaWorld.x);
Serial.print("\t");
Serial.print(aaWorld.y);
Serial.print("\t");
Serial.println(aaWorld.z);
#endif
// Are there more packets waiting?
fifoCount = mpu.getFIFOCount();
} while (fifoCount >= packetSize);
}
/*
// other program behavior stuff here
MPL3115A2_Read();
#ifdef SERIAL_DEBUG
Serial.print( F("Altitude (m): ") );
Serial.println( altitude );
#endif
if (dataFile.isOpen()) {
dataFile.print( F("Altitude (m): ") );
dataFile.println( altitude );
}
// blink LED to indicate activity
// Add blinking of LED with my own library (?!?)
blinkState = !blinkState;
digitalWrite(LED_PIN, blinkState);
*/
}
* Don't block. Never, never, not ever.
* Don't print too much, because Serial.print
will block when there are more than 64 characters to print. You can calculate the printing time with this:
t = (MPU sample frequency) *
(number of characters printed per packet) *
(10 bits/char) / (115200 bits/s)
If this number is more than 1s, you are printing too much.
* Don't use the String
class. There's no reason to assemble a String
so you can print it. Just print the pieces:
MPL3115A2_Read();
#ifdef SERIAL_DEBUG
Serial.print( F("Altitude (m): ") );
Serial.println( altitude );
#endif
if (dataFile.isOpen()) {
dataFile.print( F("Altitude (m): ") );
dataFile.println( altitude );
}
* Did I mention DON'T BLOCK?
//Returns the number of meters above sea level
float readAltitude()
{
...
//Wait for data to become available
int counter = 0;
while(Wire.available() < 3)
While this is waiting for the altitude data the IMU is generating packets. -_- Instead, you have to quickly request a reading, then return. Then test if the reading is available back in loop
. When all 3 bytes are finally ready, use them for a new altitude sample.
* You should read the "Blink without delay" or "How to do several things" examples in Useful Links. Use those techniques to blink the LED and get an altimeter reading periodically.
Cheers,
/dev