6-axis IMU API port for MPU-6000/6050?

17 Jan 2012

Hello,

I'm starting to work on the MPU-6050 Motion Processing device from Invensense. From what I've seen it is a very nice device with 3-axis accelerometer and 3-axis gyroscopes. It is capable of computing Euler's angles internally hence the attractiveness. In order to be efficient I'm wondering if anybody has done this. If not, I'll be starting in a few days to port the API from the low level ARM code they provide and proceed to share it.

08 Feb 2012

Walter Britton wrote:

Hello,

I'm starting to work on the MPU-6050 Motion Processing device from Invensense. From what I've seen it is a very nice device with 3-axis accelerometer and 3-axis gyroscopes. It is capable of computing Euler's angles internally hence the attractiveness. In order to be efficient I'm wondering if anybody has done this. If not, I'll be starting in a few days to port the API from the low level ARM code they provide and proceed to share it.

Hello,

I'm also using this chip. And I have found a useful link here: https://github.com/jrowberg/i2cdevlib/tree/master/MPU6050 It's originally for Arduino community, but the author tries to make this library generic. Hope this is a good reference.

Cheers

08 Feb 2012

Ye,

Thanks a lot for the link... this will be of great help. Unluckily I have been busy with work and classes... and since this is for fun it has lower priority.

Regards,

WBB

30 Mar 2012

How did you get the code from Invensense? I signed up for the developer resources, but when I click on any of the files in downloads it says I don't have a commercial account or some such nonsense...

Is there anything that would prevent you from sending the code to me?

Thanks, Mike

30 Mar 2012

The code for communicating with the MPU6050 has been reverse engineered, and converted to a c plus plus driver by the Arduino community. This can be a great starting point for porting to MBED. The .CPP and .h files that work with Arduino can be downloaded here:

http://www.i2cdevlib.com/devices/mpu6050

I have begun to port this myself, but am looking at translating the I2CDEV.cpp and I2CDEV.h file first. If we do that, then ALL of the drivers in this excellent library could be used by the MBED team, not just the one for the MPU6050. I am not a c plus plus expert so this process is moving slowly. Help would be appreciated!

30 Mar 2012

I believe there is no problem. See the attached./media/uploads/w8ryanb/ma111.zip

Mike Panetta wrote:

How did you get the code from Invensense? I signed up for the developer resources, but when I click on any of the files in downloads it says I don't have a commercial account or some such nonsense...

Is there anything that would prevent you from sending the code to me?

Thanks, Mike

30 Mar 2012

I believe they recently release v4 which is for the MPU-9050 (3-axis: Gyro, Acc, and Compass). I might be able to get this if you need it. WBB

30 Mar 2012

Walter Britton wrote:

I believe they recently release v4 which is for the MPU-9050 (3-axis: Gyro, Acc, and Compass). I might be able to get this if you need it. WBB

Thanks for the code! I don't think I will need it, but you never know. Depends on whether or not the competition I am entering allows the use of a magnetometer or not...

08 Jun 2012

Walter, I have some of the MPU-9150 dev boards. I'd be interested to see if you can get any documentation beyond the initial design guide for this chip.

09 Jun 2012

Wait, they did the same joke again with the next one? Advertising with their motion processor and not bothering to tell anyone who doesnt work for a multinational how it works? I am using an MPU6050 now because it is still a nice sensor, also without their motion algorithms, but it is kinda stupid. Ah well, their loss.

(Yes I know you can use the MPU6050 motion processor with the data dump someone made, but I do not consider it to be very useful if you have no clue which settings are used).

13 Jun 2012

Hi,

great effort to write an mbed driver/interface for that chip. Since the MPU6050 also eventually became my choice when I was looking for a fully featured IMU (and after frustrating work with the Sparkfun ATX/ITG 6-DOF IMU), I now found a convenient, but not so cheap solution. Check out the YEI 3-space embedded board. It is not as compact as the MPU6050, but offers plenty of processing, algorythms with an easy software interface. When I first started working with it, I simply hooked it up with an USB cable and it appeared as Virtual serial port. There, you can try out how the commands work. I then connected it to the mbed using UART, but other options (SPI, I2C) are available as well. And the great thing: Wire it, and then send simple commands to it - it works. This was really a great relief to me, since I struggle with various options (first analog IMUs, then the 6-DOF I2C-driven IMU mentioned above...) for six months now... I also have to say that I really enjoy mbed programming, it seems to be much more convenient and mature than arduino, but keeps things at an easy level (in comparison to PIC/Microchip stuff)!

13 Jun 2012

Tobias, per your recommendation I took at look at this sensor. I have previously looked at the Ardu IMU and the CHR UM6. I am impressed with the ArduImu, but the size is rather large. The CHR-UM6 is expensive and I am finding quite a bit of Yaw Drift with this sensor. Can you report on how the YEI3 works for you? Can you share any code to help get staarted with this sensor?

13 Jun 2012

The sensor works great out of the box and comes calibrated. If you are getting started, you can simply connect it to USB as described in the documentation (simply wire an USB cable, no additional electronics needed). For testing purposes, you can download an open source software suite which simulates the sensor in three dimensional space in real time. You can just most parameters, e.g. filter params, and learn about all the options available. As a second step, I connected the sensor to UART I of the mbed (pins 9 and 10 of the mbed are tx and rx. I think in the 3-Space sensor the description of the pins is incorrect, for serial communication, you might need to swap tx and rx cables.

In order to establish a connection, first define a serial object prior to the main routine (in this example, i called it "device"):

Serial device(p9, p10);  // tx, rx

Then I defined a routine which reads incoming data from the serial port (I am pretty sure that there is better code available for this task, I modified it from anywhere in the internet):

  char data[33];
void get_data() {

  int incount = 0;

  if ( device.readable() )

  {
    while (device.readable()) {
    data[incount++] = device.getc();      
    }

  }

This function reads a certain number of characters In the main routine, we communicate with the 3-space sensor. There are plenty of commands and requests available which are well documented in the PDF-manual. There you can find most info you need, and their tech-support is very helpfull. There are two communication protocols available, I choosed the ASCII version. Each command starts with ":", followed by a number representing a byte value (0-255), and then specific parameters separated with a comma. After setting the baud rate, changing the led color of the sensor gives you a good indication if everything works. The command number is 238, followed by three float values (0-1.0) for each color channel:

int main() {
    
    
 device.baud(115200);

 device.printf(":238,1.00,0.00,0.00\n ");
 wait(0.5);
 device.printf(":238,0.00,1.00,0.00\n ");
 wait(0.5);

If this works, you can start requesting sensor data. There are numerous options: You can request sensor raw data, filtered data, data processed by various algorithms, all by sending a simple command. You can find the documentation of the numerous commands available on YEIs homepage (http://tech.yostengineering.com/3-space-sensor/product-family/embedded/files/3-Space_Sensor_Users_Manual_Embedded_1.1_r13_28Feb2012.pdf). One examble: command "0" does the following: "Read filtered, tared orientation (Quaternion)". So let's send the command over UART 1, utilizing our self-defined read function:

 device.printf(":0\n ");
 get_data();

Now the data buffer contains what has been received from the serial interface. Baud rates above 115200 don't seem to work so well. If fast communication/processing is necessary, you can use the binary packet format. In these cases, you will receive results as byte values, reducing the number of bytes transferred after each request significantly. I simply printed the data over an lc display:

 lcd.printf(data);
 wait (0.5);

Sending over USB also works.

I don't think that my experiences might be applicable for all possible situations. However, I wanted to have a simple and fast way of implementing IMU data in my application. This 3-space device simply works as described, no volatile memory needs to be filled at startup etc. However, if you are skilled and experienced regarding this stuff you might find much cheaper ways to implement IMU sensors.

Hope this helps, tell me if you need additional info. Sorry for my poor english...

13 Jun 2012

Ah, I forgot, sensor size. From the datasheet: 23mmx23mmx2.2mm. Still tiny! But only the embedded version, other versions come in a housing and are larger. However, that is not much larger than the IMU from sparkfun. I use it for motion tracking e.g. of human fingers, and there the sensor is definitely tiny enough.

25 Jun 2012

http://mbed.org/users/aloeppert/programs/mbedMPU/mc1rmt

Let's informally call this drop code name "esqueleto" as it doesn't do much of anything... no interrupt support or fancy configuration. Essentially just default settings. Looked at https://github.com/jrowberg/i2cdevlib for some reference, but is a new implementation.

How to use it: 1. connect MPU SDA and SCL to the i2c port at MBED p9/p10 2. connect MPU VDD and VIO to MBED (v3.3) VOUT pin, and of course GND. 3. SW setting: serial 115200 bps. Change as desired. 4. power up look for initialization successful, then press 'd'

Hope someone finds it useful.

Anthony Loeppert

Edit: PS, this is a very rough draft written in a day. I'm rewriting it to support interrupts and multiple sensors and buses.

25 Jun 2012

Took today off work due to sickness... (in case someone I know reads this later wondering why I'm not a work :) )

Updated the program to v0.2a

I'm starting to get a feel for the platform. I like it. Verification

Anthony Loeppert wrote:

http://mbed.org/users/aloeppert/programs/mbedMPU/mc1rmt

Let's informally call this drop code name "esqueleto" as it doesn't do much of anything... no interrupt support or fancy configuration. Essentially just default settings. Looked at https://github.com/jrowberg/i2cdevlib for some reference, but is a new implementation.

How to use it: 1. connect MPU SDA and SCL to the i2c port at MBED p9/p10 2. connect MPU VDD and VIO to MBED (v3.3) VOUT pin, and of course GND. 3. SW setting: serial 115200 bps. Change as desired. 4. power up look for initialization successful, then press 'd'

Hope someone finds it useful.

Anthony Loeppert

Edit: PS, this is a very rough draft written in a day. I'm rewriting it to support interrupts and multiple sensors and buses.

05 Jul 2012

Anyone interested in invensense's sample code "embedded_motionapps-2012-05-02-Rel-V2_0_2" ported to mbed? I'm considering updating the public version.

The code is too big to run on the LPC11U24 at the moment, coming in at about a whopping 80KB.

Anthony Loeppert wrote:

Took today off work due to sickness... (in case someone I know reads this later wondering why I'm not a work :) )

Updated the program to v0.2a

I'm starting to get a feel for the platform. I like it. Verification

Anthony Loeppert wrote:

http://mbed.org/users/aloeppert/programs/mbedMPU/mc1rmt

Let's informally call this drop code name "esqueleto" as it doesn't do much of anything... no interrupt support or fancy configuration. Essentially just default settings. Looked at https://github.com/jrowberg/i2cdevlib for some reference, but is a new implementation.

How to use it: 1. connect MPU SDA and SCL to the i2c port at MBED p9/p10 2. connect MPU VDD and VIO to MBED (v3.3) VOUT pin, and of course GND. 3. SW setting: serial 115200 bps. Change as desired. 4. power up look for initialization successful, then press 'd'

Hope someone finds it useful.

Anthony Loeppert

Edit: PS, this is a very rough draft written in a day. I'm rewriting it to support interrupts and multiple sensors and buses.

23 Aug 2012

Anthony I had attempted to run your latest version of the MPU code and it doesnt work with the 'd' command. I have it successfully initializing and finding the device at i2c0 address 68 but thats all the firmware seems to do. Is there a version that actually outputs the raw sensor data? I'm looking to first get the raw data and then possibly figure out how to make the DMP work so I can get sensor fusion for doing a balance robot or quadcopter.

Thanks for a great start!

ps-I would be very interested in a port of the example program ported to Mbed.

23 Aug 2012

That sounds to me like the device doesnt come out of sleep mode, (it starts standard in it), but scanning the code it looks like it should bring it out of sleep mode, so thats a bit weird.

If you want DMP data I would really advice you to go for the device mentioned by Tobias in this topic, or a similar one. There simply is not enough information about the MPU6050 to use it as DMP imo.

25 Aug 2012

Matt Clement wrote:

Anthony I had attempted to run your latest version of the MPU code and it doesnt work with the 'd' command. I have it successfully initializing and finding the device at i2c0 address 68 but thats all the firmware seems to do. Is there a version that actually outputs the raw sensor data? I'm looking to first get the raw data and then possibly figure out how to make the DMP work so I can get sensor fusion for doing a balance robot or quadcopter.

Thanks for a great start!

ps-I would be very interested in a port of the example program ported to Mbed.

As it seemed no one was really interested in this part but me, I made a few revisions public that I didn't comment on in the thread. The latest public code assumes a bluetooth serial device and loops until three dashes are received before data will stream. It allowed me to send any setup commands to the bluetooth module before using it, though looking at the latest shared version it seems I didn't use BT to stream the data at that time so there is no reason to keep the BT code. Try removing/commenting out the code:

    bt.baud(115200);
    
    /* $$$ to get CMD mode of BT device.
    talk to bluetooth until --- */
    while (1) {
        ...
    }

The DMP code port was a slash and burn operation (and it was still HUGE!)... There was a lot of legacy code (and what I guessed to be extraneous to my setup) which I removed. Either due to a mistake I made, or because there isn't a compass connected in my setup, I would get the quaternion output but it would drift badly simply sitting still on my desk. Having had some time to think on the matter, I won't make it public, at least at this time, because I'm not terribly proud of that work.

Regards, Anthony

27 Aug 2012

Quote:

As it seemed no one was really interested in this part but me, I made a few revisions public that I didn't comment on in the thread. The latest public code assumes a bluetooth serial device and loops until three dashes are received before data will stream. It allowed me to send any setup commands to the bluetooth module before using it, though looking at the latest shared version it seems I didn't use BT to stream the data at that time so there is no reason to keep the BT code. Try removing/commenting out the code:

I have already removed the Bluetooth stuff. But on my version the 'd' command is commented out and so does nothing. What is it supposed to do when you uncomment the 'd' stuff? I think I tried that and the compile failed.

Quote:

The DMP code port was a slash and burn operation (and it was still HUGE!)... There was a lot of legacy code (and what I guessed to be extraneous to my setup) which I removed. Either due to a mistake I made, or because there isn't a compass connected in my setup, I would get the quaternion output but it would drift badly simply sitting still on my desk. Having had some time to think on the matter, I won't make it public, at least at this time, because I'm not terribly proud of that work.

C'mon Anthony, I think we've all done something we're not proud of at one point or another..haha.

Thanks

10 Sep 2012

Hey Anthony

Any chance you can take a look at the library and figure out why the 'd' command is commented out and how we can put it back so I can view the raw accel and gyro data from the device?

Thanks

10 Sep 2012

Hey Matt,

If all you need is that maybe I can help. I have my own MPU library that I made some time ago. It is a quite crappy one (first library I made, pretty much first c++ code I made), and tbh I doubt it will ever get seriously updated since it pretty much does what it needs to do. Well one day I need to get it good working together with interrupt driven I2C, but thats kinda offtopic here. Getting raw accel and gyro data out of it works fine though.

Address is set in code at 0x69, but I just added that you can at least define another address in your code (MP6050_ADDRESS is the define you need, at least I think it works).

To get raw gyro/accelero data do something like this:

#include "mbed.h"
#include "MPU6050.h"

Serial pc(USBTX, USBRX); // tx, rx
MPU6050 mpu(p9, p10);   //Also disables sleep mode

int main() {
    int accdata[3];
    int gyrodata[3];
    
    wait(0.1);
    if (mpu.testConnection())
        pc.printf("MPU connection succeeded\n\r");
    else
        pc.printf("MPU connection failed\n\r");
        
    while(1) {
        mpu.getAcceleroRaw(accdata);
        mpu.getGyroRaw(gyrodata);
        
        pc.printf("Accelero data: X: %d - Y: %d - Z: %d\n\r", accdata[0], accdata[1], accdata[2]);
        pc.printf("Gyro data: X: %d - Y: %d - Z: %d\n\r\n\r", gyrodata[0], gyrodata[1], gyrodata[2]);
        
        wait(1);
    }
        
        
}

That returns when mine is lying still:

Accelero data: X: -1056 - Y: -64 - Z: 16644
Gyro data: X: -68 - Y: 37 - Z: -16

Edit: Link to library would probably help :P

Import libraryMPU6050

MPU6050 library that is kinda beta and will probably never leave beta but it might help some people.

Edit2: If you meant with raw data just the data, but already scaled to rads/s and m/s2, remove the 'Raw' from the functions, change the arrays to floats, and of course the %d's in the printfs to %f's, and it should work.

11 Sep 2012

Matt Clement wrote:

Hey Anthony

Any chance you can take a look at the library and figure out why the 'd' command is commented out and how we can put it back so I can view the raw accel and gyro data from the device?

Thanks

It looks like Erik can help you out with his program.

Regards, Anthony

12 Sep 2012

Awesome. I actually stumbled upon it today and am using it. It works well......thank you both for helping. :-)

20 Apr 2014

Here is the some example video of usages MPU-6050

https://www.youtube.com/watch?v=D5HY_tjW1lc