Yet more MPU6050 demo code

121 posts   Page 1 of 5   1, 2, 3, 4, 5
by rgh » Tue Nov 06, 2012 10:08 pm
The MPU6050 is a Triple Axis Accelerometer & Gyro with an I2C interface, see, for example. They can be found quite cheaply on ebay.

To get it working on the Pi I took the I2C and MPU6050 code from and modified the I2C class to use the Linux in-kernel I2C drivers rather than the Arduino drivers. There are drivers for many sensors on that site, which I imagine can easily be used on the Pi via my replacement I2C class. This is C++ code, btw.

'make' builds three demo programs; one displays raw data from the MPU6050, and another displays more useful data (angle of rotation, rotation matrix, quaternion, Euler Angle, for example) using the on-chip DMP to do the processing. The third demo draws a simple 3D wireframe model on the screen and lets you rotate it on all three axes by manipulating an MPU6050 that is hooked up to your Pi. If you don't have an MPU6050 you can even 'make test_3d' and manipulate the model using the keyboard :) See comments in the Makefile for the test_3d target.

A tarball of the code is attached:
(55.87 KiB) Downloaded 9953 times

Posts: 211
Joined: Fri Nov 25, 2011 3:53 pm
by pygmy_giant » Tue Nov 06, 2012 10:20 pm
sounds better than mine - I think I'll try and adapt it to address the BSC directly under RISCOS - once I manage to install GCC

EDIT: just read the read_me - the wireframe display sounds awsome!
Posts: 1562
Joined: Sun Mar 04, 2012 12:49 am
by almarlow » Wed Nov 07, 2012 10:36 am
Hi rgh,

Great demo code. I only had to change all the references in I2Cdev.cpp from "/dev/i2c-0" to "/dev/i2c-1" for it to work on my Revision B board. I really like the wireframe demo, it's exactly what I was wanting to put together and you've saved me an enormous amount of time by posting this code. I'll enjoy going through the code now to see exactly how you managed to do it.

Posts: 6
Joined: Thu Aug 02, 2012 12:47 am
by morphy_richards » Wed Nov 07, 2012 7:29 pm
Has anyone tried soldering this chip directly? Or just used breakouts? I've got some different accelerometers which are tiny surface mount things and I'm scared to go anywhere near them with my ham fisted clumsy soldering.
User avatar
Posts: 1601
Joined: Mon Mar 05, 2012 3:26 pm
Location: Epping Forest
by edb » Sun Dec 02, 2012 10:34 pm
Hello I found this code most helpful, I managed to wire up a 6050 board to the rpi. But I have noticed on the 3d demo that the 3d object can never rotate till it is upside down, its always stuck in one "hemisphere"? Also if you use the default opengles demo 3d cube example (in /opt/vc/src) you would be able to get fast drawing updates, and it would work without "x".
Posts: 2
Joined: Sun Dec 02, 2012 10:23 pm
by rgh » Mon Dec 03, 2012 8:22 am
@edb, thanks for the feedback... the demo 3d code was just the result of me exploring how to do 3d projections, which I then glued together with the 6050 - certainly if you want to render 3d solids there are better places to start :) If you figure out why the object wont turn upside down I'll be interested to hear.
Posts: 211
Joined: Fri Nov 25, 2011 3:53 pm
by fuzz1981 » Sat Jan 05, 2013 6:35 pm
If anyone is interested I have ported the MPU6050 industrialio kernel driver into the rpi 3.6 kernel tree:

It adds a bunch of things to /sys/bus/iio/devices/iio:device0

Code: Select all
pi@raspberrypi /sys/bus/iio/devices/iio:device0 $ ls
accl_enable                event_flick        gyro_matrix             lpa_mode                      scan_elements
accl_matrix                event_orientation  in_accel_scale          name                          self_test
buffer                     event_tap          in_accel_x_calibbias    orientation_on                subsystem
clock_source               firmware_loaded    in_accel_y_calibbias    pedometer_steps               tap_min_count
dev                        flick_axis         in_accel_z_calibbias    pedometer_time                tap_on
display_orientation_on     flick_counter      in_anglvel_scale        power                         tap_threshold
dmp_firmware               flick_int_on       in_anglvel_x_calibbias  power_state                   tap_time
dmp_int_on                 flick_lower        in_anglvel_y_calibbias  quaternion_on                 temperature
dmp_on                     flick_message_on   in_anglvel_z_calibbias  reg_dump                      trigger
dmp_output_rate            flick_upper        key                     sampling_frequency            uevent
event_display_orientation  gyro_enable        lpa_freq                sampling_frequency_available

There is also a /dev/iio:device0 with IIO Kfifo poll support patch into the kernel so you can read data from the MPU. The kernel driver uses a GPIO interrupt on gpio27

Code: Select all
$ cat /proc/interrupts |grep mpu
197:        735      GPIO  inv_mpu6050_irq

DMP firmware can be loaded through the dmp_firmware sysfs node
Posts: 2
Joined: Sat Jan 05, 2013 4:09 pm
by advancetom » Mon Jan 21, 2013 5:33 pm
Hello and Thank you for this exellent code i try it out with a RevB changed the busadress from 0 to 1
and for i have to change the slave also to 0x69 and it works also nice for me, to understand this awesome MPU. :D
Posts: 2
Joined: Mon Jan 21, 2013 5:08 pm
by bubi00 » Wed Jan 23, 2013 2:52 pm

does this driver support the DMP? how is the firmware loading done?
Posts: 1
Joined: Wed Jan 23, 2013 2:44 pm
by rgh » Wed Jan 23, 2013 6:01 pm
bubi00 wrote:@fuzzy1981

does this driver support the DMP? how is the firmware loading done?

Yes it does. The firmware is loaded by writing blocks of data over i2c..... See code for details.
Posts: 211
Joined: Fri Nov 25, 2011 3:53 pm
by dominicclifton » Mon Jan 28, 2013 11:47 pm

I grabbed your code and integrated it with some Accelerometer based Gesture Recognition code i found and it worked great after a bit of tweaking! Thanks for sharing.

I found, that because I have a new raspberry pi, that /dev/i2c-0 did not work and had to use /dev/i2c-1 (see pinout differences on latest raspberry pi). Thus there needs to be some way to select the I2C port.

Can you host your code on github (is it already there?)

Gesture Recognition code i used was uWave, found here:

Note there's a couple of bug in their code and the implementation is a bit messy. I will try emailing them to see if they will or if I can host an updated library on github.
Posts: 27
Joined: Thu Aug 23, 2012 10:40 pm
by rgh » Tue Jan 29, 2013 9:21 pm
Gesture Recognition... neat :)

My code is now available here This is currently the same content as the tarball linked at the start of this thread.
Posts: 211
Joined: Fri Nov 25, 2011 3:53 pm
by Bararob » Fri Feb 01, 2013 12:57 am

Nice work. I was wondering what highest logging frequency you get is. How hard world it be to log 1000 sampels a second and save the data to the sd. I have a Rpi and the mpu6050. I am coming from Arduino and not really sure where to start.
Posts: 4
Joined: Fri Feb 01, 2013 12:52 am
by rgh » Fri Feb 01, 2013 8:27 am
Comments in the driver I ported suggest the maximum update rate is 100 hertz if you are using the DMP. You can select 200Hz but you then get very noisy data, or so it says. I guess you can go faster if you bypass the DMP and access the raw data but then you have to process and filter it your self and I think 1Khz might still be optimistic.
Posts: 211
Joined: Fri Nov 25, 2011 3:53 pm
by Bararob » Fri Feb 01, 2013 10:04 pm
200 KHz I hope you mean! Thanks for the reply though.

I have sampled at 200 kHz on two other platforms that were much less robust than this (arduino and soldercore).

Anyways just wondering if anyone can tell me how man logs they can get a second?

I need to log and write to the SD with no dropped logs at no less than 500 samples per second. I know the sensor is capable and the rpi is plenty fast enough.

Also was wondering if one could call the core clock and get the ticks in linux. I am new to this Linux things o bear with me....

One last thing can I boot a logging script on startup?
Posts: 4
Joined: Fri Feb 01, 2013 12:52 am
by rgh » Sat Feb 02, 2013 11:59 am
The device hangs off the i2c bus which I think is clocked at 100KHz on the raspberry pi, so clearly you are not going to sample the gyroscope or accelerometer at 200KHz.
Posts: 211
Joined: Fri Nov 25, 2011 3:53 pm
by Bararob » Sat Feb 02, 2013 8:45 pm
Rgh thanks for that response.

OK so the device runs at 100 KHz. That is great to know. That should be fine for 1000 X 6 16 bit samples per second. I really only need half of that but I greed is good when it comes to sampling and dft's....

Anyways I was wondering if there is a way to trigger reads every millisecond (event timing). I am really new to this and a bulk of my programming is on the Arduino, BASIC and MATLAB. Could I write a front end in Python and collect data from your program? I will give it a try anyways...I really just need to read the raw data. Any which GPIO for the SDA and SCL? ANy other things I need to know?
Posts: 4
Joined: Fri Feb 01, 2013 12:52 am
by rgh » Sat Feb 02, 2013 9:36 pm
No, the i2c interface is clocked at 100KHz and it is a serial interface, so at most you can transfer 100000 bits per second . If you want 1000 x 6 x 16 bits per second, that is 96000 bits per second, just for the data you want to read. The i2c contoller also neesd to clock out the address of the register you want to read, so there is no way it'll work at the speed you are hoping for. If you want to use the DMP in the MPU6050, that produces a 42 byte data packet of data for each sample. At best it can produce 200 packets a second, but apparently doesn't work so well at that speed, and 100 samples per second (i.e. one every 10ms) is a better choice. You can find info on which P1 header pins are for i2c here You can google for examples of using i2c from python; I guess you want to read raw values from the device and not use the DMP because of the speeds you are after, so you might be as well just to ignore this code and talk to the kernl i2c driver from python.
Posts: 211
Joined: Fri Nov 25, 2011 3:53 pm
by dominicclifton » Wed Feb 06, 2013 11:48 pm
rgh wrote:Gesture Recognition... neat :)

I've published my code here:

Why not give it a try? :o
Posts: 27
Joined: Thu Aug 23, 2012 10:40 pm
by Alpentom » Sat Feb 09, 2013 4:24 pm
Hi Richard,
great job. This code was exactly what I was looking for. I am trying to control a quadcopter with the pi and your code saved me of porting the andruino code to the pi myself.
Thanks a lot
Posts: 1
Joined: Sat Feb 09, 2013 4:15 pm
by GATTACK » Sun Feb 24, 2013 8:13 pm
Hi Richard,

Great Job getting the code working on the Pi. I got all 3 demo's up and running with no problem.

I have build my own circuit with the HMC5883L to provide heading measurements. So I have been trying to edit the code for the demo_raw to output the heading measurements. I have managed to get readings by accessing the external data registeries by editing Jeff's MPU6050.cpp code to read

Code: Select all
void MPU6050::getMotion9(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz, int16_t* mx, int16_t* my, int16_t* mz) {
    I2Cdev::readBytes(devAddr, MPU6050_RA_ACCEL_XOUT_H, 20, buffer);
    *ax = (((int16_t)buffer[0]) << 8) | buffer[1];
    *ay = (((int16_t)buffer[2]) << 8) | buffer[3];
    *az = (((int16_t)buffer[4]) << 8) | buffer[5];
    *gx = (((int16_t)buffer[8]) << 8) | buffer[9];
    *gy = (((int16_t)buffer[10]) << 8) | buffer[11];
    *gz = (((int16_t)buffer[12]) << 8) | buffer[13];
   *mx = (((int16_t)buffer[14]) << 8) | buffer[15];
   *mz = (((int16_t)buffer[16]) << 8) | buffer[17];
   *my = (((int16_t)buffer[18]) << 8) | buffer[19];
   // TODO: magnetometer integration

I get readings. However, I have no idea whether the data stored in these registeries are for the magnetometer! Hoping you might be able to help.

Posts: 6
Joined: Sun Feb 24, 2013 8:06 pm
by rgh » Mon Feb 25, 2013 8:56 am
Sorry Glen, I've got no idea.. all my knowledge came from reading Jeff's code, and I've not explored adding a HMC5883L.
Posts: 211
Joined: Fri Nov 25, 2011 3:53 pm
by badook » Mon Feb 25, 2013 10:31 am
I'm very interested in integrating the HMC5883L magnetometer too!
Posts: 43
Joined: Sun Dec 16, 2012 7:44 pm
by GATTACK » Mon Feb 25, 2013 1:29 pm
I have e-mail Jeff to see whether he can offer any assistance.

There is a 9Axis header file on Jeff's github. I haven't tried it yet - but this is for integration with the MPU6050 Digital Motion Processing code. ... no/MPU6050

To get the raw code the MPU6050 has 24 registry addresses where the external data from a Slave device which has the HMC5883L can be read from - but I think the slave has to be configured first with its address and instructions with regard to which registries to access to get the magnetometer data. This I think is done using:


I don't really know how to code these, but the address for the HMC5883L is fixed at 0x1E and the register for the first magnatometer reading begins at 0x03 - I have no idea what to specifiy for the CTRL.

You can view more of the IMU device I have made as

Best Wishes
Posts: 6
Joined: Sun Feb 24, 2013 8:06 pm
by JohnMcC1 » Mon Apr 08, 2013 2:48 am
A question from a user with limited knowledge.

The MPU6050 runs on an Arduino OK, with very stable values - this is an awesome module.

I am trying to get this MPU6050 running on a new RP. It is wired correctly with the LED on when connected to the RP.

I have unzipped everything to a directory on the RP, libgtkmm-3.0-dev installed. Run make and all seems to compile but DMP initialization fails, code 1 when I try to run ./demo.dmp

I did try changing the value 0 to 1 in sudo chmod 666 /dev/i2c-1, but that still did not help.

i2cdetect -y 1 shows a valid value of 68, so from my limited knowledge I need to set 1, not 0.

Is there somewhere else I change the value 0 to 1?

Any clues?



OK found the issue. With the new RPi you need to edit IC2dev.cpp in three places, as mentioned by almarlow above.

change i2c-0 to i2c-1

fd = open("/dev/i2c-1", O_RDWR);

Quick look and demo_dmp seems to be outputting to the screen at about 20 Hz.

Previous test I did showed, logging from an Arduino, a yaw drift rate of about 0.3 deg/min when tested overnight with no additional sensor input to correct for long term drift. Pretty amazing for an $8 part. Thanks for posting this code Richard.
Posts: 1
Joined: Sun Apr 07, 2013 7:17 pm