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. 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?
  2. 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
  3. 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
  4. 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_ */
  5. 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.
  6. 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();
  7. 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.
  8. 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.
  9. Hi, I am new to this so please bear with me. My current project requires that i use multiple MPU6050's in order to track the motion of a person. I am aware that the MPU6050 has two addresses and that in the code supplied by jeff you can state which address on the I2C bus to read from. The problem is with the use of the DMP code and interrupts, am I able to attach the second IMU to the alternate interrupt pin on the Arduino Pro Mini that I am using? If i was to do this what would i have to do in the example code and/or the libraries in order to determine which interrupt is read etc. I have tried to interpret the libraries to see if there was a line of code that states which interrupt pin is being used but i quite frankly dont know what i am looking at or looking for. I hope that someone will be able to help me. Thanks
  10. 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?
  11. 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-
  12. 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
  13. 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); } }
  14. 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
  15. I am trying to figure out how to calculate movement along an axis. With Y & Z axis still, I would like to calculate movement along the X axis and same for the other two axes. Then take this data to make a mouse. I would like to recreate what is in this video : I am not sure where to start and how to go about doing this, I would really appreciate some help. Thanks!
  16. Hi @ all, im new here, but i've read much in this forum about the MPU6050 and I2C. First i wanna say two things: 1. my english isnn't the best, i hope u understand me 2. you guys do a really great job here *clap* Im here, because i have a problem. i use a Arduino due and a GY-521 with an MPU6050. I've written my own code, but there are somethimes connectionproblems. I dont know why, i cant understand. What i've done: - Checked the connections 3.3V is connected to VCC GND is connected to GND SCL is connected to SCL (via pull up to 3,3v) SDA is connected to SDA (via pull up to 3,3v) AD0 is connected directly to GND the rest is open. - I've soldered additionaly 2x 4,7kOhm Resistors from SDA and SCL to 3.3V (read this could help in playground) The problem is strange, because its just somethimes. If u disconnect my board and reconnect it, it works. But somethimes i have to do this several times. Im not sure if the problem is in the code. Because if i start the Seiral monitor, there are some printouts, that shouldnt get printet before other printouts. I've testet it with several boards, sensors and shields, its always the same problem. Do you have any ideas. in the attachement my file as .txt, cant upload .ino Thanks and best regards. Patrick gyro.txt
  17. Hello Everyone, I have a small query, can I use motion drivers provided by Invensense on a general purpose MSP430 evaluation board and read sensor data with UART ?? I don't want to purchase Evaluation Board from Invensense as I want to make some hardware and software changes in order to read multiple MSP6050 using single MSP430 controller. I need preliminary suggestion so I can go ahead and purchase the stuff I need. regards, Mandar
  18. Hello, I started to use MPU6050 library about a week ago and it was a delicious thing, thanks for that. Since I want to use it in a quadcopter, sensor readings is not all the work, so I created a library and do the sensor stuff under that library for simplicity of the main program. That's when I encountered with multiple definitions problem. In my library, I included 6 axis motion apps library and try to do initializing and reading. The error output is below. I use Visual Micro for Arduino programming but Arduino IDE gives the same error. I couldn't find multiple definitions, so any help would be great. Thanks in advance. Compiling 'QuadroCopter_v0_92' for 'Arduino Mega 2560 or Mega ADK' MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetAccel(long*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetAccel(long*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:577: first defined here ld.exe:Disabling relaxation: it will not work with multiple definitions MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetAccel(int*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetAccel(int*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:585: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetAccel(VectorInt16*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetAccel(VectorInt16*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:593: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetQuaternion(long*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetQuaternion(long*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:601: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetQuaternion(int*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetQuaternion(int*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:610: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetQuaternion(Quaternion*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetQuaternion(Quaternion*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:619: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetGyro(long*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetGyro(long*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:634: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetGyro(int*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetGyro(int*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:642: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetLinearAccel(VectorInt16*, VectorInt16*, VectorFloat*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetLinearAccel(VectorInt16*, VectorInt16*, VectorFloat*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:652: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetGravity(VectorFloat*, Quaternion*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetGravity(VectorFloat*, Quaternion*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:672: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpProcessFIFOPacket(unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpProcessFIFOPacket(unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:711: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetFIFOPacketSize()' MPU6050_6Axis_MotionApps20.cpp:dmpGetFIFOPacketSize()' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:737: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpReadAndProcessFIFOPacket(unsigned char, unsigned char*)' MPU6050_6Axis_MotionApps20.cpp:dmpReadAndProcessFIFOPacket(unsigned char, unsigned char*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:712: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetYawPitchRoll(float*, Quaternion*, VectorFloat*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetYawPitchRoll(float*, Quaternion*, VectorFloat*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:689: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetEuler(float*, Quaternion*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetEuler(float*, Quaternion*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:683: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpGetLinearAccelInWorld(VectorInt16*, VectorInt16*, Quaternion*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetLinearAccelInWorld(VectorInt16*, VectorInt16*, Quaternion*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:660: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpPacketAvailable()' MPU6050_6Axis_MotionApps20.cpp:dmpPacketAvailable()' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:550: first defined here MPU6050_6Axis_MotionApps20.cpp.o:In function `MPU6050::dmpInitialize()' MPU6050_6Axis_MotionApps20.cpp:dmpInitialize()' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:325: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetAccel(long*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetAccel(long*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:577: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetAccel(int*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetAccel(int*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:585: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetAccel(VectorInt16*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetAccel(VectorInt16*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:593: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetQuaternion(long*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetQuaternion(long*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:601: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetQuaternion(int*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetQuaternion(int*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:610: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetQuaternion(Quaternion*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetQuaternion(Quaternion*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:619: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetGyro(long*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetGyro(long*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:634: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetGyro(int*, unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetGyro(int*, unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:642: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetLinearAccel(VectorInt16*, VectorInt16*, VectorFloat*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetLinearAccel(VectorInt16*, VectorInt16*, VectorFloat*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:652: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetGravity(VectorFloat*, Quaternion*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetGravity(VectorFloat*, Quaternion*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:672: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpProcessFIFOPacket(unsigned char const*)' MPU6050_6Axis_MotionApps20.cpp:dmpProcessFIFOPacket(unsigned char const*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:711: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetFIFOPacketSize()' MPU6050_6Axis_MotionApps20.cpp:dmpGetFIFOPacketSize()' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:737: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpReadAndProcessFIFOPacket(unsigned char, unsigned char*)' MPU6050_6Axis_MotionApps20.cpp:dmpReadAndProcessFIFOPacket(unsigned char, unsigned char*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:712: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetYawPitchRoll(float*, Quaternion*, VectorFloat*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetYawPitchRoll(float*, Quaternion*, VectorFloat*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:689: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetEuler(float*, Quaternion*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetEuler(float*, Quaternion*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:683: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpGetLinearAccelInWorld(VectorInt16*, VectorInt16*, Quaternion*)' MPU6050_6Axis_MotionApps20.cpp:dmpGetLinearAccelInWorld(VectorInt16*, VectorInt16*, Quaternion*)' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:660: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpPacketAvailable()' MPU6050_6Axis_MotionApps20.cpp:dmpPacketAvailable()' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:550: first defined here QuadroCopter_v0_92.cpp.o:In function `MPU6050::dmpInitialize()' MPU6050_6Axis_MotionApps20.cpp:dmpInitialize()' BBSensors.cpp.o:\MPU6050_6Axis_MotionApps20.cpp:325: first defined here Error creating .elf
  19. Hello, To begin with Thanks to Jeff for the wonderful library. I could interface and get data from the sensor.However, there are few issues I can see when I did some checks. 1. I have a GY521 breakout board, which I fixed on a cuboid made of metal for rigidity and I have measurements at different angles(deg.) - 0,5,10,15,etc. The readings I got are as follows: 0 -> 0.37 5 -> 4.98 10 ->9.57 15->14.31 30-> 28.10 45->42.17 These are averaged readings over a period of about 1 minute each. The readings are stable - there is no drift. But, as you can see, the error is increasing with angle. Im not sure where the correction is needed.Any ideas for the same are welcome. 2. Im logging data at 10 Hz on my laptop over TCP connection, I have given a delay of about 95000 us in the loop on the processor. And I see FIFO overflow sometimes when I observe for few minutes. I need advise on resolve these two issues. Kindly advise. Thanks.
  20. The demo DMP sketch continually locks up after anywhere between 3-20 seconds into running. The demo code is unmodified in any way other than commenting out a few of the #define's to limit the output. I get no errors and no FIFO overflows, results appear on the serial monitor...but then the program just hangs. I have a clean setup here...nothing else attached to the Arduino. Suggestions??
  21. 've Read, you can put an acceleration value which then generates an interrupt if it is exceeded. How can the sensor can be configured for this to work so? I just need the acceleration value for the X-axis! Thanks a lot Wolfgang
  22. Hello, I'm playing around with the MPU6050 to compute displacement (yes, quite aware of how inaccurate it is) using the real and world acceleration in the DMP sketche (a God sent!). I'm also using the raw data. With the raw data I was able to compute the displacement without any trouble, whereas in the case of the real and world acceleration I'm getting results that hardly make sense in the context of displacement. Which made me wonder what unit of measurement is being used? I assumed g (acceleration of gravity), but I must be mistaken. Apologises for the newb question and thank you!
  23. Hello, I've built a quadrotor and have connected an MPU6050 accel/gyro to an Arduino Uno, successfully reading any gyro and accel outputs. I'm trying to keep it as simple as possible, so I'm not concerned with DMP at the moment and am only trying to read raw values, I'll implement my own conversions and filters later. The challenge I've been facing now is to feed a LSM303 tilt compass (https://www.sparkfun.com/products/retired/10703) through the MPU6050 ASDA and ASCL. I'm only trying to read the LSM303 magnetometer readings. The current wiring is as follows: LSM303: ----------- MPU6050: SCL <-------------> ASCL SDA <-------------> ASDA GND <-------------> GND with both voltages connected to the Arduino's 3.3v output. The main problems are: 1) How to setup the registries on the MPU6050 for a slave device. 2) How to read the aux ports from the MPU6050 and print them on the arduino serial monitor. I've attached the basic code, you'll notice I'm trying to keep it as simple as possible and for the time being am not using jrowberg's librairies to best understand the process. Any help would be greatly appreciated. Sensor_9DOF.txt
  24. Hey there - I've been using the I2CDevlib MPU6050 code for about 18 months in the development of a new flight control system (I know what some of you are thinking - oh god ANOTHE flight control thingy...) Anyways, in optimizaing the code, I've found that the MPU6050 type is munching ~1200 bytes of RAM Which on a standard ATMega328 is almost 60% of all its RAM. The older flight computers used a cluster configuration that talked over I2C so we could just dump the mpu handling code in there and have the other ATMegas do the reast. This isn't ideal since its unreliable, bulky (and so on). I had a skim of the source and not found anything that my reasonably poor C skills can pick out as a stick out memory hog. So in short - is there anything that I can remove from the MPU6050 class to make it use less memory? The only data I am interested in is roll, pitch, yaw angles as well as accleration on the X, Y & Z axes. However if it would save a reasonable amount of memory, the acceleration data could be replaced by using data from other sensors onboard the aircraft. Cheers, code (and sorry if this first post isn't in quite the same style as other posts, do feel free to edit and whatnot).
  25. Hi, my name is Stephane, 44 yo, and I'm a software engineer. I'm working on Segway clone as a hobby.. I'm facing an issue when I make LCD updates via I2C when DMP is activated. The program run a few seconds then hangs. The same code run well in the MPU6050_RAW, that is why I'm concerned about the fact that the DMP is conflicting. I've tried with pullpups resistors, different LCD libraries, delays, without interuption etc .. and now I'm out of ideas. Here is the code, it's 99% the same as MPU6050_DMP6 + LCD parts in bold Any idea ? Thanks Stephane // 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 #include <LiquidCrystal_I2C.h> // 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(0x69); // <-- use for AD0 high LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address #define OUTPUT_READABLE_YAWPITCHROLL long time10Hz = 0; long currentMillis; #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 // ================================================================ // === 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 // initialize serial communication // (115200 chosen because it is required for Teapot Demo output, but it's // really up to you depending on your project) Serial.begin(115200); 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(); // verify connection Serial.println(F("Testing device connections...")); Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); // 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 Serial.println(F("Initializing DMP...")); devStatus = mpu.dmpInitialize(); // supply your own gyro offsets here, scaled for min sensitivity mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); // 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(")")); } lcd.begin(20, 4); // initialize the lcd lcd.backlight(); lcd.clear(); // configure LED for output pinMode(LED_PIN, OUTPUT); } // ================================================================ // === MAIN PROGRAM LOOP === // ================================================================ void 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 mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); Serial.print("ypr\t"); Serial.print(ypr[0] * 180 / M_PI); Serial.print("\t"); Serial.print(ypr[1] * 180 / M_PI); Serial.print("\t"); Serial.println(ypr[2] * 180 / M_PI); #endif currentMillis = millis(); if (currentMillis - time10Hz >= 100) { loopAt10Hz(); time10Hz = currentMillis; } // blink LED to indicate activity blinkState = !blinkState; digitalWrite(LED_PIN, blinkState); } } void loopAt10Hz() { lcd.setCursor(0, 1); lcd.print(currentMillis); }
×
×
  • Create New...