Jump to content
I2Cdevlib Forums

Search the Community

Showing results for tags 'mpu6050'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • I2Cdevlib Web Tools
    • I2C Protocol Analyzer
    • I2C Device Entry Interface
    • I2C Device Library API
  • I2Cdev Platform Discussion
    • Arduino (ATmega)
    • Arduino Due (ARM Cortex M3)
    • MSP430
    • Other Platforms
  • I2C Device Discussion
    • AD7746 capacitance-to-digital converter (Analog Devices)
    • ADS1115 16-bit A/D converter (Texas Instruments)
    • ADXL345 3-axis accelerometer (Analog Devices)
    • AK8975 3-axis magnetometer (AKM Semiconductor)
    • BMA150 3-axis accelerometer (Bosch Sensortec)
    • BMP085 pressure sensor (Bosch Sensortec)
    • DS1307 real-time clock (Maxim)
    • HMC5843 3-axis magnetometer (Honeywell)
    • HMC5883L 3-axis magnetometer (Honeywell)
    • iAQ-2000 indoor air quality sensor (AppliedSensor)
    • IQS156 ProxSense capacitive touch sensor (Azoteq)
    • ITG-3200 3-axis gyroscope (InvenSense)
    • L3G4200D 3-axis accelerometer (STMicroelectronics)
    • MPL3115A2 Xtrinsic Smart Pressure Sensor (Freescale)
    • MPR121 12-bit capacitive touch sensor (Freescale)
    • MPU-6050 6-axis accelerometer/gyroscope (InvenSense)
    • MPU-9150 9-axis accelerometer/gyroscope/magnetometer (InvenSense)
    • PanelPilot multi-screen digital meter (Lascar Electronics)
    • SSD1308 128x64 OLED/PLED driver (Solomon Systech)
    • TCA6424A 24-bit I/O expander (Texas Instruments)

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


AIM


MSN


Website URL


ICQ


Yahoo


Jabber


Skype


Location


Interests

  1. Hello, I'm encountering problem with function given in the title of this thread. My project is based on angular velocity from the Mpu6050's gyro, but I don't seem to get smooth enough readings. What is happening: - Through first 5-10s after the power up I mostly (not always) get perfect 0.00 reading. - After the internal calibration process ends, output gets dominated by -1.00 reading mixed with the prevoius one. (so it goes radomly like: -1-1-1-10-1000-10-10-1-10...and so on). In this case I can't simply compensate the reading by adding a constant. Is there a way to smooth output value? Also, it prints with the decimals, but it doesn't use them(X.00). How to get better precision with decimals being involved(eg. X.34)? And lastly, just to make sure, are those readings given in deg/s? Why I'm not using only gyro module? Because I'll need precise angle in later development to implement cascade PID. What I have tried/done: - Changing offsets. Result: it only changes output val for those first seconds. After, as I guess, internal calibration process it always ends on reading -1 and 0's. - No external noise is involved(from motors etc.) and MPU (Gy-521) doesn't share power supply with any other device. Conection( MPU - Arduino uno): Vcc - 5v Gnd- Gnd Sda - Sda Scl - Scl AD0- 5v // only with this setup I'm avoiding random sketch hangs... so far. Int - D2 I've modified / shortened Jeff's code (I'm using multiple tab sketch). I'll be grateful for any help. Also, I want to thank you for all the information I could find on this forum. Regards, Arek // I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0) // 6/21/2012 by Jeff Rowberg <jeff@rowberg.net> // Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib // // Changelog: // 2013-05-08 - added seamless Fastwire support // - added note about gyro calibration // 2012-06-21 - added note about Arduino 1.0.1 + Leonardo compatibility error // 2012-06-20 - improved FIFO overflow handling and simplified read process // 2012-06-19 - completely rearranged DMP initialization code and simplification // 2012-06-13 - pull gyro and accel data from FIFO packet instead of reading directly // 2012-06-09 - fix broken FIFO read sequence and change interrupt detection to RISING // 2012-06-05 - add gravity-compensated initial reference frame acceleration output // - add 3D math helper file to DMP6 example sketch // - add Euler output and Yaw/Pitch/Roll output formats // 2012-06-04 - remove accel offset clearing for better results (thanks Sungon Lee) // 2012-06-01 - fixed gyro sensitivity to be 2000 deg/sec instead of 250 // 2012-05-30 - basic DMP initialization working /* ============================================ I2Cdev device library code is placed under the MIT license Copyright (c) 2012 Jeff Rowberg Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =============================================== */ // I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files // for both classes must be in the include path of your project #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" //#include "MPU6050.h" // not necessary if using MotionApps include file // Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation // is used in I2Cdev.h #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif // class default I2C address is 0x68 // specific I2C addresses may be passed as a parameter here // AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board) // AD0 high = 0x69 //MPU6050 mpu; MPU6050 mpu(0x69); // <-- use for AD0 high /* ========================================================================= NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch depends on the MPU-6050's INT pin being connected to the Arduino's external interrupt #0 pin. On the Arduino Uno and Mega 2560, this is digital I/O pin 2. * ========================================================================= */ /* ========================================================================= NOTE: Arduino v1.0.1 with the Leonardo board generates a compile error when using Serial.write(buf, len). The Teapot output uses this method. The solution requires a modification to the Arduino USBAPI.h file, which is fortunately simple, but annoying. This will be fixed in the next IDE release. For more info, see these links: http://arduino.cc/forum/index.php/topic,109987.0.html http://code.google.com/p/arduino/issues/detail?id=958 * ========================================================================= */ #define OUTPUT_READABLE_YAWPITCHROLL #define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6) bool blinkState = false; // MPU control/status vars bool dmpReady = false; // set true if DMP init was successful uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU 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 // orientation/motion vars Quaternion q; // [w, x, y, z] quaternion container VectorFloat gravity; // [x, y, z] gravity vector float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector int16_t gyro[3]; //[x,y,z] // ================================================================ // === INTERRUPT DETECTION ROUTINE === // ================================================================ volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high void dmpDataReady() { mpuInterrupt = true; } // ================================================================ // === INITIAL SETUP === // ================================================================ bool MPU_setup() { // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz). Comment this line if having compilation difficulties with TWBR. #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif // initialize serial communication // (115200 chosen because it is required for Teapot Demo output, but it's // really up to you depending on your project) while (!Serial); // wait for Leonardo enumeration, others continue immediately // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3v or Ardunio // Pro Mini running at 3.3v, cannot handle this baud rate reliably due to // 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. // initialize device Serial.println(F("Initializing I2C devices...")); mpu.initialize(); mpu.setFullScaleGyroRange(0); //set the gyro range to 250 mpu.setFullScaleAccelRange(0); //set the accelerometer sensibilty to 2g Serial.print(F("Gyro sensitivity: ")); Serial.println(mpu.getFullScaleGyroRange()); // print gyro / acc sensitivity Serial.print(F("Acc sensitivity: ")); Serial.println(mpu.getFullScaleAccelRange()); // verify connection Serial.println(F("Testing device connections...")); Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); // load and configure the DMP Serial.println(F("Initializing DMP...")); devStatus = mpu.dmpInitialize(); // supply your own gyro offsets here, scaled for min sensitivity mpu.setXGyroOffset(-30); mpu.setYGyroOffset(-54); mpu.setZGyroOffset(-21); mpu.setXAccelOffset(-3083); mpu.setYAccelOffset(-1972); mpu.setZAccelOffset(754); // make sure it worked (returns 0 if so) if (devStatus == 0) { // turn on the DMP, now that it's ready Serial.println(F("Enabling DMP...")); mpu.setDMPEnabled(true); // enable Arduino interrupt detection Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)...")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); // set our DMP Ready flag so the main loop() function knows it's okay to use it Serial.println(F("DMP ready! Waiting for first interrupt...")); dmpReady = true; // get expected DMP packet size for later comparison packetSize = mpu.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) Serial.print(F("DMP Initialization failed (code ")); Serial.print(devStatus); Serial.println(F(")")); return false; } // configure LED for output pinMode(LED_PIN, OUTPUT); return true; } // ================================================================ // === MAIN PROGRAM LOOP === // ================================================================ void MPU_loop() { // if programming failed, don't try to do anything if (!dmpReady) return; // wait for MPU interrupt or extra packet(s) available 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; #ifdef OUTPUT_READABLE_YAWPITCHROLL // display Euler angles in degrees & angular velocity from gyro mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGyro(gyro, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); #endif // blink LED to indicate activity blinkState = !blinkState; digitalWrite(LED_PIN, blinkState); } } double MPU_gyroX(){ return gyro[0]; }
  2. Hi All, I am New to all this arduino stuff and was wondering if I could get help/see if it is possible to make a profilograph survey device from a arduino and MPU 6050? so a profilograph in a nutshell measures the floor plan every 0.5 sec in degrees which gives you data so that you can get a reading over a said distance. so what I want to do is build a device that is self calibrating (by the click of a push button) and write the data collected from the MPU6050 to a SD card shield and also have the data displayed on a LCD screen so that I know the data is begin collected. So in theory I would need..... Push button = self Calibrating Push Button = Start and Stop SD card Shield = Data files MPU 6050 = data collection Note: the data has to be in degrees so that it will work with a spreadsheet I have and also a filter will have to be in place so it will give me acc readings and be a true plan of the floor. If anyone can give me help or guidance on this (i.e Code, set up filters and the rest) I would be very greatful. Many Thanks.
  3. Hello I am combinig MPU6050 with Encoder for cycle simulation. But as I move the encoder very fastly it stopped automatically giving readings. I am little bit confused whats is the exact problem? My Code #define BAUDRATE 38400 //Encoder //#define pinA A1 #define ARDUINOPIN A2 #define STATE_UNINIT 0 #define STATE_INIT 1 byte systemState; volatile long count; int pinA = 2; int pinB = 3; int limitSW_1 = 4; boolean sigA = 0; boolean sigB = 0; boolean status_L1 = 0; //Ends Encoder //Start MPU #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #include "PinChangeInt.h" #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif #define OUTPUT_READABLE_QUATERNION //#define OUTPUT_READABLE_YAWPITCHROLL //Ends MPU MPU6050 mpu; // MPU control/status vars bool dmpReady = false; uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU 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 // orientation/motion vars Quaternion q; // [w, x, y, z] quaternion container VectorInt16 aa; // [x, y, z] accel sensor measurements VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements VectorFloat gravity; // [x, y, z] gravity vector 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' }; // ================================================================ // === INTERRUPT DETECTION ROUTINE === // ================================================================ volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high void dmpDataReady() { mpuInterrupt = true; } // ================================================================ // === INITIAL SETUP === // ================================================================ void setup() { // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz) #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif Serial.begin(BAUDRATE); //while (!Serial); // mpu.initialize(); devStatus = mpu.dmpInitialize(); mpu.setXGyroOffset(52); mpu.setYGyroOffset(18); mpu.setZGyroOffset(-24); mpu.setZAccelOffset(1030); // 1688 factory default for my test chip if (devStatus == 0) { mpu.setDMPEnabled(true); pinMode(ARDUINOPIN, INPUT_PULLUP); // attachInterrupt(ARDUINOPIN, dmpDataReady, RISING); attachPinChangeInterrupt(ARDUINOPIN, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); dmpReady = true; packetSize = mpu.dmpGetFIFOPacketSize(); } else { } systemState = STATE_UNINIT; // pinMode(pinA, INPUT_PULLUP); // attachPinChangeInterrupt(pinA, interruptA, CHANGE); // pinMode(pinB, INPUT_PULLUP); // attachPinChangeInterrupt(pinB, interruptB, CHANGE); attachInterrupt(0, interruptA, CHANGE); attachInterrupt(1, interruptB, CHANGE); } // ================================================================ // === MAIN PROGRAM LOOP === // ================================================================ void loop() { if (!dmpReady) return; while (!mpuInterrupt && fifoCount < packetSize) {} mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus(); fifoCount = mpu.getFIFOCount(); if ((mpuIntStatus & 0x10) || fifoCount == 1024) { mpu.resetFIFO(); } else if (mpuIntStatus & 0x02) { while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); mpu.getFIFOBytes(fifoBuffer, packetSize); fifoCount -= packetSize; //YPR #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(","); // Serial.print(ypr[1] * 180/M_PI); // Serial.print(","); // Serial.println(ypr[2] * 180/M_PI); #endif //Quaternion #ifdef OUTPUT_READABLE_QUATERNION // display quaternion values in easy matrix form: w x y z mpu.dmpGetQuaternion(&q, fifoBuffer); // Serial.print("quat\t"); Serial.print(q.w); Serial.print(","); Serial.print(q.x); Serial.print(","); Serial.print(q.y); Serial.print(","); Serial.print(q.z); Serial.print(","); #endif Serial.print(count); Serial.print(','); Serial.print(status_L1); Serial.println(); // Stream.flush(); } status_L1 = digitalRead(limitSW_1); if (status_L1 == 1 && false) { count = 0; systemState = STATE_INIT; } // delay(50); } //interupt for PinA void interruptA() { sigA = digitalRead(pinA); switch(sigA) { case 0: if(sigB == 1) count++; else count--; break; case 1: if(sigB == 0) count++; else count--; break; } } //interupt for PinA void interruptB() { sigB = digitalRead(pinB); switch(sigB) { case 0: if(sigA == 0) count++; else count--; break; case 1: if(sigA == 1) count++; else count--; break; } }
  4. I'm trying to calibrate my MPU6050, i tried to follow the guide here: http://www.i2cdevlib.com/forums/topic/91-how-to-decide-gyro-and-accelerometer-offsett/ But the values my sensor gives me were all around: a/g: 3980 1512 3892 -6 70 -9 a/g: 4056 1452 3884 28 51 -19 a/g: 4088 1304 3712 17 49 -14 a/g: 4068 1340 3820 7 66 14 a/g: 4044 1332 3628 40 104 -16 a/g: 4072 1336 3896 2 47 16 a/g: 4088 1332 3760 19 62 -14 a/g: 4004 1448 3728 16 48 -4 a/g: 3980 1444 3740 18 29 -1 a/g: 4112 1432 3828 7 56 14 a/g: 4092 1376 3736 8 55 -4 a/g: 3936 1528 3560 -26 122 -13 When i tried to add this values to my offset, the offset simple gets BIGGER. I tried than using the sketch calibration by Luis Ródenas (i put on pastebin here) It says at the end: Sensor readings with offsets: 7 -4 16382 0 0 0 Your offsets: -426 -165 1525 -3 -14 0 Data is printed as: acelX acelY acelZ giroX giroY giroZ Check that your sensor readings are close to 0 0 16384 0 0 0 If calibration was succesful write down your offsets so you can set them in your projects using something similar to mpu.setXAccelOffset(youroffset) When i add these values to my sensor it gets: a/g: -44 60 16252 -19 -6 -10 a/g: 68 12 16444 14 -14 6 a/g: -132 -44 16340 -3 4 -2 a/g: -68 80 16248 18 10 12 a/g: -28 108 16068 -18 -7 2 a/g: 16 -80 16368 -26 14 -15 a/g: 32 76 16324 -16 4 4 a/g: -8 60 16092 -5 2 7 a/g: 32 -40 16288 2 11 1 a/g: -16 44 16384 14 -14 -3 a/g: -92 32 16608 3 -18 -7 a/g: -80 -88 16384 20 1 -9 The wide range betwen positive and negative numbers here make me worries about my sensor has any problems. Yes it's wired corect. I'm using the raw values to get these values, no i cant use DMP because it uses interuption and my interuption port are being used by my encoders. So i'm being that stupid that can see the problems or theres something here?
  5. Hello I am using MPU6050 + Encoder + Switch. While running the sketch its show output in Serial monitor for some time then suddenly its stop.Please give me some suggestion asap. Code: #define BAUDRATE 9600 //Encoder #define pinA A1 #define STATE_UNINIT 0 #define STATE_INIT 1 byte systemState; volatile long count; //int pinA = 2; int pinB = 3; int limitSW_1 = 4; boolean sigA = 0; boolean sigB = 0; boolean status_L1 = 0; //Ends Encoder //Start MPU #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #include "PinChangeInt.h" #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif #define OUTPUT_READABLE_QUATERNION //#define OUTPUT_READABLE_YAWPITCHROLL //Ends MPU MPU6050 mpu; // MPU control/status vars bool dmpReady = false; uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU 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 // orientation/motion vars Quaternion q; // [w, x, y, z] quaternion container VectorInt16 aa; // [x, y, z] accel sensor measurements VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements VectorFloat gravity; // [x, y, z] gravity vector 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' }; // ================================================================ // === INTERRUPT DETECTION ROUTINE === // ================================================================ volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high void dmpDataReady() { mpuInterrupt = true; } // ================================================================ // === INITIAL SETUP === // ================================================================ void setup() { // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz) #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif Serial.begin(BAUDRATE); //while (!Serial); // mpu.initialize(); devStatus = mpu.dmpInitialize(); mpu.setXGyroOffset(52); mpu.setYGyroOffset(18); mpu.setZGyroOffset(-24); mpu.setZAccelOffset(1030); // 1688 factory default for my test chip if (devStatus == 0) { mpu.setDMPEnabled(true); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); dmpReady = true; packetSize = mpu.dmpGetFIFOPacketSize(); } else { } systemState = STATE_UNINIT; pinMode(pinA, INPUT_PULLUP); attachPinChangeInterrupt(pinA, interruptA, CHANGE); //attachInterrupt(0, interruptA, CHANGE); attachInterrupt(1, interruptB, CHANGE); } // ================================================================ // === MAIN PROGRAM LOOP === // ================================================================ void loop() { if (!dmpReady) return; while (!mpuInterrupt && fifoCount < packetSize) {} mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus(); fifoCount = mpu.getFIFOCount(); if ((mpuIntStatus & 0x10) || fifoCount == 1024) { mpu.resetFIFO(); } else if (mpuIntStatus & 0x02) { while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); mpu.getFIFOBytes(fifoBuffer, packetSize); fifoCount -= packetSize; //YPR #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(","); // Serial.print(ypr[1] * 180/M_PI); // Serial.print(","); // Serial.println(ypr[2] * 180/M_PI); #endif //Quaternion #ifdef OUTPUT_READABLE_QUATERNION // display quaternion values in easy matrix form: w x y z mpu.dmpGetQuaternion(&q, fifoBuffer); // Serial.print("quat\t"); Serial.print(q.w); Serial.print(","); Serial.print(q.x); Serial.print(","); Serial.print(q.y); Serial.print(","); Serial.print(q.z); Serial.print(","); #endif Serial.print(count); Serial.print(','); Serial.print(status_L1); Serial.println(); // Stream.flush(); } status_L1 = digitalRead(limitSW_1); if (status_L1 == 1 && false) { count = 0; systemState = STATE_INIT; } // delay(50); } //interupt for PinA void interruptA() { sigA = digitalRead(pinA); switch(sigA) { case 0: if(sigB == 1) count++; else count--; break; case 1: if(sigB == 0) count++; else count--; break; } } //interupt for PinA void interruptB() { sigB = digitalRead(pinB); switch(sigB) { case 0: if(sigA == 0) count++; else count--; break; case 1: if(sigA == 1) count++; else count--; break; } }
  6. https://tachymoron.wordpress.com/2015/09/13/mpu6050-dmp-example-code-glitchish/
  7. well I dont have any Problem with the arduino sketch and libraries. I can read all the Information from the sensor. My question is related to the dmp integreted in the unit. Als is that mentioned in the Header file "MPU6050_6Axis_MotionApps20.h" many data will be written to different Registers at power on. if i have unterstand the Routine "dmpinitialize" at first a block of Memory will be written (the first Register in which the first Byte will be written is the Register 0x6F") and then configuration data will be written and finally "dmpupdate" data. Is there anyone who can affirm that the first Register in which the first block Memory data will be written at power on is 0x68? and i would appreciate when i got also in which adress the other data will be written? ( i have tried to find it out but until now i cannot get it) i have tried to Display the Content of some Registers from the Serial Monitor provided by arduino IDE. I have added a few line of fuctions from the library "wire" just after the line "devStatus = mpu.dmpInitialize();" My program dont do anything just initialize dmp. the Content of the Register are not equal to any of the series of data to write through the Routine "dmpinitiaze" Please help me to understand what is going!!!!! Ah why am i interested to These adress? I want to reprogramm in Assembler avr and i should These adress at first step known. I would appreciate any Help, even a Suggestion to read up to 10M Byte pdf document.
  8. Hello everybody, We should connect two mpu6050 to an Arduino mega but we don't know how to connect them physically. We know that we have to turn the i2c adress from 0x68 to 0x69 in order to have 2 different adress, one for each sensor. Someone says that it must connect them in parallel but other thinks that it is usefull to set two digital pins high or low to "swich on/off" a sensor in order to read information alternated. moreover we would like to read quarternion or euler data but now we are only able to receive raw data. May anyone help us? thanks
  9. I've connected multiple(3 or more) MPU6050s on an I2C bus and used AD0 pin to control the chips. But after altering the AD0 pin I've to reset the chip to perform the address change. Is it possible to change the chip's address permanently without need to change the external AD0 pin? Regards
  10. This thread is just to ideas and other relevant info on this project My idea is to create an advanced version of a motion / shock sensor alarm use. (Motion = Accel & Shock = Gyro) A bit like NorthQ NQ-10920 - G-sensor or NQ-10030, but more advanced. G-Sensor Only - NQ-10920: http://northq.linux01.dandomain.dk/products/alarm/nq10920.html NQ-10030 is a set with G-sensor, remote control + Sound Unit !! A set - NQ-10030: http://northq.linux01.dandomain.dk/products/alarm/nq10030.html I did a demo code for this, but it is only the beginning.This I upload later, in a post on this thread. Make your bid / ideas about this project. All ideas and otherwise are welcome. Regards.Nicolai
  11. I have mpu6050 interfaced to 8051 micro-controller. I am using this to balance my quadcopter. I googled very much but I did not find how to get value of gyro or accel, every where i found is that it was interfaced to Audrino. When I try to get the WHO_AM_I address values I get them successfully, but when I try to get the gyro values from register 0x43h it shows constantly varying values and are completely random, that is they are not rounding around any value. My question is that is there any initialization required to start getting correct value from gyro? Do I need to write some registers first so that then I could get the gyro values correctly?
  12. I am using arduino leonardo to serially print the raw data from the mpu6050 example given alongwith its library.But after around 10 seconds, it stops sending data....please help
  13. Hi lads, I managed to do the mpu6050 DMP initialization via a PIC24F device using my own straightforward IIC routines. The excercise was based on Jeff Rowberg's MPU6050_6Axis_MotionApps20.h document and the original I2C analysis spreadsheet produced I believe by Noah Zerkin, which I had downloaded back in 2011 i think it was. Many thanks to JR and NZ for their work. I read the 16 bit quaternion data from the FIFO and divide by 16384, to obtain the normalized quaternion (float data type) from which I extract the YPR angles using arctan2() functions for yaw and roll, and an arcsin() function to obtain pitch. The three calculations (2 x arctan2 and 1 x arcsin funcs) involve around 12836 instruction cycles which with my PIC24 running at 16 MIPS take 12836 * 1/16 us = 802.25us ~ .8 ms I have a few questions: 1) Does anybody know if the DMP can output the YPR angles directly as it does with Quat data? 2) What is the significance of the three OTP (one time programmable?) flags? I am referring to the OTP_BNK_VLD bit (bit 0) in registers XG_OFFS_TC (0x00),YG_OFFS_TC (0x01), ZG_OFFS_TC (0x02). I downloaded the MPU HW Offset Registers 1.1.pdf AppNote which makes it clear how to configure your own Gyro and Accel offset values but am not sure how it all ties with the OTP flags. I left the offset registers as is and got quite good YPR angles. 3) Why 32 bit Gyro and Accel data in FIFO when the raw data is available as 16 bit values in the sensor registers? A couple of observations: a) Note that line 298: "0x00, 0x00, 0x00, 0x01, // SET INT_ENABLE at i=22, SPECIAL INSTRUCTION" in MPU6050_6Axis_MotionApps20.h contains 0x00 in the payload field when it should be 0x01. Not a big deal but can mess up your indexing if you use a single function to do the writes. Memory update 6 of 7 is actually a read and not a write. This is reflected in MPU6050_6Axis_MotionApps20.h and in the IIC analyzer file. Nevertheless in my procedure I just wrote the corresponding values as in the rest of the updates. It seems to work OK. Sorry if I posed questions that have been answered elsewhere. I have made an effort to read this and the Invensense forum. If anybody is interested I can make available my code and procedure in the "Other Platforms" section of the forum. Cheers
  14. HELLO, can someone please help me in understanding this code ? Atleast the part that how do you initialize the DMP or get the DMP values ? I want to write my own code and i am trying to refer to this code by jeff rowberg : or atleast point me to resources where i can understand how the reading and initialization of DMP works I have been trying this since weeks now and really need some help : #ifndef _MPU6050_6AXIS_MOTIONAPPS20_H_ #define _MPU6050_6AXIS_MOTIONAPPS20_H_ #include "I2Cdev.h" #include "helper_3dmath.h" // MotionApps 2.0 DMP implementation, built using the MPU-6050EVB evaluation board #define MPU6050_INCLUDE_DMP_MOTIONAPPS20 #include "MPU6050.h" // Tom Carpenter's conditional PROGMEM code // http://forum.arduino.cc/index.php?topic=129407.0 #ifndef __arm__ #include <avr/pgmspace.h> #else // Teensy 3.0 library conditional PROGMEM code from Paul Stoffregen #ifndef __PGMSPACE_H_ #define __PGMSPACE_H_ 1 #include <inttypes.h> #define PROGMEM #define PGM_P const char * #define PSTR(str) (str) #define F(x) x typedef void prog_void; typedef char prog_char; typedef unsigned char prog_uchar; typedef int8_t prog_int8_t; typedef uint8_t prog_uint8_t; typedef int16_t prog_int16_t; typedef uint16_t prog_uint16_t; typedef int32_t prog_int32_t; typedef uint32_t prog_uint32_t; #define strcpy_P(dest, src) strcpy((dest), (src)) #define strcat_P(dest, src) strcat((dest), (src)) #define strcmp_P(a, b) strcmp((a), () #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #define pgm_read_word(addr) (*(const unsigned short *)(addr)) #define pgm_read_dword(addr) (*(const unsigned long *)(addr)) #define pgm_read_float(addr) (*(const float *)(addr)) #define pgm_read_byte_near(addr) pgm_read_byte(addr) #define pgm_read_word_near(addr) pgm_read_word(addr) #define pgm_read_dword_near(addr) pgm_read_dword(addr) #define pgm_read_float_near(addr) pgm_read_float(addr) #define pgm_read_byte_far(addr) pgm_read_byte(addr) #define pgm_read_word_far(addr) pgm_read_word(addr) #define pgm_read_dword_far(addr) pgm_read_dword(addr) #define pgm_read_float_far(addr) pgm_read_float(addr) #endif #endif /* Source is from the InvenSense MotionApps v2 demo code. Original source is * unavailable, unless you happen to be amazing as decompiling binary by * hand (in which case, please contact me, and I'm totally serious). * * Also, I'd like to offer many, many thanks to Noah Zerkin for all of the * DMP reverse-engineering he did to help make this bit of wizardry * possible. */ // NOTE! Enabling DEBUG adds about 3.3kB to the flash program size. // Debug output is now working even on ATMega328P MCUs (e.g. Arduino Uno) // after moving string constants to flash memory storage using the F() // compiler macro (Arduino IDE 1.0+ required). //#define DEBUG #ifdef DEBUG #define DEBUG_PRINT(x) Serial.print(x) #define DEBUG_PRINTF(x, y) Serial.print(x, y) #define DEBUG_PRINTLN(x) Serial.println(x) #define DEBUG_PRINTLNF(x, y) Serial.println(x, y) #else #define DEBUG_PRINT(x) #define DEBUG_PRINTF(x, y) #define DEBUG_PRINTLN(x) #define DEBUG_PRINTLNF(x, y) #endif #define MPU6050_DMP_CODE_SIZE 1929 // dmpMemory[] #define MPU6050_DMP_CONFIG_SIZE 192 // dmpConfig[] #define MPU6050_DMP_UPDATES_SIZE 47 // dmpUpdates[] /* ================================================================================================ * | Default MotionApps v2.0 42-byte FIFO packet structure: | | | | [QUAT W][ ][QUAT X][ ][QUAT Y][ ][QUAT Z][ ][GYRO X][ ][GYRO Y][ ] | | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | | | | [GYRO Z][ ][ACC X ][ ][ACC Y ][ ][ACC Z ][ ][ ] | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | * ================================================================================================ */ // this block of memory gets written to the MPU on start-up, and it seems // to be volatile memory, so it has to be done each time (it only takes ~1 // second though) const unsigned char dmpMemory[MPU6050_DMP_CODE_SIZE] PROGMEM = { // bank 0, 256 bytes 0xFB, 0x00, 0x00, 0x3E, 0x00, 0x0B, 0x00, 0x36, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0xFA, 0x80, 0x00, 0x0B, 0x12, 0x82, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0xFF, 0xFF, 0x45, 0x81, 0xFF, 0xFF, 0xFA, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xE8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7F, 0xFF, 0xFF, 0xFE, 0x80, 0x01, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x03, 0x30, 0x40, 0x00, 0x00, 0x00, 0x02, 0xCA, 0xE3, 0x09, 0x3E, 0x80, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x41, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x2A, 0x00, 0x00, 0x16, 0x55, 0x00, 0x00, 0x21, 0x82, 0xFD, 0x87, 0x26, 0x50, 0xFD, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x05, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x6F, 0x00, 0x02, 0x65, 0x32, 0x00, 0x00, 0x5E, 0xC0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0x8C, 0x6F, 0x5D, 0xFD, 0x5D, 0x08, 0xD9, 0x00, 0x7C, 0x73, 0x3B, 0x00, 0x6C, 0x12, 0xCC, 0x32, 0x00, 0x13, 0x9D, 0x32, 0x00, 0xD0, 0xD6, 0x32, 0x00, 0x08, 0x00, 0x40, 0x00, 0x01, 0xF4, 0xFF, 0xE6, 0x80, 0x79, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xD6, 0x00, 0x00, 0x27, 0x10, // bank 1, 256 bytes 0xFB, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x36, 0xFF, 0xBC, 0x30, 0x8E, 0x00, 0x05, 0xFB, 0xF0, 0xFF, 0xD9, 0x5B, 0xC8, 0xFF, 0xD0, 0x9A, 0xBE, 0x00, 0x00, 0x10, 0xA9, 0xFF, 0xF4, 0x1E, 0xB2, 0x00, 0xCE, 0xBB, 0xF7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x0C, 0xFF, 0xC2, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xCF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3F, 0x68, 0xB6, 0x79, 0x35, 0x28, 0xBC, 0xC6, 0x7E, 0xD1, 0x6C, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x6A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x4D, 0x00, 0x2F, 0x70, 0x6D, 0x00, 0x00, 0x05, 0xAE, 0x00, 0x0C, 0x02, 0xD0, // bank 2, 256 bytes 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x54, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0xFF, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // bank 3, 256 bytes 0xD8, 0xDC, 0xBA, 0xA2, 0xF1, 0xDE, 0xB2, 0xB8, 0xB4, 0xA8, 0x81, 0x91, 0xF7, 0x4A, 0x90, 0x7F, 0x91, 0x6A, 0xF3, 0xF9, 0xDB, 0xA8, 0xF9, 0xB0, 0xBA, 0xA0, 0x80, 0xF2, 0xCE, 0x81, 0xF3, 0xC2, 0xF1, 0xC1, 0xF2, 0xC3, 0xF3, 0xCC, 0xA2, 0xB2, 0x80, 0xF1, 0xC6, 0xD8, 0x80, 0xBA, 0xA7, 0xDF, 0xDF, 0xDF, 0xF2, 0xA7, 0xC3, 0xCB, 0xC5, 0xB6, 0xF0, 0x87, 0xA2, 0x94, 0x24, 0x48, 0x70, 0x3C, 0x95, 0x40, 0x68, 0x34, 0x58, 0x9B, 0x78, 0xA2, 0xF1, 0x83, 0x92, 0x2D, 0x55, 0x7D, 0xD8, 0xB1, 0xB4, 0xB8, 0xA1, 0xD0, 0x91, 0x80, 0xF2, 0x70, 0xF3, 0x70, 0xF2, 0x7C, 0x80, 0xA8, 0xF1, 0x01, 0xB0, 0x98, 0x87, 0xD9, 0x43, 0xD8, 0x86, 0xC9, 0x88, 0xBA, 0xA1, 0xF2, 0x0E, 0xB8, 0x97, 0x80, 0xF1, 0xA9, 0xDF, 0xDF, 0xDF, 0xAA, 0xDF, 0xDF, 0xDF, 0xF2, 0xAA, 0xC5, 0xCD, 0xC7, 0xA9, 0x0C, 0xC9, 0x2C, 0x97, 0x97, 0x97, 0x97, 0xF1, 0xA9, 0x89, 0x26, 0x46, 0x66, 0xB0, 0xB4, 0xBA, 0x80, 0xAC, 0xDE, 0xF2, 0xCA, 0xF1, 0xB2, 0x8C, 0x02, 0xA9, 0xB6, 0x98, 0x00, 0x89, 0x0E, 0x16, 0x1E, 0xB8, 0xA9, 0xB4, 0x99, 0x2C, 0x54, 0x7C, 0xB0, 0x8A, 0xA8, 0x96, 0x36, 0x56, 0x76, 0xF1, 0xB9, 0xAF, 0xB4, 0xB0, 0x83, 0xC0, 0xB8, 0xA8, 0x97, 0x11, 0xB1, 0x8F, 0x98, 0xB9, 0xAF, 0xF0, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xF1, 0xA3, 0x29, 0x55, 0x7D, 0xAF, 0x83, 0xB5, 0x93, 0xAF, 0xF0, 0x00, 0x28, 0x50, 0xF1, 0xA3, 0x86, 0x9F, 0x61, 0xA6, 0xDA, 0xDE, 0xDF, 0xD9, 0xFA, 0xA3, 0x86, 0x96, 0xDB, 0x31, 0xA6, 0xD9, 0xF8, 0xDF, 0xBA, 0xA6, 0x8F, 0xC2, 0xC5, 0xC7, 0xB2, 0x8C, 0xC1, 0xB8, 0xA2, 0xDF, 0xDF, 0xDF, 0xA3, 0xDF, 0xDF, 0xDF, 0xD8, 0xD8, 0xF1, 0xB8, 0xA8, 0xB2, 0x86, // bank 4, 256 bytes 0xB4, 0x98, 0x0D, 0x35, 0x5D, 0xB8, 0xAA, 0x98, 0xB0, 0x87, 0x2D, 0x35, 0x3D, 0xB2, 0xB6, 0xBA, 0xAF, 0x8C, 0x96, 0x19, 0x8F, 0x9F, 0xA7, 0x0E, 0x16, 0x1E, 0xB4, 0x9A, 0xB8, 0xAA, 0x87, 0x2C, 0x54, 0x7C, 0xB9, 0xA3, 0xDE, 0xDF, 0xDF, 0xA3, 0xB1, 0x80, 0xF2, 0xC4, 0xCD, 0xC9, 0xF1, 0xB8, 0xA9, 0xB4, 0x99, 0x83, 0x0D, 0x35, 0x5D, 0x89, 0xB9, 0xA3, 0x2D, 0x55, 0x7D, 0xB5, 0x93, 0xA3, 0x0E, 0x16, 0x1E, 0xA9, 0x2C, 0x54, 0x7C, 0xB8, 0xB4, 0xB0, 0xF1, 0x97, 0x83, 0xA8, 0x11, 0x84, 0xA5, 0x09, 0x98, 0xA3, 0x83, 0xF0, 0xDA, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xD8, 0xF1, 0xA5, 0x29, 0x55, 0x7D, 0xA5, 0x85, 0x95, 0x02, 0x1A, 0x2E, 0x3A, 0x56, 0x5A, 0x40, 0x48, 0xF9, 0xF3, 0xA3, 0xD9, 0xF8, 0xF0, 0x98, 0x83, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0x97, 0x82, 0xA8, 0xF1, 0x11, 0xF0, 0x98, 0xA2, 0x24, 0x08, 0x44, 0x10, 0x64, 0x18, 0xDA, 0xF3, 0xDE, 0xD8, 0x83, 0xA5, 0x94, 0x01, 0xD9, 0xA3, 0x02, 0xF1, 0xA2, 0xC3, 0xC5, 0xC7, 0xD8, 0xF1, 0x84, 0x92, 0xA2, 0x4D, 0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9, 0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0x93, 0xA3, 0x4D, 0xDA, 0x2A, 0xD8, 0x48, 0x69, 0xD9, 0x2A, 0xD8, 0x68, 0x55, 0xDA, 0x32, 0xD8, 0x50, 0x71, 0xD9, 0x32, 0xD8, 0x70, 0x5D, 0xDA, 0x3A, 0xD8, 0x58, 0x79, 0xD9, 0x3A, 0xD8, 0x78, 0xA8, 0x8A, 0x9A, 0xF0, 0x28, 0x50, 0x78, 0x9E, 0xF3, 0x88, 0x18, 0xF1, 0x9F, 0x1D, 0x98, 0xA8, 0xD9, 0x08, 0xD8, 0xC8, 0x9F, 0x12, 0x9E, 0xF3, 0x15, 0xA8, 0xDA, 0x12, 0x10, 0xD8, 0xF1, 0xAF, 0xC8, 0x97, 0x87, // bank 5, 256 bytes 0x34, 0xB5, 0xB9, 0x94, 0xA4, 0x21, 0xF3, 0xD9, 0x22, 0xD8, 0xF2, 0x2D, 0xF3, 0xD9, 0x2A, 0xD8, 0xF2, 0x35, 0xF3, 0xD9, 0x32, 0xD8, 0x81, 0xA4, 0x60, 0x60, 0x61, 0xD9, 0x61, 0xD8, 0x6C, 0x68, 0x69, 0xD9, 0x69, 0xD8, 0x74, 0x70, 0x71, 0xD9, 0x71, 0xD8, 0xB1, 0xA3, 0x84, 0x19, 0x3D, 0x5D, 0xA3, 0x83, 0x1A, 0x3E, 0x5E, 0x93, 0x10, 0x30, 0x81, 0x10, 0x11, 0xB8, 0xB0, 0xAF, 0x8F, 0x94, 0xF2, 0xDA, 0x3E, 0xD8, 0xB4, 0x9A, 0xA8, 0x87, 0x29, 0xDA, 0xF8, 0xD8, 0x87, 0x9A, 0x35, 0xDA, 0xF8, 0xD8, 0x87, 0x9A, 0x3D, 0xDA, 0xF8, 0xD8, 0xB1, 0xB9, 0xA4, 0x98, 0x85, 0x02, 0x2E, 0x56, 0xA5, 0x81, 0x00, 0x0C, 0x14, 0xA3, 0x97, 0xB0, 0x8A, 0xF1, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, 0xD9, 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x84, 0x0D, 0xDA, 0x0E, 0xD8, 0xA3, 0x29, 0x83, 0xDA, 0x2C, 0x0E, 0xD8, 0xA3, 0x84, 0x49, 0x83, 0xDA, 0x2C, 0x4C, 0x0E, 0xD8, 0xB8, 0xB0, 0xA8, 0x8A, 0x9A, 0xF5, 0x20, 0xAA, 0xDA, 0xDF, 0xD8, 0xA8, 0x40, 0xAA, 0xD0, 0xDA, 0xDE, 0xD8, 0xA8, 0x60, 0xAA, 0xDA, 0xD0, 0xDF, 0xD8, 0xF1, 0x97, 0x86, 0xA8, 0x31, 0x9B, 0x06, 0x99, 0x07, 0xAB, 0x97, 0x28, 0x88, 0x9B, 0xF0, 0x0C, 0x20, 0x14, 0x40, 0xB8, 0xB0, 0xB4, 0xA8, 0x8C, 0x9C, 0xF0, 0x04, 0x28, 0x51, 0x79, 0x1D, 0x30, 0x14, 0x38, 0xB2, 0x82, 0xAB, 0xD0, 0x98, 0x2C, 0x50, 0x50, 0x78, 0x78, 0x9B, 0xF1, 0x1A, 0xB0, 0xF0, 0x8A, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x8B, 0x29, 0x51, 0x79, 0x8A, 0x24, 0x70, 0x59, 0x8B, 0x20, 0x58, 0x71, 0x8A, 0x44, 0x69, 0x38, 0x8B, 0x39, 0x40, 0x68, 0x8A, 0x64, 0x48, 0x31, 0x8B, 0x30, 0x49, 0x60, 0xA5, 0x88, 0x20, 0x09, 0x71, 0x58, 0x44, 0x68, // bank 6, 256 bytes 0x11, 0x39, 0x64, 0x49, 0x30, 0x19, 0xF1, 0xAC, 0x00, 0x2C, 0x54, 0x7C, 0xF0, 0x8C, 0xA8, 0x04, 0x28, 0x50, 0x78, 0xF1, 0x88, 0x97, 0x26, 0xA8, 0x59, 0x98, 0xAC, 0x8C, 0x02, 0x26, 0x46, 0x66, 0xF0, 0x89, 0x9C, 0xA8, 0x29, 0x51, 0x79, 0x24, 0x70, 0x59, 0x44, 0x69, 0x38, 0x64, 0x48, 0x31, 0xA9, 0x88, 0x09, 0x20, 0x59, 0x70, 0xAB, 0x11, 0x38, 0x40, 0x69, 0xA8, 0x19, 0x31, 0x48, 0x60, 0x8C, 0xA8, 0x3C, 0x41, 0x5C, 0x20, 0x7C, 0x00, 0xF1, 0x87, 0x98, 0x19, 0x86, 0xA8, 0x6E, 0x76, 0x7E, 0xA9, 0x99, 0x88, 0x2D, 0x55, 0x7D, 0x9E, 0xB9, 0xA3, 0x8A, 0x22, 0x8A, 0x6E, 0x8A, 0x56, 0x8A, 0x5E, 0x9F, 0xB1, 0x83, 0x06, 0x26, 0x46, 0x66, 0x0E, 0x2E, 0x4E, 0x6E, 0x9D, 0xB8, 0xAD, 0x00, 0x2C, 0x54, 0x7C, 0xF2, 0xB1, 0x8C, 0xB4, 0x99, 0xB9, 0xA3, 0x2D, 0x55, 0x7D, 0x81, 0x91, 0xAC, 0x38, 0xAD, 0x3A, 0xB5, 0x83, 0x91, 0xAC, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, 0xD9, 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0x8C, 0x9D, 0xAE, 0x29, 0xD9, 0x04, 0xAE, 0xD8, 0x51, 0xD9, 0x04, 0xAE, 0xD8, 0x79, 0xD9, 0x04, 0xD8, 0x81, 0xF3, 0x9D, 0xAD, 0x00, 0x8D, 0xAE, 0x19, 0x81, 0xAD, 0xD9, 0x01, 0xD8, 0xF2, 0xAE, 0xDA, 0x26, 0xD8, 0x8E, 0x91, 0x29, 0x83, 0xA7, 0xD9, 0xAD, 0xAD, 0xAD, 0xAD, 0xF3, 0x2A, 0xD8, 0xD8, 0xF1, 0xB0, 0xAC, 0x89, 0x91, 0x3E, 0x5E, 0x76, 0xF3, 0xAC, 0x2E, 0x2E, 0xF1, 0xB1, 0x8C, 0x5A, 0x9C, 0xAC, 0x2C, 0x28, 0x28, 0x28, 0x9C, 0xAC, 0x30, 0x18, 0xA8, 0x98, 0x81, 0x28, 0x34, 0x3C, 0x97, 0x24, 0xA7, 0x28, 0x34, 0x3C, 0x9C, 0x24, 0xF2, 0xB0, 0x89, 0xAC, 0x91, 0x2C, 0x4C, 0x6C, 0x8A, 0x9B, 0x2D, 0xD9, 0xD8, 0xD8, 0x51, 0xD9, 0xD8, 0xD8, 0x79, // bank 7, 138 bytes (remainder) 0xD9, 0xD8, 0xD8, 0xF1, 0x9E, 0x88, 0xA3, 0x31, 0xDA, 0xD8, 0xD8, 0x91, 0x2D, 0xD9, 0x28, 0xD8, 0x4D, 0xD9, 0x48, 0xD8, 0x6D, 0xD9, 0x68, 0xD8, 0xB1, 0x83, 0x93, 0x35, 0x3D, 0x80, 0x25, 0xDA, 0xD8, 0xD8, 0x85, 0x69, 0xDA, 0xD8, 0xD8, 0xB4, 0x93, 0x81, 0xA3, 0x28, 0x34, 0x3C, 0xF3, 0xAB, 0x8B, 0xF8, 0xA3, 0x91, 0xB6, 0x09, 0xB4, 0xD9, 0xAB, 0xDE, 0xFA, 0xB0, 0x87, 0x9C, 0xB9, 0xA3, 0xDD, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x95, 0xF1, 0xA3, 0xA3, 0xA3, 0x9D, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0xF2, 0xA3, 0xB4, 0x90, 0x80, 0xF2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xB2, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xA3, 0xB0, 0x87, 0xB5, 0x99, 0xF1, 0xA3, 0xA3, 0xA3, 0x98, 0xF1, 0xA3, 0xA3, 0xA3, 0xA3, 0x97, 0xA3, 0xA3, 0xA3, 0xA3, 0xF3, 0x9B, 0xA3, 0xA3, 0xDC, 0xB9, 0xA7, 0xF1, 0x26, 0x26, 0x26, 0xD8, 0xD8, 0xFF }; // thanks to Noah Zerkin for piecing this stuff together! const unsigned char dmpConfig[MPU6050_DMP_CONFIG_SIZE] PROGMEM = { // BANK OFFSET LENGTH [DATA] 0x03, 0x7B, 0x03, 0x4C, 0xCD, 0x6C, // FCFG_1 inv_set_gyro_calibration 0x03, 0xAB, 0x03, 0x36, 0x56, 0x76, // FCFG_3 inv_set_gyro_calibration 0x00, 0x68, 0x04, 0x02, 0xCB, 0x47, 0xA2, // D_0_104 inv_set_gyro_calibration 0x02, 0x18, 0x04, 0x00, 0x05, 0x8B, 0xC1, // D_0_24 inv_set_gyro_calibration 0x01, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00, // D_1_152 inv_set_accel_calibration 0x03, 0x7F, 0x06, 0x0C, 0xC9, 0x2C, 0x97, 0x97, 0x97, // FCFG_2 inv_set_accel_calibration 0x03, 0x89, 0x03, 0x26, 0x46, 0x66, // FCFG_7 inv_set_accel_calibration 0x00, 0x6C, 0x02, 0x20, 0x00, // D_0_108 inv_set_accel_calibration 0x02, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_00 inv_set_compass_calibration 0x02, 0x44, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_01 0x02, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_02 0x02, 0x4C, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_10 0x02, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_11 0x02, 0x54, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_12 0x02, 0x58, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_20 0x02, 0x5C, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_21 0x02, 0xBC, 0x04, 0x00, 0x00, 0x00, 0x00, // CPASS_MTX_22 0x01, 0xEC, 0x04, 0x00, 0x00, 0x40, 0x00, // D_1_236 inv_apply_endian_accel 0x03, 0x7F, 0x06, 0x0C, 0xC9, 0x2C, 0x97, 0x97, 0x97, // FCFG_2 inv_set_mpu_sensors 0x04, 0x02, 0x03, 0x0D, 0x35, 0x5D, // CFG_MOTION_BIAS inv_turn_on_bias_from_no_motion 0x04, 0x09, 0x04, 0x87, 0x2D, 0x35, 0x3D, // FCFG_5 inv_set_bias_update 0x00, 0xA3, 0x01, 0x00, // D_0_163 inv_set_dead_zone // SPECIAL 0x01 = enable interrupts 0x00, 0x00, 0x00, 0x01, // SET INT_ENABLE at i=22, SPECIAL INSTRUCTION 0x07, 0x86, 0x01, 0xFE, // CFG_6 inv_set_fifo_interupt 0x07, 0x41, 0x05, 0xF1, 0x20, 0x28, 0x30, 0x38, // CFG_8 inv_send_quaternion 0x07, 0x7E, 0x01, 0x30, // CFG_16 inv_set_footer 0x07, 0x46, 0x01, 0x9A, // CFG_GYRO_SOURCE inv_send_gyro 0x07, 0x47, 0x04, 0xF1, 0x28, 0x30, 0x38, // CFG_9 inv_send_gyro -> inv_construct3_fifo 0x07, 0x6C, 0x04, 0xF1, 0x28, 0x30, 0x38, // CFG_12 inv_send_accel -> inv_construct3_fifo 0x02, 0x16, 0x02, 0x00, 0x01 // D_0_22 inv_set_fifo_rate // This very last 0x01 WAS a 0x09, which drops the FIFO rate down to 20 Hz. 0x07 is 25 Hz, // 0x01 is 100Hz. Going faster than 100Hz (0x00=200Hz) tends to result in very noisy data. // DMP output frequency is calculated easily using this equation: (200Hz / (1 + value)) // It is important to make sure the host processor can keep up with reading and processing // the FIFO output at the desired rate. Handling FIFO overflow cleanly is also a good idea. }; const unsigned char dmpUpdates[MPU6050_DMP_UPDATES_SIZE] PROGMEM = { 0x01, 0xB2, 0x02, 0xFF, 0xFF, 0x01, 0x90, 0x04, 0x09, 0x23, 0xA1, 0x35, 0x01, 0x6A, 0x02, 0x06, 0x00, 0x01, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x04, 0x40, 0x00, 0x00, 0x00, 0x01, 0x62, 0x02, 0x00, 0x00, 0x00, 0x60, 0x04, 0x00, 0x40, 0x00, 0x00 }; uint8_t MPU6050::dmpInitialize() { // reset device DEBUG_PRINTLN(F("\n\nResetting MPU6050...")); reset(); delay(30); // wait after reset // enable sleep mode and wake cycle /*Serial.println(F("Enabling sleep mode...")); setSleepEnabled(true); Serial.println(F("Enabling wake cycle...")); setWakeCycleEnabled(true);*/ // disable sleep mode DEBUG_PRINTLN(F("Disabling sleep mode...")); setSleepEnabled(false); // get MPU hardware revision DEBUG_PRINTLN(F("Selecting user bank 16...")); setMemoryBank(0x10, true, true); DEBUG_PRINTLN(F("Selecting memory byte 6...")); setMemoryStartAddress(0x06); DEBUG_PRINTLN(F("Checking hardware revision...")); uint8_t hwRevision = readMemoryByte(); DEBUG_PRINT(F("Revision @ user[16][6] = ")); DEBUG_PRINTLNF(hwRevision, HEX); DEBUG_PRINTLN(F("Resetting memory bank selection to 0...")); setMemoryBank(0, false, false); // check OTP bank valid DEBUG_PRINTLN(F("Reading OTP bank valid flag...")); uint8_t otpValid = getOTPBankValid(); DEBUG_PRINT(F("OTP bank is ")); DEBUG_PRINTLN(otpValid ? F("valid!") : F("invalid!")); // get X/Y/Z gyro offsets DEBUG_PRINTLN(F("Reading gyro offset TC values...")); int8_t xgOffsetTC = getXGyroOffsetTC(); int8_t ygOffsetTC = getYGyroOffsetTC(); int8_t zgOffsetTC = getZGyroOffsetTC(); DEBUG_PRINT(F("X gyro offset = ")); DEBUG_PRINTLN(xgOffset); DEBUG_PRINT(F("Y gyro offset = ")); DEBUG_PRINTLN(ygOffset); DEBUG_PRINT(F("Z gyro offset = ")); DEBUG_PRINTLN(zgOffset); // setup weird slave stuff (?) DEBUG_PRINTLN(F("Setting slave 0 address to 0x7F...")); setSlaveAddress(0, 0x7F); DEBUG_PRINTLN(F("Disabling I2C Master mode...")); setI2CMasterModeEnabled(false); DEBUG_PRINTLN(F("Setting slave 0 address to 0x68 (self)...")); setSlaveAddress(0, 0x68); DEBUG_PRINTLN(F("Resetting I2C Master control...")); resetI2CMaster(); delay(20); // load DMP code into memory banks DEBUG_PRINT(F("Writing DMP code to MPU memory banks (")); DEBUG_PRINT(MPU6050_DMP_CODE_SIZE); DEBUG_PRINTLN(F(" bytes)")); if (writeProgMemoryBlock(dmpMemory, MPU6050_DMP_CODE_SIZE)) { DEBUG_PRINTLN(F("Success! DMP code written and verified.")); // write DMP configuration DEBUG_PRINT(F("Writing DMP configuration to MPU memory banks (")); DEBUG_PRINT(MPU6050_DMP_CONFIG_SIZE); DEBUG_PRINTLN(F(" bytes in config def)")); if (writeProgDMPConfigurationSet(dmpConfig, MPU6050_DMP_CONFIG_SIZE)) { DEBUG_PRINTLN(F("Success! DMP configuration written and verified.")); DEBUG_PRINTLN(F("Setting clock source to Z Gyro...")); setClockSource(MPU6050_CLOCK_PLL_ZGYRO); DEBUG_PRINTLN(F("Setting DMP and FIFO_OFLOW interrupts enabled...")); setIntEnabled(0x12); DEBUG_PRINTLN(F("Setting sample rate to 200Hz...")); setRate(4); // 1khz / (1 + 4) = 200 Hz DEBUG_PRINTLN(F("Setting external frame sync to TEMP_OUT_L[0]...")); setExternalFrameSync(MPU6050_EXT_SYNC_TEMP_OUT_L); DEBUG_PRINTLN(F("Setting DLPF bandwidth to 42Hz...")); setDLPFMode(MPU6050_DLPF_BW_42); DEBUG_PRINTLN(F("Setting gyro sensitivity to +/- 2000 deg/sec...")); setFullScaleGyroRange(MPU6050_GYRO_FS_2000); DEBUG_PRINTLN(F("Setting DMP configuration bytes (function unknown)...")); setDMPConfig1(0x03); setDMPConfig2(0x00); DEBUG_PRINTLN(F("Clearing OTP Bank flag...")); setOTPBankValid(false); DEBUG_PRINTLN(F("Setting X/Y/Z gyro offset TCs to previous values...")); setXGyroOffsetTC(xgOffsetTC); setYGyroOffsetTC(ygOffsetTC); setZGyroOffsetTC(zgOffsetTC); //DEBUG_PRINTLN(F("Setting X/Y/Z gyro user offsets to zero...")); //setXGyroOffset(0); //setYGyroOffset(0); //setZGyroOffset(0); DEBUG_PRINTLN(F("Writing final memory update 1/7 (function unknown)...")); uint8_t dmpUpdate[16], j; uint16_t pos = 0; for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); DEBUG_PRINTLN(F("Writing final memory update 2/7 (function unknown)...")); for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); DEBUG_PRINTLN(F("Resetting FIFO...")); resetFIFO(); DEBUG_PRINTLN(F("Reading FIFO count...")); uint16_t fifoCount = getFIFOCount(); uint8_t fifoBuffer[128]; DEBUG_PRINT(F("Current FIFO count=")); DEBUG_PRINTLN(fifoCount); getFIFOBytes(fifoBuffer, fifoCount); DEBUG_PRINTLN(F("Setting motion detection threshold to 2...")); setMotionDetectionThreshold(2); DEBUG_PRINTLN(F("Setting zero-motion detection threshold to 156...")); setZeroMotionDetectionThreshold(156); DEBUG_PRINTLN(F("Setting motion detection duration to 80...")); setMotionDetectionDuration(80); DEBUG_PRINTLN(F("Setting zero-motion detection duration to 0...")); setZeroMotionDetectionDuration(0); DEBUG_PRINTLN(F("Resetting FIFO...")); resetFIFO(); DEBUG_PRINTLN(F("Enabling FIFO...")); setFIFOEnabled(true); DEBUG_PRINTLN(F("Enabling DMP...")); setDMPEnabled(true); DEBUG_PRINTLN(F("Resetting DMP...")); resetDMP(); DEBUG_PRINTLN(F("Writing final memory update 3/7 (function unknown)...")); for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); DEBUG_PRINTLN(F("Writing final memory update 4/7 (function unknown)...")); for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); DEBUG_PRINTLN(F("Writing final memory update 5/7 (function unknown)...")); for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); DEBUG_PRINTLN(F("Waiting for FIFO count > 2...")); while ((fifoCount = getFIFOCount()) < 3); DEBUG_PRINT(F("Current FIFO count=")); DEBUG_PRINTLN(fifoCount); DEBUG_PRINTLN(F("Reading FIFO data...")); getFIFOBytes(fifoBuffer, fifoCount); DEBUG_PRINTLN(F("Reading interrupt status...")); uint8_t mpuIntStatus = getIntStatus(); DEBUG_PRINT(F("Current interrupt status=")); DEBUG_PRINTLNF(mpuIntStatus, HEX); DEBUG_PRINTLN(F("Reading final memory update 6/7 (function unknown)...")); for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); readMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); DEBUG_PRINTLN(F("Waiting for FIFO count > 2...")); while ((fifoCount = getFIFOCount()) < 3); DEBUG_PRINT(F("Current FIFO count=")); DEBUG_PRINTLN(fifoCount); DEBUG_PRINTLN(F("Reading FIFO data...")); getFIFOBytes(fifoBuffer, fifoCount); DEBUG_PRINTLN(F("Reading interrupt status...")); mpuIntStatus = getIntStatus(); DEBUG_PRINT(F("Current interrupt status=")); DEBUG_PRINTLNF(mpuIntStatus, HEX); DEBUG_PRINTLN(F("Writing final memory update 7/7 (function unknown)...")); for (j = 0; j < 4 || j < dmpUpdate[2] + 3; j++, pos++) dmpUpdate[j] = pgm_read_byte(&dmpUpdates[pos]); writeMemoryBlock(dmpUpdate + 3, dmpUpdate[2], dmpUpdate[0], dmpUpdate[1]); DEBUG_PRINTLN(F("DMP is good to go! Finally.")); DEBUG_PRINTLN(F("Disabling DMP (you turn it on later)...")); setDMPEnabled(false); DEBUG_PRINTLN(F("Setting up internal 42-byte (default) DMP packet buffer...")); dmpPacketSize = 42; /*if ((dmpPacketBuffer = (uint8_t *)malloc(42)) == 0) { return 3; // TODO: proper error code for no memory }*/ DEBUG_PRINTLN(F("Resetting FIFO and clearing INT status one last time...")); resetFIFO(); getIntStatus(); } else { DEBUG_PRINTLN(F("ERROR! DMP configuration verification failed.")); return 2; // configuration block loading failed } } else { DEBUG_PRINTLN(F("ERROR! DMP code verification failed.")); return 1; // main binary block loading failed } return 0; // success } bool MPU6050::dmpPacketAvailable() { return getFIFOCount() >= dmpGetFIFOPacketSize(); } // uint8_t MPU6050::dmpSetFIFORate(uint8_t fifoRate); // uint8_t MPU6050::dmpGetFIFORate(); // uint8_t MPU6050::dmpGetSampleStepSizeMS(); // uint8_t MPU6050::dmpGetSampleFrequency(); // int32_t MPU6050::dmpDecodeTemperature(int8_t tempReg); //uint8_t MPU6050::dmpRegisterFIFORateProcess(inv_obj_func func, int16_t priority); //uint8_t MPU6050::dmpUnregisterFIFORateProcess(inv_obj_func func); //uint8_t MPU6050::dmpRunFIFORateProcesses(); // uint8_t MPU6050::dmpSendQuaternion(uint_fast16_t accuracy); // uint8_t MPU6050::dmpSendGyro(uint_fast16_t elements, uint_fast16_t accuracy); // uint8_t MPU6050::dmpSendAccel(uint_fast16_t elements, uint_fast16_t accuracy); // uint8_t MPU6050::dmpSendLinearAccel(uint_fast16_t elements, uint_fast16_t accuracy); // uint8_t MPU6050::dmpSendLinearAccelInWorld(uint_fast16_t elements, uint_fast16_t accuracy); // uint8_t MPU6050::dmpSendControlData(uint_fast16_t elements, uint_fast16_t accuracy); // uint8_t MPU6050::dmpSendSensorData(uint_fast16_t elements, uint_fast16_t accuracy); // uint8_t MPU6050::dmpSendExternalSensorData(uint_fast16_t elements, uint_fast16_t accuracy); // uint8_t MPU6050::dmpSendGravity(uint_fast16_t elements, uint_fast16_t accuracy); // uint8_t MPU6050::dmpSendPacketNumber(uint_fast16_t accuracy); // uint8_t MPU6050::dmpSendQuantizedAccel(uint_fast16_t elements, uint_fast16_t accuracy); // uint8_t MPU6050::dmpSendEIS(uint_fast16_t elements, uint_fast16_t accuracy); uint8_t MPU6050::dmpGetAccel(int32_t *data, const uint8_t* packet) { // TODO: accommodate different arrangements of sent data (ONLY default supported now) if (packet == 0) packet = dmpPacketBuffer; data[0] = ((packet[28] << 24) + (packet[29] << 16) + (packet[30] << 8) + packet[31]); data[1] = ((packet[32] << 24) + (packet[33] << 16) + (packet[34] << 8) + packet[35]); data[2] = ((packet[36] << 24) + (packet[37] << 16) + (packet[38] << 8) + packet[39]); return 0; } uint8_t MPU6050::dmpGetAccel(int16_t *data, const uint8_t* packet) { // TODO: accommodate different arrangements of sent data (ONLY default supported now) if (packet == 0) packet = dmpPacketBuffer; data[0] = (packet[28] << 8) + packet[29]; data[1] = (packet[32] << 8) + packet[33]; data[2] = (packet[36] << 8) + packet[37]; return 0; } uint8_t MPU6050::dmpGetAccel(VectorInt16 *v, const uint8_t* packet) { // TODO: accommodate different arrangements of sent data (ONLY default supported now) if (packet == 0) packet = dmpPacketBuffer; v -> x = (packet[28] << 8) + packet[29]; v -> y = (packet[32] << 8) + packet[33]; v -> z = (packet[36] << 8) + packet[37]; return 0; } uint8_t MPU6050::dmpGetQuaternion(int32_t *data, const uint8_t* packet) { // TODO: accommodate different arrangements of sent data (ONLY default supported now) if (packet == 0) packet = dmpPacketBuffer; data[0] = ((packet[0] << 24) + (packet[1] << 16) + (packet[2] << 8) + packet[3]); data[1] = ((packet[4] << 24) + (packet[5] << 16) + (packet[6] << 8) + packet[7]); data[2] = ((packet[8] << 24) + (packet[9] << 16) + (packet[10] << 8) + packet[11]); data[3] = ((packet[12] << 24) + (packet[13] << 16) + (packet[14] << 8) + packet[15]); return 0; } uint8_t MPU6050::dmpGetQuaternion(int16_t *data, const uint8_t* packet) { // TODO: accommodate different arrangements of sent data (ONLY default supported now) if (packet == 0) packet = dmpPacketBuffer; data[0] = ((packet[0] << 8) + packet[1]); data[1] = ((packet[4] << 8) + packet[5]); data[2] = ((packet[8] << 8) + packet[9]); data[3] = ((packet[12] << 8) + packet[13]); return 0; } uint8_t MPU6050::dmpGetQuaternion(Quaternion *q, const uint8_t* packet) { // TODO: accommodate different arrangements of sent data (ONLY default supported now) int16_t qI[4]; uint8_t status = dmpGetQuaternion(qI, packet); if (status == 0) { q -> w = (float)qI[0] / 16384.0f; q -> x = (float)qI[1] / 16384.0f; q -> y = (float)qI[2] / 16384.0f; q -> z = (float)qI[3] / 16384.0f; return 0; } return status; // int16 return value, indicates error if this line is reached } // uint8_t MPU6050::dmpGet6AxisQuaternion(long *data, const uint8_t* packet); // uint8_t MPU6050::dmpGetRelativeQuaternion(long *data, const uint8_t* packet); uint8_t MPU6050::dmpGetGyro(int32_t *data, const uint8_t* packet) { // TODO: accommodate different arrangements of sent data (ONLY default supported now) if (packet == 0) packet = dmpPacketBuffer; data[0] = ((packet[16] << 24) + (packet[17] << 16) + (packet[18] << 8) + packet[19]); data[1] = ((packet[20] << 24) + (packet[21] << 16) + (packet[22] << 8) + packet[23]); data[2] = ((packet[24] << 24) + (packet[25] << 16) + (packet[26] << 8) + packet[27]); return 0; } uint8_t MPU6050::dmpGetGyro(int16_t *data, const uint8_t* packet) { // TODO: accommodate different arrangements of sent data (ONLY default supported now) if (packet == 0) packet = dmpPacketBuffer; data[0] = (packet[16] << 8) + packet[17]; data[1] = (packet[20] << 8) + packet[21]; data[2] = (packet[24] << 8) + packet[25]; return 0; } uint8_t MPU6050::dmpGetGyro(VectorInt16 *v, const uint8_t* packet) { // TODO: accommodate different arrangements of sent data (ONLY default supported now) if (packet == 0) packet = dmpPacketBuffer; v -> x = (packet[16] << 8) + packet[17]; v -> y = (packet[20] << 8) + packet[21]; v -> z = (packet[24] << 8) + packet[25]; return 0; } // uint8_t MPU6050::dmpSetLinearAccelFilterCoefficient(float coef); // uint8_t MPU6050::dmpGetLinearAccel(long *data, const uint8_t* packet); uint8_t MPU6050::dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity) { // get rid of the gravity component (+1g = +8192 in standard DMP FIFO packet, sensitivity is 2g) v -> x = vRaw -> x - gravity -> x*8192; v -> y = vRaw -> y - gravity -> y*8192; v -> z = vRaw -> z - gravity -> z*8192; return 0; } // uint8_t MPU6050::dmpGetLinearAccelInWorld(long *data, const uint8_t* packet); uint8_t MPU6050::dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q) { // rotate measured 3D acceleration vector into original state // frame of reference based on orientation quaternion memcpy(v, vReal, sizeof(VectorInt16)); v -> rotate(q); return 0; } // uint8_t MPU6050::dmpGetGyroAndAccelSensor(long *data, const uint8_t* packet); // uint8_t MPU6050::dmpGetGyroSensor(long *data, const uint8_t* packet); // uint8_t MPU6050::dmpGetControlData(long *data, const uint8_t* packet); // uint8_t MPU6050::dmpGetTemperature(long *data, const uint8_t* packet); // uint8_t MPU6050::dmpGetGravity(long *data, const uint8_t* packet); uint8_t MPU6050::dmpGetGravity(VectorFloat *v, Quaternion *q) { v -> x = 2 * (q -> x*q -> z - q -> w*q -> y); v -> y = 2 * (q -> w*q -> x + q -> y*q -> z); v -> z = q -> w*q -> w - q -> x*q -> x - q -> y*q -> y + q -> z*q -> z; return 0; } // uint8_t MPU6050::dmpGetUnquantizedAccel(long *data, const uint8_t* packet); // uint8_t MPU6050::dmpGetQuantizedAccel(long *data, const uint8_t* packet); // uint8_t MPU6050::dmpGetExternalSensorData(long *data, int size, const uint8_t* packet); // uint8_t MPU6050::dmpGetEIS(long *data, const uint8_t* packet); uint8_t MPU6050::dmpGetEuler(float *data, Quaternion *q) { data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); // psi data[1] = -asin(2*q -> x*q -> z + 2*q -> w*q -> y); // theta data[2] = atan2(2*q -> y*q -> z - 2*q -> w*q -> x, 2*q -> w*q -> w + 2*q -> z*q -> z - 1); // phi return 0; } uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) { // yaw: (about Z axis) data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1); // pitch: (nose up/down, about Y axis) data[1] = atan(gravity -> x / sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z)); // roll: (tilt left/right, about X axis) data[2] = atan(gravity -> y / sqrt(gravity -> x*gravity -> x + gravity -> z*gravity -> z)); return 0; } // uint8_t MPU6050::dmpGetAccelFloat(float *data, const uint8_t* packet); // uint8_t MPU6050::dmpGetQuaternionFloat(float *data, const uint8_t* packet); uint8_t MPU6050::dmpProcessFIFOPacket(const unsigned char *dmpData) { /*for (uint8_t k = 0; k < dmpPacketSize; k++) { if (dmpData[k] < 0x10) Serial.print("0"); Serial.print(dmpData[k], HEX); Serial.print(" "); } Serial.print("\n");*/ //Serial.println((uint16_t)dmpPacketBuffer); return 0; } uint8_t MPU6050::dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed) { uint8_t status; uint8_t buf[dmpPacketSize]; for (uint8_t i = 0; i < numPackets; i++) { // read packet from FIFO getFIFOBytes(buf, dmpPacketSize); // process packet if ((status = dmpProcessFIFOPacket(buf)) > 0) return status; // increment external process count variable, if supplied if (processed != 0) *processed++; } return 0; } // uint8_t MPU6050::dmpSetFIFOProcessedCallback(void (*func) (void)); // uint8_t MPU6050::dmpInitFIFOParam(); // uint8_t MPU6050::dmpCloseFIFO(); // uint8_t MPU6050::dmpSetGyroDataSource(uint_fast8_t source); // uint8_t MPU6050::dmpDecodeQuantizedAccel(); // uint32_t MPU6050::dmpGetGyroSumOfSquare(); // uint32_t MPU6050::dmpGetAccelSumOfSquare(); // void MPU6050::dmpOverrideQuaternion(long *q); uint16_t MPU6050::dmpGetFIFOPacketSize() { return dmpPacketSize; } #endif /* _MPU6050_6AXIS_MOTIONAPPS20_H_ */
  15. I am using MPU6050 along with ATtiny2313 avr microcontroller. I want to read the values generated by the DMP in the MPU6050 IMU, but i am not sure as to what to do. i.e. which register contains what value, which register to read ... I tried to understand things by example your code but could not understand anything. Could someone please help me in some way, maybe by pointing me in some direction or some resources. I am trying to write my one code in Embedded C for interfacing and i am succesful in reading in accelerometer and gyroscope values from the MPU6050 IC.
  16. i imported i2cdev.h and mpu6050.h library. But it doesnt work. Help me please. Error code; MPU6050.cpp:1997:6: error: prototype for 'bool MPU6050::getMotionStatus()' does not match any in class 'MPU6050' bool MPU6050::getMotionStatus() { ^ In file included from MPU6050.cpp:37:0: C:\Users\ziya.ozcelik\Documents\Arduino\libraries\MPU6050/MPU6050.h:611:17: error: candidate is: uint8_t MPU6050::getMotionStatus() uint8_t getMotionStatus();
  17. 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 basic sketch i described: ///////////////////////////////////////////////////////////////////////////////// #define BUTTON_PIN 4 ///////////////////////////////////////////////////////////////////////////////// //////////////Includes, Constants and Objects for datalogging//////////////////// #include <SdFat.h> // SD chip select pin. Be sure to disable any other SPI devices such as Enet. const uint8_t chipSelect = 8; //#define LOG_ACC // Log file base name. Must be six characters or less. #define FILE_BASE_NAME "DATA" // Error messages stored in flash. #define error(msg) error_P(PSTR(msg)) // File system object. SdFat sd; // Log file. SdFile file; //Variable for collumn separation ************* char tab = ';'; ///////////////////////////////////////////////////////////////////////////////// //////////////////////Includes, Constants and Objects for MPU//////////////////// #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" //#define OUTPUT_READABLE_REALACCEL // Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation // is used in I2Cdev.h #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif // class default I2C address is 0x68 // specific I2C addresses may be passed as a parameter here // AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board) // AD0 high = 0x69 MPU6050 mpu; //MPU6050 mpu(0x69); // <-- use for AD0 high //#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6) bool blinkState = false; // MPU control/status vars bool dmpReady = false; // set true if DMP init was successful uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU 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 // orientation/motion vars Quaternion q; // [w, x, y, z] quaternion container VectorInt16 aa; // [x, y, z] accel sensor measurements VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements VectorFloat gravity; // [x, y, z] gravity vector 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' }; ///////////////////////////////////////////////////////////////////////////////// //////////////////////////////User functions///////////////////////////////////// //------------------------------------------------------------------------------ // Write data header. void writeHeader() { file.print(F("accel_X")); file.print(tab); file.print(F("accel_Y")); file.print(tab); file.print(F("accel_Z")); file.println(); } //------------------------------------------------------------------------------ // error messages void error_P(const char* msg) { sd.errorHalt_P(msg); } //------------------------------------------------------------------------------ // Interrupt detection volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high void dmpDataReady() { mpuInterrupt = true; } //------------------------------------------------------------------------------ // setup function void setup() { const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1; char fileName[13] = FILE_BASE_NAME "00.CSV"; Serial.begin(115200); //while (!Serial) {} // wait for Leonardo //delay(1000); pinMode(BUTTON_PIN, INPUT_PULLUP); Serial.println(F("Press Button to start")); while(digitalRead(BUTTON_PIN)) {} //wait for button // Initialize the SD card at SPI_HALF_SPEED to avoid bus errors with // breadboards. use SPI_FULL_SPEED for better performance. if (!sd.begin(chipSelect, SPI_FULL_SPEED)) sd.initErrorHalt(); // Find an unused file name. if (BASE_NAME_SIZE > 6) { error("FILE_BASE_NAME too long"); } while (sd.exists(fileName)) { if (fileName[BASE_NAME_SIZE + 1] != '9') { fileName[BASE_NAME_SIZE + 1]++; } else if (fileName[BASE_NAME_SIZE] != '9') { fileName[BASE_NAME_SIZE + 1] = '0'; fileName[BASE_NAME_SIZE]++; } else { error("Can't create file name"); } } if (!file.open(fileName, O_CREAT | O_WRITE | O_EXCL)) error("file.open"); do { delay(10); } while (Serial.read() >= 0); Serial.print(F("Logging to: ")); Serial.println(fileName); // Write data header. writeHeader(); // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz) #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif // initialize device Serial.println(F("Initializing I2C devices...")); mpu.initialize(); // verify connection Serial.println(F("Testing device connections...")); Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); // load and configure the DMP Serial.println(F("Initializing DMP...")); devStatus = mpu.dmpInitialize(); // supply your own gyro offsets here, scaled for min sensitivity mpu.setXGyroOffset(99); mpu.setYGyroOffset(-35); mpu.setZGyroOffset(67); mpu.setZAccelOffset(1106); // 1688 factory default for my test chip // make sure it worked (returns 0 if so) if (devStatus == 0) { // turn on the DMP, now that it's ready Serial.println(F("Enabling DMP...")); mpu.setDMPEnabled(true); // enable Arduino interrupt detection Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)...")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); // set our DMP Ready flag so the main loop() function knows it's okay to use it Serial.println(F("DMP ready! Waiting for first interrupt...")); dmpReady = true; // get expected DMP packet size for later comparison packetSize = mpu.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) Serial.print(F("DMP Initialization failed (code ")); Serial.print(devStatus); Serial.println(F(")")); } // configure LED for output pinMode(13, OUTPUT); } // ================================================================ // === 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
  18. Hi friends, I have managed to read from two mpu6050 on DMP. Both sensors are fitted on a piece of board and are perfectly levelled. My problem is that when I tilt the sensors such that I increase/decrease Roll, the Yaw is changed, even when the sensors are not rotated on the z axis. Is it normal that rolling affects yawing? Furthermore, the change in Yaw for both sensors is not the same, and there will be a difference in yaw of 8 deg between the two sensors for a 45deg rolling. Thanks in advance, Hatt
  19. Hey all, So I'm connecting my MPU6050 to an Arduino micro running the DMP Example code however, every time it says that the mpu connection fails! I ran the i2c scanner to see what address the MPU6050 was in but it says no devices found. I'm not sure what I'm doing wrong. I have the following pins connected: VIN to 5V (also tried 3.3V) GROUND to GROUND SDA to A4 SCL to A5 We've also tried INT to D2. Pictures of my breakout board and overall setup are below. Do you have any idea what could be causing this to go wrong. The light on the MPU lights up so we know that electricity is flowing/it's connecting.
  20. Sorry If this question is already answered or is way too noob.... I am a novice programmer and I dont really know how to get Degrees/second mpu.getRotation(&gx, &gy, &gz); gyroRoll = gx/131.0; gyroPitch = gy/131.0; gyroYaw = gz/131.0; Is this correct ? Does my gyroRoll, gyroPitch, gyroYaw give values in degrees/second? I want the values to use in my quadcopter code... Also I didnt change any default sensitivity in my MPU6050. Actually I am using Hextronik Nanowii V01 flight controller which is Arduino Leonardo. Also I got another doubt, Is ± 250 °/s more sensitive to changes and give wider range of raw values and ± 2000 °/s is less sensitive to changes and gives narrow range of raw values??? Sorry if these questions are way too noob, I just cant confirm anywhere the above assumptions that I have made.
  21. Hi, I know that there are some eamples showing how to put magnetometer data into DMP. For example this one: http://www.i2cdevlib.com/forums/topic/111-arduino-example-sketch-to-read-magnetometer-while-dmp-is-on/ but it does not make any sensor fusion. I couldn't find any library which would make magnetometer fusion inside DMP. Does such library exist? Maybe code in this file MPU6050_9Axis_MotionApps41.h make DMP+magnetometer fusion? I couldn't find any tips in the code and right now I am not able to test it. So the question is: does such library exist or the only way to do this is to make own fiters (for example complementary filter)? Maybe there is some MPU9150 library that can be used with MPU6050+magnetometer?
  22. Hello Forum User, First off, thank you for taking the time to read this. Second, I require some assistance in the rewriting of the InvenSence DMP lib for the TI microcontroller for use with the Arduino Uno and MPU6050. I have managed to remove most of the syntax errors that occured when switching from .c to .cpp, and removed the TI microcontroller specific code, but I am having problems with utilizing the Wire.h twi libraries for the I2C communication (specificly writing a function to call the twi libs when the i2c_write or i2c_read functions are called.) Ideally, it would use the included Wire.h library or the i2cdev library for the i2c communication. The main reason for this rewrite is to provide the ability of the users to call all of the listed functions of the DMP. In my case, this is primarally for the Pedometer functions which are not included in other libraries, but it can be used for the other functions as well. Below is a link to the dropbox file with the original library and the modified library. https://www.dropbox.com/s/4umn96yhh5hb9gu/eMPL_Rewrite.zip?dl=0 Thank you very much for your assistance in the matter. -Amatoxin-
  23. Hello , I experiencing some Problems with my MPU6050. I want to construct a self balancing robot on two wheels. Therefore i need the IMU and a Motorshield (RoboClaw 2x15A Motor Controller V4). If i run the IMU alone all works fine. Its the same with the Motorshield. But if i try to run the IMU and the Motorshield together i cannot initialize the IMU anymore. Both devices need serial communication. It would be really nice if someone could help me. The Motorshield is connected to the rx and tx (0,1) pin of my Arduino Uno. The Interrupt Pin of the IMU to digital pin 2, SCL to analog 5 and SDA to analog 4 Best Regards Arman Shakupbekow #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #include "BMSerial.h" #include "RoboClaw.h" #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif #define address 0x80 #define LED_PIN 13 #define runEvery(t) for (static long _lasttime;\ (uint16_t)((uint16_t)millis() - _lasttime) >= (t);\ _lasttime += (t)) MPU6050 mpu; RoboClaw roboclaw (0,1,10000,true); Quaternion q; VectorFloat gravity; uint8_t devStatus; uint8_t mpuIntStatus; uint8_t fifoBuffer[64]; uint16_t packetSize; uint16_t fifoCount; bool dmpReady = false; bool blinkState = false; volatile bool mpuInterrupt = false; int tx = 1; int rx = 0; float ypr[3]; double intendedAngle; double setpoint, input, output; int posOutMax = 127; int negOutMin = -24; int posOutMin = 24; int negOutMax = -127; float lastError = 0; double ITerm =0; double kp = 1.0; double ki = 0.0; double kd = 1.0; void initIMU(); void dmpDataReady(); void initMotors(); void setSetpoint(double); float getAngle(); void initPID(); double computePID(float); void motorcontrol(double); void setup() { initIMU(); initMotors(); setSetpoint(0.0); initPID(); } void loop() { float Angle = getAngle(); double PIDOutput = computePID(Angle); motorcontrol(PIDOutput); //Serial.println(PIDOutput); } void initIMU() { #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif Serial.begin(38400); while (!Serial); mpu.initialize(); devStatus = mpu.dmpInitialize(); mpu.setXGyroOffset(50); // 220 mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); if (devStatus == 0) { Serial.println(F("Enabling DMP...")); mpu.setDMPEnabled(true); Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)...")); attachInterrupt(1, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); Serial.println(F("DMP ready! Waiting for first interrupt...")); dmpReady = true; packetSize = mpu.dmpGetFIFOPacketSize(); } else { Serial.print(F("DMP Initialization failed (code ")); Serial.print(devStatus); Serial.println(F(")")); } pinMode(LED_PIN, OUTPUT); } void dmpDataReady() { mpuInterrupt = true; } float getAngle() { while (!mpuInterrupt && fifoCount < packetSize) { } mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus(); fifoCount = mpu.getFIFOCount(); if ((mpuIntStatus & 0x10) || fifoCount == 1024) { mpu.resetFIFO(); Serial.println(F("FIFO overflow!")); } else if (mpuIntStatus & 0x02) { while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); mpu.getFIFOBytes(fifoBuffer, packetSize); fifoCount -= packetSize; mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); //Serial.print("ypr\t"); //Serial.print(ypr[0] * 360/M_PI); //Serial.print("\t"); //Serial.print(ypr[1] * 360/M_PI); Serial.print("Pitch: "); Serial.println(ypr[1] * 360/M_PI); blinkState = !blinkState; digitalWrite(LED_PIN, blinkState); return (ypr[1] * 360/M_PI); } } void initMotors() { roboclaw.begin(38400); } void setSetpoint(double setp) { intendedAngle = setp; } void initPID() { setpoint = intendedAngle; } double computePID(float pitch) { double error = setpoint - pitch; ITerm+= (ki * error); if(ITerm > posOutMax) ITerm= posOutMax; else if(ITerm < negOutMax) ITerm= negOutMax; double dError = (error - lastError); double output = kp * error + ITerm + kd * dError; if(output > 0) { output = posOutMin + output; } else if(output < 0) { output = negOutMin + output; } if(output > posOutMax) { output = posOutMax; } else if ( output < negOutMax ) { output = negOutMax; } lastError = error; //Serial.print("error: "); //Serial.println(error); return output; } void motorcontrol(double out) { if (out > 0) { byte vel = abs(out); if (vel<0) vel=0; if (vel > 127) vel=127; //roboclaw.BackwardM1(address,vel); //roboclaw.BackwardM2(address,vel); } else { byte vel = abs(out); if (vel<0) vel=0; if (vel > 127) vel=127; //roboclaw.ForwardM1(address,vel); //roboclaw.ForwardM2(address,vel); } }
  24. Hello Everyone Using Invensenses Motion Driver, I want to read about 8 MPU6050. With AD0 connecting to 0 and 1, 2 sensors could be read successfully. I plan to control AD0 pin with MSP430 GPIO, with reading one sensor at a time (using concept one unique slave address over I2C), interrupts will be connected to one port to indicate availability of data in buffer. I need some guidance through the process. Has anyone been able to read more than 2 MPUs using Motion Driver ?? If yes, how is it done ? Thanks in advance
  25. Hello i2cdevlib forums, This is post seeking assistance with a little additional programming for the MPU6050-DMP6 sketch. I am using the Sparkfun MPU6050 breakout board with an Arduino Micro strapped to the bottom of a skateboard to get data to compare the analytical mechanical model I am working on. The sketch works almost perfectly. When outputting quaternions, after anywhere from 5-30 seconds of vigorous movement the serial monitor stops giving me data. (Are there any fixes for this?) My main request is for a addition to the sketch to allow the run to be stopped with another entering of a any key. Press an key to start, then press any key to stop kind of thing. Or is there an arduino pin which I could wire that can send a high/low signal to turn off and on the arduino in order to capture the ollie data which is only 1-2 seconds long? Are there any other manual ways of doing this? Any help or interest is greatly appreciated. Adam Gomez
×
×
  • Create New...