Friday, November 28, 2014

57. Exploring the Pi B+'s Ports III - Connecting the MPU-6050 Inertial Measurement Unit to the I2C bus

Some time back (see HERE) I had this GY-521 breakout board connected to an Arduino.  This time it's connected to the Raspberry Pi through the Cyntech paddle board:
As before, moving the small breadboard about (it's a blue one this time) generates signals in the on-board gyroscope and accelerometer, which are read via the I2C interface (serial data line, SDA - GPIO2 and serial clock line, SCL - GPIO3) by the Raspberry Pi.

A video of the demonstration is shown below:
I used ShareX 9.4.2 free software with FFmpeg added to capture the Pi's desktop from my PC, and used Vimeo to embed the video.

In the video I ran 3 different programs, using the following commands: ./demo_dmp, ./demo_raw and ./demo_3d which I will explain later.


Enabling the I2C interface

  • Install the i2c-tools:
sudo apt-get install python-smbus
sudo apt-get install i2c-tools
  • Enable I2C and SPI protocols:
sudo nano /etc/modprobe.d/raspi-blacklist.conf
  • This will open the above file in a text editor, allowing the following lines to be commented out:
#blacklist spi-bcm2708
#blacklist i2c-bcm2708
  • Edit the following file as follows, to allow the I2C module to be started automatically on start up:
sudo nano /etc/modules
  • When opened in the editor, add the last line as follows:
i2c-dev
  • Add the ‘pi’ user to the I2C group:
sudo adduser pi i2c
  • Update the Pi to ensure that all the latest packages are installed:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
  • Finally re-boot the Pi:
sudo reboot

The Pi will now automatically support I2C on startup.


Interfacing the MPU-6050

Make the connections as follows:
  • Pin 1 - 3.3V connect to VCC on the MPU-6050
  • Pin 3 - SDA connect to the MPU's SDA
  • Pin 5 - SCL connect to the MPU's SCL
  • Pin 6 - Ground connect to GND


Checking the 
Addresses of the I2C bus & the MPU-6050's Registers

Using the command:

i2cdetect -y 1 (the 1 refers to Revision 2 or later Raspberry Pis)

the following output was printed on the terminal:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                       


The entry at the hexadecimal address 0x68 shows that an I2C device has been detected at that address.  The UU at 0x3b appears to be reserved by the kernel for a driver.

These addresses allow us to examine their contents.  For example, entering the command:

sudo i2cget -y 1 0x68 0x75

reads the contents of the address 0x68 of I2CBUS 1 (the 1 refers to a Rev 2 or later Raspberry Pi) and retrieves the value in the register 0x75, which has a default value the same as the address (I think it is called the WHO_AM_I register - this is where the device itself 'knows' where it is on the I2C bus), and so it returns the value:

0x68

This apparently indicates that everything is working properly. :)


The Test Programs

I don't pretend to fully understand these programs, which have been written in the C++ language by Richard G Hirst, and available at https://github.com/richardghirst/PiBits/tree/master/MPU6050-Pi-Demo, but the first one, demo_dmp outputs the 4 quaternion values, followed by the yaw, pitch and roll values corresponding to the position and movement of the GY-521 breakout board.

The second program, demo_raw outputs the values of accelerometer measurements in the x, y and z directions, followed by the gyroscope measurements in the x, y and z directions.

The third program, demo_3d plots the 3D geometrical wireframe object's orientation in space, based on the calculated values mentioned above.

What Next?

What I would like to do is use the calculated values to feed to a 2-servo combination to control a self-levelling platform.

I think this might be a bit ambitious, so if anyone out there has any ideas how I could do this, I would be very grateful for your suggestions.


No comments:

Post a Comment