The last post described the 3D wireframe demonstration of the MPU-6050's rotations (ie the GY-521 breakout board) about the x-, y- and z-axes, and other scripts which displayed the readout of quaternions etc. Those test programs were written in the C++ programming language.
This time test programs are written in Python, giving me a better chance of understanding what's going on! The circuitry is identical to that used in the last post, and of course, the I2C interface has previously been enabled.
smbus is a Python module which allows SMBus (system management bus - a sub-set of the I2C protocol) access through the I2C interface on Linux hosts. This is the key module for Python access.
Reading Accelerometer Data
In this first program, in addition to reading the data from the accelerometer, the output values are sent to a web page, just for fun! The address of the web page depends on the Pi's IP address, which can be found using the terminal command
ifconfig
and appending :8080 to the end. For example,
http://ip-address-of-your-pi:8080
Here's the Python code for server.py:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
#This python program serves a web page which can be accessed via | |
#local wifi network, giving x and y rotations of the MPU-6050 | |
# Written by Andrew Birkett | |
# (http://blog.bitify.co.uk/2013/11/3d-opengl-visualisation-of-data-from.html) | |
# and modified by S&S Dec 2014 | |
import web | |
import smbus | |
import math | |
urls = ( | |
'/', 'index' | |
) | |
# Power management registers | |
power_mgmt_1 = 0x6b | |
power_mgmt_2 = 0x6c | |
bus = smbus.SMBus(1) # or bus = smbus.SMBus(0) for pre-Revision 2 boards | |
address = 0x68 # This is the address value read via the i2cdetect command | |
def read_byte(adr): | |
return bus.read_byte_data(address, adr) | |
def read_word(adr): | |
high = bus.read_byte_data(address, adr) | |
low = bus.read_byte_data(address, adr+1) | |
val = (high << 8) + low | |
return val | |
def read_word_2c(adr): | |
val = read_word(adr) | |
if (val >= 0x8000): | |
return -((65535 - val) + 1) | |
else: | |
return val | |
def dist(a,b): | |
return math.sqrt((a*a)+(b*b)) | |
def get_y_rotation(x,y,z): | |
radians = math.atan2(x, dist(y,z)) | |
return -math.degrees(radians) | |
def get_x_rotation(x,y,z): | |
radians = math.atan2(y, dist(x,z)) | |
return math.degrees(radians) | |
class index: | |
def GET(self): | |
accel_xout = read_word_2c(0x3b) | |
accel_yout = read_word_2c(0x3d) | |
accel_zout = read_word_2c(0x3f) | |
accel_xout_scaled = accel_xout / 16384.0 | |
accel_yout_scaled = accel_yout / 16384.0 | |
accel_zout_scaled = accel_zout / 16384.0 | |
xrot = get_x_rotation(accel_xout_scaled, accel_yout_scaled, accel_zout_scaled) | |
yrot = get_y_rotation(accel_xout_scaled, accel_yout_scaled, accel_zout_scaled) | |
# Return angle values to 1 decimal place | |
return "x-rotation: %.1f" %xrot+" degrees. y-rotation: %.1f" %yrot+" degrees" | |
if __name__ == "__main__": | |
# Now wake the 6050 up as it starts in sleep mode | |
bus.write_byte_data(address, power_mgmt_1, 0) | |
app = web.application(urls, globals()) | |
app.run() |
x-rotation: 0.2 degrees. y-rotation: -2.2 degrees.
The values of course change as the MPU-6050 is rotated about its x- and y-axes. for example:
x-rotation: 50.8 degrees. y-rotation: 18.4 degrees.
The web page has to be refreshed to see new values.
Reading Gyro & Accelerometer Data
This program, Reading6050.py, also written by Andrew Birkett, looks like this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import smbus | |
import math | |
# Power management registers | |
power_mgmt_1 = 0x6b | |
power_mgmt_2 = 0x6c | |
def read_byte(adr): | |
return bus.read_byte_data(address, adr) | |
def read_word(adr): | |
high = bus.read_byte_data(address, adr) | |
low = bus.read_byte_data(address, adr+1) | |
val = (high << 8) + low | |
return val | |
def read_word_2c(adr): | |
val = read_word(adr) | |
if (val >= 0x8000): | |
return -((65535 - val) + 1) | |
else: | |
return val | |
def dist(a,b): | |
return math.sqrt((a*a)+(b*b)) | |
def get_y_rotation(x,y,z): | |
radians = math.atan2(x, dist(y,z)) | |
return -math.degrees(radians) | |
def get_x_rotation(x,y,z): | |
radians = math.atan2(y, dist(x,z)) | |
return math.degrees(radians) | |
bus = smbus.SMBus(1) # or bus = smbus.SMBus(1) for Revision 2 boards | |
address = 0x68 # This is the address value read via the i2cdetect command | |
# Now wake the 6050 up as it starts in sleep mode | |
bus.write_byte_data(address, power_mgmt_1, 0) | |
print "gyro data" | |
print "---------" | |
gyro_xout = read_word_2c(0x43) | |
gyro_yout = read_word_2c(0x45) | |
gyro_zout = read_word_2c(0x47) | |
print "gyro_xout: ", gyro_xout, " scaled: ", (gyro_xout / 131) | |
print "gyro_yout: ", gyro_yout, " scaled: ", (gyro_yout / 131) | |
print "gyro_zout: ", gyro_zout, " scaled: ", (gyro_zout / 131) | |
print "accelerometer data" | |
print "------------------" | |
accel_xout = read_word_2c(0x3b) | |
accel_yout = read_word_2c(0x3d) | |
accel_zout = read_word_2c(0x3f) | |
accel_xout_scaled = accel_xout / 16384.0 | |
accel_yout_scaled = accel_yout / 16384.0 | |
accel_zout_scaled = accel_zout / 16384.0 | |
print "accel_xout: ", accel_xout, " scaled: ", accel_xout_scaled | |
print "accel_yout: ", accel_yout, " scaled: ", accel_yout_scaled | |
print "accel_zout: ", accel_zout, " scaled: ", accel_zout_scaled | |
print "x rotation: " , get_x_rotation(accel_xout_scaled, accel_yout_scaled, accel_zout_scaled) | |
print "y rotation: " , get_y_rotation(accel_xout_scaled, accel_yout_scaled, accel_zout_scaled) |
The program produces results like this:
pi@raspberrypi ~ $ sudo python Reading6050.py
gyro data
---------
gyro_xout: -202 scaled: -2
gyro_yout: -191 scaled: -2
gyro_zout: 11 scaled: 0
accelerometer data
------------------
accel_xout: 176 scaled: 0.0107421875
accel_yout: 160 scaled: 0.009765625
accel_zout: 15364 scaled: 0.937744140625
x rotation: 0.596614942501
y rotation: -0.656278927449
pi@raspberrypi ~ $
So what does the program do and what do these results mean?
No comments:
Post a Comment