I2C and Invensense MPU6050 Driver

So has anyone figured out how to get the MPU6050 to respond?
I dont know too much about how all this works but all I’ve done is

root@beaglebone:~# i2cdetect -y -r 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: – -- – -- – -- – -- – -- – -- –
10: – -- – -- – -- – -- – -- – -- – -- – --
20: – -- – -- – -- – -- – -- – -- – -- – --
30: – -- – -- – -- – -- – -- – -- – -- – --
40: – -- – -- – -- – -- – -- – -- – -- – --
50: – -- – -- UU UU UU UU – -- – -- – -- – --
60: – -- – -- – -- – -- 68 – -- – -- – -- –
70: – -- – -- – -- – --

root@beaglebone:~# i2cdump -y 1 0x68
No size specified (using byte-data access)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 81 7d 00 1d 3c cd fc ae 05 44 08 5c 28 8f 6e 90 ?}.?<???D?(?n?
10: d4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ?..
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
60: 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 …@…
70: 00 00 00 00 00 68 00 00 00 00 00 00 00 00 00 00 …h…
80: 81 7d 00 1d 3c cd fc ae 05 44 08 5c 28 8f 6e 90 ?}.?<???D?(?n?
90: d4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ?..
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
e0: 00 00 00 00 00 00 00 00 00 00 00 40 00 00 00 00 …@…
f0: 00 00 00 00 00 68 00 00 00 00 00 00 00 00 00 00 …h…

I cant get my board (sparkfun breakout board) to respond to anything… i2cset doesn’t affect the board… did I wire something wrong?
VDD to Pin 3 (3.3V)
Gnd to Pin 1
SCL to Pin 19
SDA to Pin 20
VIO to Pin 3 (3.3) ← I’m not quite sure what this does but I get nothing back when I disconnect it.

Any help will be greatly appreciated!

Thanks,
Andrew

Andrew,
You have made some progress. i2cdetect can see it. Your pin connections seem to be ok, compared to the ones posted earlier. According to the device docs, it “will come up in sleep mode upon power up.” The SLEEP bit is apparently Bit6 in Register 0x6B. Set it to 0 to leave the sleep mode.

Maybe that helps.

We got as far as using the MPU6050 and the MPU9150 via file I/O thru /dev/i2c. We never got the Invensense driver to work. It still looks like no one replying to the posts here has either. The disadvantage of the file I/O access approach is that it seems very slow compared to the relatively few I2C bus cycles required.

Clark

Setting the SLEEP bit seemed to have done the trick, everything seems to work now! (or at least at the surface)

I apologize for any beginner questions (this is my first trip into the wonderful world of embedded linux). What is the difference between the “file” approach and i2c?
I was planning on using something like the Adafruit_BBIO library (http://learn.adafruit.com/setting-up-io-python-library-on-beaglebone-black) and accessing the chip through i2c. My understanding is that that approach would be basically the same as using the command line tools (i2cdetect, i2cdump/set/get etc). Using this method, I have no use for anything driver or device tree related… correct?

I’m not sure I understand exactly what you are asking, but you can access the i2c bus directly through linux file descriptors (i.e. like any other normal file). No special device drivers are needed and if you are using P_19 and P-20, it’s enabled by default w/o custom device trees.

I made a blog post of resources which might help: http://datko.net/2013/11/03/bbb_i2c/

Andrew,
Doing file I/O means read and write to /dev/i2c/etc. As you put it in your question, they are the same thing and basically the same as using the command line tools. This works out of the box. You need to know the device registers pretty well because you will be accessing them. Some libraries will give you nice wrappers for simple register access and some may provide higher level calls, for example, for reading all 3 gyros.
The alternative is to use the Invensense driver. Way back up in this conversation was a description of how it should work based on documentation in the driver and the kernel source tree. So far in this conversation, no one has made that work. That is, the driver fails to load. When it does load, its documentation says it will provide psuedo files that are functions under the sysfs tree /sys/bus/iio/devices. Besides being functionally named instead of addresses, we are expecting them to be faster. My timing tests with using file I/O via /dev/i2c shows file I/O to take significantly more time that one would expect by counting I2C bus cycles. Some applications need faster access time than this provides. Your application may work just fine at this speed.
Clark

Okay thanks for all the help!

Knowing this discussion is old, i have to ask did you get it working? And my experience is with the bbw, not the bbb. but the i2c buss on my device is 100khz. maximum is 400khz. I was able to get the accelerometer and gyro values at a rate of 200hz without issue, which isn’t the max the chip can provide, but it’s more than suitable for most applications. All through accessing /dev/i2c-#. If you havent got the driver to work yet, I can send you my tiny little C program that prints the data to the shell.

No we never got this (the Invensense driver) working. We just stuck it out with reading /dev/i2c. This is costing us a 20% time penalty which really really hurts. We couldn’t get anyone to take on fixing the unbelievably long read times (~1msec) on /dev/i2c either.
Some of us are hoping the up coming move to Debian from Angstrom will bring us an Invensense driver in the distro that will somehow work.

Hi,
I have got a small project at home running the inv_mpu6050 driver on a 3.8.13 kernel. To get it working I had to modify the driver, so that it accepts device tree parameters, then I wrote a cape configuration for the i2c and the mpu6050 device and voila it worked. I added the driver to the kernel and then add the cape to the device tree by echoing the cape name to /sys/devices/bone_capemgr.8/slots. So then I had:

cat /sys/devices/bone_capemgr.8/slots
0: 54:PF—
1: 55:PF—
2: 56:PF—
3: 57:PF—
4: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-BONE-MPU6050

lsmod
Module Size Used by
inv_mpu6050 7868 0
g_multi 47670 0
libcomposite 14299 1 g_multi
mt7601Usta 601404 0

ls /sys/bus/iio/devices/iio:device0/
buffer in_accel_scale in_accel_z_raw in_anglvel_y_raw in_temp_offset name sampling_frequency_available trigger
dev in_accel_x_raw in_anglvel_scale in_anglvel_z_raw in_temp_raw power scan_elements uevent
in_accel_matrix in_accel_y_raw in_anglvel_x_raw in_gyro_matrix in_temp_scale sampling_frequency subsystem

cat /sys/bus/iio/devices/iio:device0/*raw
-8202
-458
11288
10
51
109
-4967

But now to the downside of it all. If I try to access the values, e.g. /sys/bus/iio/devices/iio:device0/in_accel_x_raw it takes more than 100ms?
Well I am still working on some improvements in the driver’s device tree (the parameters can be negative, but the dtc version I have got can not handle unary parameters yet), but when I am finished I will commit the driver back to the community.

My work so far:
-) The Cape File:
/*

  • Copyright © 2014 Thomas Grazadei

Hi,

I have got a small project at home, running the inv-mpu6050 driver. To get it to work I had to add device tree functionality to the driver and then write a cape dtc for the beaglebone. As a result I have got the following outputs:

cat /sys/devices/bone_capemgr.8/slots
0: 54:PF—
1: 55:PF—
2: 56:PF—
3: 57:PF—
4: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-BONE-MPU6050

lsmod
Module Size Used by
inv_mpu6050 7868 0
g_multi 47670 0
libcomposite 14299 1 g_multi
mt7601Usta 601404 0

ls /sys/bus/iio/devices/iio:device0/
buffer in_accel_scale in_accel_z_raw in_anglvel_y_raw in_temp_offset name sampling_frequency_available trigger
dev in_accel_x_raw in_anglvel_scale in_anglvel_z_raw in_temp_raw power scan_elements uevent
in_accel_matrix in_accel_y_raw in_anglvel_x_raw in_gyro_matrix in_temp_scale sampling_frequency subsystem

cat /sys/bus/iio/devices/iio:device0/*raw
-8202
-458
11288
10
51
109
-4967

But now to the downside. It takes about100ms to read one value e.g. /sys/bus/iio/devices/iio:device0/in_accel_x_raw ?!

I am still working on the device tree part of the driver, as the configuration should be able to deal with negative values, but my current dtc does not support the unary operator yet. That is fixed in a later version. I will have a look at that when I find some time. When it is finished I would like to give the driver back to the community.

For now my work has the current state:
-) MPU6050 cape:
/*

  • Copyright © 2014 Thomas Graziadei

Hi

Also been struggling to get Invensense driver to work…not very impressed with Invensense to be honest. If you login to their support forum, there is no mention of MPU9250 Linux kernel drivers…I found the tegra stuff, emailed Invensense and asked them where they publish their code…they don’t.

Rather then release a unified driver for 3.4 (i2c &spi) and 3.10+ (i2c & spi) …they rather efforts and struggle be duplicated by every user of their component…this is very advanced and progressive thinking …the head of software development must be an absolute genius, no wonder their products are so easy to integrate.

Invense replied to my email with this link:
https://android.googlesource.com/kernel/msm/+/android-msm-hammerhead-3.4-kk-fr2/drivers/staging/iio/imu/inv_mpu/README

*So I’m guessing with the endless array of 2012 versions…this is what they suggested…no idea

I have yet to find an working Invensense driver that natively supports MPU9250 for the 3.10+ kernel…and absolutely nothing that supports Linux & SPI

Hoping bosch will come to the rescue and offer real linux support for this little guy:
http://www.bosch-sensortec.com/en/homepage/products_3/9_axis_sensors_5/ecompass_2/bmx055_1/bmx055

Invensense may have some nice components…but they’re worthless without quality drivers.

Hi Bruce

The link https://android.googlesource.com/kernel/msm/+/android-msm-hammerhead-3.4-kk-fr2/drivers/staging/iio/imu/inv_mpu/README
says that i have to build the kernel to make it work.

Hi,
did you pursue your work on the mpu6050 ?
I have a hard time figuring how to use the invensense driver. Is it worth it ?

thanks

I gave up, repeated emails about Linux drivers were ignored, together
with the fact that it's not a true 9 DOF ...so I dumped the board

I'm hoping Bosch comes to the party with this little gem:
http://www.bosch-sensortec.com/en_GB/homepage/products_3/9_axis_sensors_5/ecompass_2/bno055_3/bno055_4

Recently released so should be available from Tindie in the coming
weeks, I would recommend this board:
https://www.tindie.com/products/onehorse/bno-055-9-axis-motion-sensor-with-hardware-sensor-fusion/

Hi,
well currently I am working on other projects.

To get the invensens driver up and running was a matter of either filling the data necessary for the driver in the platform data (old school) or make the driver aware of device tree information.
I have quickly had a look at the current implementation of the driver in the current 3.17-rc7 kernel and it still does not support the device tree information, so you will have to do that bit for yourself.
Take my patch as a first startup and that should get you working :slight_smile:

have fun,
Thomas

I understand the frustration with the Invense driver. I want to repeat my post from earlier (May 6) that the I2C based chips are quite usable with direct I2C reads and writes. I don’t like the remaining I2C latency, but the chips are quite nice. We progressed beyond our initial implementation (which used the IMU filtered gyros and accels with our own combinatory filter) to using the onboard fusion motion processor. Our fast loop is timed by the DMP 200Hz interrupt and directly reads the fused quaternion angles via I2C reads. This moves a lot of arithmetic off of the Black’s processor.
I think this approach is better than avoiding their products and got us moving.
Clark

The new Bosch sensor really looks great! Do you know whether there are already some arduino sketches available, as the author says in the description at tindie? Would be cool to read some code and port them for the beaglebone. Im about to build my own quadcopter and used the Bosch BMA180 Accelerometer and l3g4200d Gyrometer so far, but I want some more accurate measurements than just combining them by a complementary filter. I ordered the MPU6050 now, but I don’t like the way the DMP is controlled. The BNO055 really seems to combine all benefits into one single chip. And it even features a magnetometer, which might be useless on a quad though.

I believe (via email correspondence) that the people at Tindie have
been busy with the Arduino sketch for the past 2 weeks and should have
something out within the next 2 weeks (my guess at their time frame)

I've been hounding Bosch for the Linux device
drivers.....unfortunately nothing yet. Bosch did send the API, but my
focus is Linux so ideally need a Linux device driver. I'm hoping they
release a "DTS" enabled, kernel 3.4 & 3.15+ driver.

"...new Bosch sensor really looks great!..."
It certainly does, provided they release some decent software and if
it performs I suspect it's going to clean up and certainly force
Invensense to sharpen up their offering.

"...port them for the beaglebone.."
Well if you don't mind I might ping you an email and follow your
progress? I'm using:
https://www.olimex.com/Products/SOM/A13/A13-SOM-512/
https://www.olimex.com/Products/SOM/A20/A20-SOM-4GB/

Cheers
Bruce

Hello!
I know this is an old topic and so and I’m just passing by. I also wanted to use MPU-6050 with its IIO driver, albeit on UDOO board, not a Beagle.
Indeed, I also found out that just using modprobe to load inv-mpu6050 doesn’t work. Why? Because it cannot know which I²C bus to use and which GPIO is the interrupt pin connected to.

Through a bit of perseverance I found out this is doable by declaring the device in the device tree files (arch/arm/boot/dts/), somewhat like this:

&i2c1 { accelerometer: imu@69 { // Name not really important, but it should be descriptive (as in human-readable) compatible = "invensense,mpu6050"; // This declares what driver you're attaching reg = <0x69>; // I2C address (0x69 in my case) interrupt-parent = <&gpio5>; interrupts = <22 IRQ_TYPE_EDGE_RISING>; }; };
where:
&i2c1 refers to the I²C bus declaration, you should look up the relevant bus and its alias designation in BeagleBone Black .dts/.dtsi files (caveat: the suffix number does not necessarily coincide with the /dev/i2c-x number);
interrupt-parent and interrupts must be correct if you’re going to use FIFO aided (streaming) data reading, their meaning however is board-specific.
In my case, <&gpio5> means fifth GPIO block and 22 is the pin number within that block. IRQ_TYPE_EDGE_RISING (which is a constant 1) declares that interrupt is triggered on rising edge.
Also, be careful to use angle brackets (’<’ and ‘>’) as shown, as they have important semantic meaning in device tree syntax.

Once adapted for your case, compile the device tree (make dtbs under Linux source tree) and copy over the relevant .dtb file where your bootloader expects it (/boot/dts/ most likely).

I found the device tree binding information at https://kernel.googlesource.com/pub/scm/linux/kernel/git/rzhang/linux/+/release/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt

I hope this is useful for you or anyone who stumbles on this topic (as I did). Cheers!