This code is bad. Don't use this fork as an example. I don't know if this shows up publicly.
Dependencies: MPU6050-DMP mbed
Fork of MPU6050_Example by
Revision 2:07e29b6d29da, committed 2015-03-18
- Comitter:
- majik
- Date:
- Wed Mar 18 22:21:23 2015 +0000
- Parent:
- 1:ec0a08108442
- Commit message:
- This program successfully sends the DMP data for 2 IMUs.; Only modification required: Lowered the DMP data rate so the FIFO buffer doesn't overflow.
Changed in this revision
| MPU6050-DMP.lib | Show annotated file Show diff for this revision Revisions of this file |
| main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/MPU6050-DMP.lib Sat Nov 23 16:47:59 2013 +0000 +++ b/MPU6050-DMP.lib Wed Mar 18 22:21:23 2015 +0000 @@ -1,1 +1,1 @@ -https://mbed.org/users/syundo0730/code/MPU6050-DMP/#7d1bf3ce0053 +http://developer.mbed.org/users/majik/code/MPU6050-DMP/#d348c3cad7c7
--- a/main.cpp Sat Nov 23 16:47:59 2013 +0000
+++ b/main.cpp Wed Mar 18 22:21:23 2015 +0000
@@ -48,6 +48,7 @@
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
+#include "MPU6051_6Axis_MotionApps20.h"
//#include "MPU6050.h" // not necessary if using MotionApps include file
// class default I2C address is 0x68
@@ -56,6 +57,7 @@
// AD0 high = 0x69
MPU6050 mpu;
+MPU6051 mpu2;
/* =========================================================================
NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch
@@ -77,10 +79,10 @@
const float M_PI = 3.14159265;
-// uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual
+//uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual
// quaternion components in a [w, x, y, z] format (not best for parsing
// on a remote host such as Processing or something though)
-//#define OUTPUT_READABLE_QUATERNION
+#define OUTPUT_READABLE_QUATERNION
// uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles
// (in degrees) calculated from the quaternions coming from the FIFO.
@@ -93,7 +95,7 @@
// from the FIFO. Note this also requires gravity vector calculations.
// Also note that yaw/pitch/roll angles suffer from gimbal lock (for
// more info, see: http://en.wikipedia.org/wiki/Gimbal_lock)
-//#define OUTPUT_READABLE_YAWPITCHROLL
+#define OUTPUT_READABLE_YAWPITCHROLL
// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration
// components with gravity removed. This acceleration reference frame is
@@ -118,7 +120,14 @@
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount; // count of all bytes currently in FIFO
-uint8_t fifoBuffer[64]; // FIFO storage buffer
+uint8_t fifoBuffer[128]; // FIFO storage buffer
+
+bool dmpReady2 = false; // set true if DMP init was successful
+uint8_t mpuIntStatus2; // holds actual interrupt status byte from MPU
+uint8_t devStatus2; // return status after each device operation (0 = success, !0 = error)
+uint16_t packetSize2; // expected DMP packet size (default is 42 bytes)
+uint16_t fifoCount2; // count of all bytes currently in FIFO
+uint8_t fifoBuffer2[128]; // FIFO storage buffer
// orientation/motion vars
Quaternion q; // [w, x, y, z] quaternion container
@@ -129,13 +138,18 @@
float euler[3]; // [psi, theta, phi] Euler angle container
float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
+
// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };
-DigitalOut led1(LED1);
-InterruptIn checkpin(p29);
-Serial pc(USBTX, USBRX);
-
+DigitalOut led1(PTE3);
+InterruptIn checkpin(PTD7); //PTD7, PTD5
+InterruptIn checkpin2(PTD5);
+Serial pc(PTA2,PTA1);
+DigitalOut btSwitch(PTE30);
+DigitalOut imuSwitch(PTD6); //PTD6, PTD4
+DigitalOut imu2Switch(PTD4);
+//int counter = 0;
// ================================================================
// === INTERRUPT DETECTION ROUTINE ===
// ================================================================
@@ -144,14 +158,26 @@
void dmpDataReady() {
mpuInterrupt = true;
}
+volatile bool mpuInterrupt2 = false; // indicates whether MPU interrupt pin has gone high
+void dmpDataReady2() {
+ mpuInterrupt2 = true;
+}
void setup();
void loop();
-
+void loop2();
+Timer t;
int main() {
setup();
+ t.start();
+ pc.baud(115200);
while(1) {
+ // pc.printf("Loopy loop\n\r");
+ //pc.printf("%f\t",t.read());
loop();
+ //pc.printf("\t");
+ loop2();
+ //pc.printf("\n\r");
}
}
@@ -165,7 +191,25 @@
// the baud timing being too misaligned with processor ticks. You must use
// 38400 or slower in these cases, or use some kind of external separate
// crystal solution for the UART timer.
-
+btSwitch = 1;
+imuSwitch = 1;
+imu2Switch = 1;
+wait_ms(200);
+while(!mpu.testConnection()){
+ imuSwitch = 0;
+ wait_ms(100);
+ imuSwitch = 1;
+ wait_ms(200);
+ led1 = !led1;
+}
+while(!mpu2.testConnection()){
+ imu2Switch = 0;
+ wait_ms(100);
+ imu2Switch = 1;
+ wait_ms(200);
+ led1 = !led1;
+}
+pc.baud(115200);
// initialize device
pc.printf("Initializing I2C devices...\r\n");
mpu.initialize();
@@ -175,12 +219,6 @@
if (mpu.testConnection()) pc.printf("MPU6050 connection successful\r\n");
else pc.printf("MPU6050 connection failed\r\n");
- // wait for ready
- //Serial.println(F("\nSend any character to begin DMP programming and demo: "));
- //while (Serial.available() && Serial.read()); // empty buffer
- //while (!Serial.available()); // wait for data
- //while (Serial.available() && Serial.read()); // empty buffer again
-
// load and configure the DMP
pc.printf("Initializing DMP...\r\n");
devStatus = mpu.dmpInitialize();
@@ -213,7 +251,47 @@
pc.printf("%d", devStatus);
pc.printf(")\r\n");
}
+ // initialize device
+ pc.printf("Initializing I2C devices...\r\n");
+ mpu2.initialize();
+ // verify connection
+ pc.printf("Testing device connections...\r\n");
+ if (mpu2.testConnection()) pc.printf("MPU6050 connection successful\r\n");
+ else pc.printf("MPU6050 connection failed\r\n");
+
+ // load and configure the DMP
+ pc.printf("Initializing DMP...\r\n");
+ devStatus2 = mpu2.dmpInitialize();
+
+ // make sure it worked (returns 0 if so)
+ if (devStatus2 == 0) {
+ // turn on the DMP, now that it's ready
+ pc.printf("Enabling DMP...\r\n");
+ mpu2.setDMPEnabled(true);
+
+ // enable Arduino interrupt detection
+ pc.printf("Enabling interrupt detection (Arduino external interrupt 0)...\r\n");
+ checkpin2.rise(&dmpDataReady2);
+
+ mpuIntStatus2 = mpu2.getIntStatus();
+
+ // set our DMP Ready flag so the main loop() function knows it's okay to use it
+ pc.printf("DMP ready! Waiting for first interrupt...\r\n");
+ dmpReady2 = true;
+
+ // get expected DMP packet size for later comparison
+ packetSize2 = mpu2.dmpGetFIFOPacketSize();
+ } else {
+ // ERROR!
+ // 1 = initial memory load failed
+ // 2 = DMP configuration updates failed
+ // (if it's going to break, usually the code will be 1)
+
+ pc.printf("DDMP Initialization failed (code ");
+ pc.printf("%d", devStatus2);
+ pc.printf(")\r\n");
+ }
}
@@ -238,6 +316,8 @@
// .
// .
// .
+ //led1 = !led1;
+ //wait_ms(100);
}
// reset interrupt flag and get INT_STATUS byte
@@ -265,6 +345,8 @@
// (this lets us immediately read more without waiting for an interrupt)
fifoCount -= packetSize;
+
+ printf("\n\r%.4f\t",t.read());
#ifdef OUTPUT_READABLE_QUATERNION
// display quaternion values in easy matrix form: w x y z
mpu.dmpGetQuaternion(&q, fifoBuffer);
@@ -272,7 +354,7 @@
printf("%f\t", q.w);
printf("%f\t", q.x);
printf("%f\t", q.y);
- printf("%f\t\r\n", q.z);
+ printf("%f\t", q.z);
#endif
#ifdef OUTPUT_READABLE_EULER
@@ -282,7 +364,7 @@
printf("euler\t");
printf("%f\t", euler[0] * 180/M_PI);
printf("%f\t", euler[1] * 180/M_PI);
- printf("%f\t\r\n", euler[2] * 180/M_PI);
+ printf("%f\t\", euler[2] * 180/M_PI);
#endif
#ifdef OUTPUT_READABLE_YAWPITCHROLL
@@ -291,9 +373,9 @@
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
printf("ypr\t");
- printf("%f\t", ypr[0] * 180/M_PI);
- printf("%f\t", ypr[1] * 180/M_PI);
- printf("%f\t\r\n", ypr[2] * 180/M_PI);
+ printf("%.4f\t", ypr[0] * 180/M_PI);
+ printf("%.4f\t", ypr[1] * 180/M_PI);
+ printf("%.4f\t", ypr[2] * 180/M_PI);
#endif
#ifdef OUTPUT_READABLE_REALACCEL
@@ -303,9 +385,9 @@
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
printf("areal\t");
- printf("%f\t", aaReal.x);
- printf("%f\t", aaReal.y);
- printf("%f\t\r\n", aaReal.z);
+ printf("%f.4\t", aaReal.x);
+ printf("%f.4\t", aaReal.y);
+ printf("%f.4\t", aaReal.z);
#endif
#ifdef OUTPUT_READABLE_WORLDACCEL
@@ -316,9 +398,9 @@
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
printf("aworld\t");
- printf("%f\t", aaWorld.x);
- printf("%f\t", aaWorld.y);
- printf("%f\t\r\n", aaWorld.z);
+ printf("%f.4\t", aaWorld.x);
+ printf("%f.4\t", aaWorld.y);
+ printf("%f.4\t", aaWorld.z);
#endif
#ifdef OUTPUT_TEAPOT
@@ -338,6 +420,129 @@
#endif
// blink LED to indicate activity
- led1 = !led1;
+ //led1 = !led1;
+ }
+}
+
+
+void loop2() {
+ // if programming failed, don't try to do anything
+ if (!dmpReady2) return;
+
+ // wait for MPU interrupt or extra packet(s) available
+ while (!mpuInterrupt2 && fifoCount2 < packetSize2) {
+ // 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
+ // .
+ // .
+ // .
+ //led1 = !led1;
+ //wait_ms(100);
+ }
+
+ // reset interrupt flag and get INT_STATUS byte
+ mpuInterrupt2 = false;
+ mpuIntStatus2 = mpu2.getIntStatus();
+
+ // get current FIFO count
+ fifoCount2 = mpu2.getFIFOCount();
+
+ // check for overflow (this should never happen unless our code is too inefficient)
+ if ((mpuIntStatus2 & 0x10) || fifoCount2 == 1024) {
+ // reset so we can continue cleanly
+ mpu2.resetFIFO();
+ //Serial.println(F("FIFO overflow!"));
+
+ // otherwise, check for DMP data ready interrupt (this should happen frequently)
+ } else if (mpuIntStatus2 & 0x02) {
+ // wait for correct available data length, should be a VERY short wait
+ while (fifoCount2 < packetSize2) fifoCount2 = mpu2.getFIFOCount();
+
+ // read a packet from FIFO
+ mpu2.getFIFOBytes(fifoBuffer2, packetSize2);
+
+ // track FIFO count here in case there is > 1 packet available
+ // (this lets us immediately read more without waiting for an interrupt)
+ fifoCount2 -= packetSize2;
+
+ #ifdef OUTPUT_READABLE_QUATERNION
+ // display quaternion values in easy matrix form: w x y z
+ mpu2.dmpGetQuaternion(&q, fifoBuffer2);
+ printf("quat\t");
+ printf("%.4f\t", q.w);
+ printf("%.4f\t", q.x);
+ printf("%.4f\t", q.y);
+ printf("%.4f\t", q.z);
+ #endif
+
+ #ifdef OUTPUT_READABLE_EULER
+ // display Euler angles in degrees
+ mpu2.dmpGetQuaternion(&q, fifoBuffer2);
+ mpu2.dmpGetEuler(euler, &q);
+ printf("euler\t");
+ printf("%.4f\t", euler2[0] * 180/M_PI);
+ printf("%.4f\t", euler2[1] * 180/M_PI);
+ printf("%.4f\t", euler2[2] * 180/M_PI);
+ #endif
+
+ #ifdef OUTPUT_READABLE_YAWPITCHROLL
+ // display Euler angles in degrees
+ mpu2.dmpGetQuaternion(&q, fifoBuffer2);
+ mpu2.dmpGetGravity(&gravity, &q);
+ mpu2.dmpGetYawPitchRoll(ypr, &q, &gravity);
+ printf("ypr\t");
+ printf("%.4f\t", ypr[0] * 180/M_PI);
+ printf("%.4f\t", ypr[1] * 180/M_PI);
+ printf("%.4f\t", 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);
+ printf("areal\t");
+ printf("%.4f\t", aaReal.x);
+ printf("%.4f\t", aaReal.y);
+ printf("%.4f\t\r\n", 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.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
+ printf("aworld\t");
+ printf("%f\t", aaWorld.x);
+ printf("%f\t", aaWorld.y);
+ printf("%f\t\r\n", aaWorld.z);
+ #endif
+ /*
+ #ifdef OUTPUT_TEAPOT
+ // display quaternion values in InvenSense Teapot demo format:
+ teapotPacket[2] = fifoBuffer[0];
+ teapotPacket[3] = fifoBuffer[1];
+ teapotPacket[4] = fifoBuffer[4];
+ teapotPacket[5] = fifoBuffer[5];
+ teapotPacket[6] = fifoBuffer[8];
+ teapotPacket[7] = fifoBuffer[9];
+ teapotPacket[8] = fifoBuffer[12];
+ teapotPacket[9] = fifoBuffer[13];
+ for (int i = 0; i < 14; ++i) {
+ pc.send(teapotPacket[i]);
+ }
+ teapotPacket[11]++; // packetCount, loops at 0xFF on purpose
+ #endif*/
+ printf("\r\n");
+ // blink LED to indicate activity
+ //led1 = !led1;
}
}
\ No newline at end of file
