Showing posts with label I2C. Show all posts
Showing posts with label I2C. Show all posts

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:

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...