Friday, March 20, 2015

MPU6050 with Intel Galileo (Python interface)

The MPU6050 is an integrated 6-axis Motion-tracking device that combines a 3-axis gyroscope, 3-axis accelerometer, and Digital Motion Processor (Datasheet and Register Mapping).
It is accurate, as it contains 16-bits analog to digital conversion hardware for each channel. Therefore it captures x, y, and z channel at the same time. The sensor has an I2C-bus so we can communicate with this device over I2C.

MPU6050 with Galileo (Arduino Environment):


This is pretty simple, for this you need to boot small SPI flash image (default one). Several sources are already available in internet but if you couldn't find it please check this out.

MPU6050 with Galileo - Python interface (Linux Environment):


To do this, you need to boot bigger linux image.

Connecting the sensor: 




To do this, your image needs to have python-smbus module. python-smbus is a Python module allows SMBus access through the I2C interface on Linux hosts. The host kernel must have I2C support, I2C device interface support, and a bus adapter driver.

The official image doesnot contain python-smbus module.

Workaround for python-smbus on Intel Galileo:  

  • First, you need to use an image with dev-tools installed on it (I’m using an image provided by Intel). Download the image from here.
  • Manually download I2C library from here and extract the tar file.
  • Before compilation, you have to patch a single line.
  • Go to the extracted directory and edit smbusmodule.c file in py-smbus directory. 
  • cd py-smbus
    vi smbusmodule.c
  • Change the constant I2C_SLAVE to I2C_SLAVE_FORCE in line 159 and then compile the source code.
  • make EXTRA="py-smbus"
    make install     # This will create the i2c-tools
    #The tools like i2cdetect and i2cget should be work now
    #Then go into the py-symbus directory and call
    python setup.py install
  • Now you should be able to execute a python script like this.
  • from smbus import SMBus
    bus = SMBus(0)
    bus.write_byte_data(0x20, 0x29, 0x04)

Note: IO mapping in Gen 2 is different from Gen 1.

For Galileo Gen 1:

If you want to communicate with external I2C slaves (like MPU6050, TSL2561), then you need to change the value of GPIO 29 to 0 (default is 1).
echo -n "29" > /sys/class/gpio/export
cd /sys/class/gpio
cat /gpio29/value # check the value of GPIO 29, it is 1 change it to 0
echo -n "out" > /sys/class/gpio/gpio29/direction
echo -n "0" > /sys/class/gpio/gpio29/value # After this, A4 and A5 lines act like
#SDA and SCL lines respectively 

For Galileo Gen 2:
echo -n "60" > /sys/class/gpio/export
cd /sys/class/gpio
cat /gpio60/value # check the value of GPIO 60, it is 1 change it to 0
echo -n "out" > /sys/class/gpio/gpio60/direction
echo -n "0" > /sys/class/gpio/gpio60/value # After this, A4 and A5 lines act like
#SDA and SCL lines respectively 

For IO Mapping, please check the below links.

Python program for MPU6050
#!/usr/bin/python

import smbus
import sys

# This is the address value read via the i2cdetect command
# if AD0 pin is connected to ground, address will be 0x68
# if AD0 pin is connected to vcc, address will be 0x69
 
ADDRESS_LOW      = 0x68
ADDRESS_HIGH     = 0x69

# Power management registers
power_mgmt_1  = 0x6B
power_mgmt_2  = 0x6C
SMPLRT_DIV       = 0x19
#Registers from which read accel, temp and gyro sensor values
ACCEL_XOUT_H  = 0X3B
ACCEL_YOUT_H  = 0X3D
ACCEL_ZOUT_H  = 0X3F

TEMP_OUT_H  = 0X41

GYRO_XOUT_H   = 0X43
GYRO_YOUT_H  = 0X45
GYRO_ZOUT_H   = 0X47

address = ADDRESS_HIGH

def write_byte(radd, val):
    bus.write_byte_data(address, radd, val)

def read_byte(radd):
    return bus.read_byte_data(address, radd)

def read_word(radd):
    high = bus.read_byte_data(address, radd)
    low = bus.read_byte_data(address, radd+1)
    val = (high << 8) + low
    return val

def read_word_2c(radd):
    val = read_word(radd)
    if (val >= 0x8000):
        return -((65535 - val) + 1)
    else:
        return val

try:
    bus = smbus.SMBus(0)
    # Now wake the 6050 up as it starts in sleep mode
    write_byte(power_mgmt_1, 0x01)

    while(True):
        try:

            accel_xout = read_word_2c(ACCEL_XOUT_H)
            accel_yout = read_word_2c(ACCEL_YOUT_H)
            accel_zout = read_word_2c(ACCEL_ZOUT_H)

            gyro_xout = read_word_2c(GYRO_XOUT_H)
            gyro_yout = read_word_2c(GYRO_YOUT_H)
            gyro_zout = read_word_2c(GYRO_ZOUT_H)

            temp_val = read_word_2c(TEMP_OUT_H)
   
            print "######################################"
            print "accelerometer data"
            print "------------------"  

            print "accel_xout: ", accel_xout
            print "accel_yout: ", accel_yout
            print "accel_zout: ", accel_zout

            print "gyro data"
            print "---------"

            print "gyro_xout: ", gyro_xout
            print "gyro_yout: ", gyro_yout
            print "gyro_zout: ", gyro_zout

            temp_dT = (temp_val / 340)+36.53
            print "temp val: ", temp_dT

        except KeyboardInterrupt:
            write_byte(power_mgmt_1, 0x41) # Sleep mode
            print "Keyboard exception arises.
            print "Program interrupted."
            print "Program is going to terminate."
            break

except IOError:
    print "Program IO Error."

except:
    print "Program General Exception." 
 
sys.exit()  

Reference:

17 comments:

  1. when I am going cat /gpio60/value. It is showing no such file or directory. Also I have attached the connections in the very same manner as described above to my intel galileo gen 2 but the light on MPU is not turning on.Is the schematic for connection different for gen-2?

    ReplyDelete
  2. After rectifying the above error,now it throwing "program exception error".I think the mpu has not been interfaced properly with the intel galileo gen-2 board,because the light is not on on mpu

    ReplyDelete
    Replies
    1. Hi Amardeep,
      Sorry for my late reply. Connections for gen 2 is not different than gen 1.
      Please make sure you have compiled smbus properly. The sysfs interface, expose the system information and control points to user space from the kernel space. I used the above approach when I initially started to work with Galileo. now, if you are using Intel's official os for Galileo, accessing the pins should not be a problem. You can use mraa library provided from Intel to access any pin on Galileo very easily (including I2C).

      Delete
    2. Hi sharwesh!
      I couldnt find VI0 pin--is it AD0 pin in MPU6050?Kindly reply

      Delete
    3. Also if you're on facebook,then do let me know.Would contact you there

      Delete
  3. Hi Amardeep,

    1. Yes, it is AD0. I updated the guide. Please check
    2. In Sparkfun's MPU6050 module, AD0 pin is not exposed and AD0 is connected to GND(so it supports only one I2C slave address, 0x68). Also the module has an additional pin called 'VIO'. If you are using this, connect VIO to VCC

    I don't use facebook much. Instead, post your questions in the blog or send me a mail

    ReplyDelete
    Replies
    1. sharweshkumar,ok send me your mail then!

      Delete
    2. I basically wanted to know how to use i2c feature of either upm or mraa library that comes shipped with latest yocto image. Unfortunately there aint many good tutorial available.

      Delete
    3. Plenty of resources out there. Read the mraa documentation before starting to write the code
      http://iotdk.intel.com/docs/master/mraa/python/mraa.html#i2c
      https://communities.intel.com/thread/87108
      https://communities.intel.com/thread/109924

      Delete
    4. Hi sarvesh kumar!
      After a lot of searching I finally came to know of mpu6050 support in upm library.
      https://github.com/intel-iot-devkit/upm/blob/master/examples/python/mpu60x0.py
      However my only issue is,when I use this library and fire up mpu6050,I get Gyro values as 11.26 about x axis,-2.2 about y and similarly -4 about z axis. My problem is how can I get these values constantly even when my mpu6050 is lying still on my table?Are these initial garbage values? After all these are supposed to be angular rates right?

      Delete
    5. Also do send me your email id!

      Delete
    6. I don't have much experience in understanding and analyzing the sensor data. Please ask the above question in some other forum.

      Check the blogger profile to get my contact info

      Delete
  4. And one more thing the last link you shared with me is my own question that I asked at intel communities forum.
    Here is that link-
    https://communities.intel.com/thread/109924

    My question in previous message about gyroscope can be found in the above link.Kindly open it and check please!

    ReplyDelete
  5. This link seems to be broken
    http://www.lm-sensors.org/wiki/I2CTools

    any other link to get the i2c tools?

    ReplyDelete

Fun with RGB LED

People often need home lighting control in their lives. These individuals can easily find relevant products which often use different meth...