Another illustration that demonstrate how to use MPU6050 on Raspberry Pi. The MPU 6050 sensor board contains a MEMS ACCELEROMETER and MEMS GYRO a single chip that provide a very accurate data, as it contains 16bits analog to digital conversion hardware for each channel that captures the X, Y, and Z channel at the same time. The board sensor uses i2c Bus interface that you can just hookup to your Raspberry Pi.
The MPU 6050 combines both an accelerometer and a gyro together in one single chip. There two type of MPU version there is 6050 and 9150 that has a MAGNETOMETER (Compass) integrate to chip. On this illustration we will cover only the MPU 6050 without using the magnetometer. Getting the raw values for the accelerometer and the gyro is quite easy. The sleep mode has to be disable and then the registers for the accelerometer and gyro can be read. The sensor also contains 1025 bytes FIFO buffer that can be programmed to be place into FIFO buffer and the buffer can be ready by the microcontroller.
The FIFO buffer is used together with the interrupt signal if the MPU 6050 places a data into the FIFO buffer it send signals to the Raspberry PI with the interrupt signal. The Raspberry Pi knows that there is a data coming from FIFO buffer that ready to be read.
The MPU 6050 always acts as a slave to the Arduino with the SDA and SCL pins connected to i2c BUS. The board has also its own i2c controller to be a master on a second sub i2c bus. It uses the pins AUX_DA and AUX_CL for the second sub i2c BUS you can control the magnetometer and the values of the magnetometer can be passed into the Raspberry Pi.
The sensor has a Digital Motion Processor (DMP) or Digital Motion Processing Unit these DMP can be programmed with firmware and can do a complex calculation with the sensor values.
The Digital Motion Processor can calculate directly to the chip at this state the load reduce for the Raspberry Pi. The DMP can even do a calculations with the sensor values of another chip, for example if the magnetometer connected to the second i2c Bus.
Required Components
- Raspberry Pi / Banana Pi / Orange Pi (If your using Banana Pi or Orange See first the GPIO Pin Mapping)
- Rotary Encode
- Solder Less Bread Board
- Jumper Wire / DuPont Wire
Wiring Diagram
Configuring Raspberry Pi i2C Bus Interface
Uploading the code
C Code : Example 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
#include <wiringPiI2C.h> #include <stdio.h> #include <math.h> int fd; int acclX, acclY, acclZ; int gyroX, gyroY, gyroZ; double acclX_scaled, acclY_scaled, acclZ_scaled; double gyroX_scaled, gyroY_scaled, gyroZ_scaled; int read_word_2c(int addr) { int val; val = wiringPiI2CReadReg8(fd, addr); val = val << 8; val += wiringPiI2CReadReg8(fd, addr+1); if (val >= 0x8000) val = -(65536 - val); return val; } double dist(double a, double b) { return sqrt((a*a) + (b*b)); } double get_y_rotation(double x, double y, double z) { double radians; radians = atan2(x, dist(y, z)); return -(radians * (180.0 / M_PI)); } double get_x_rotation(double x, double y, double z) { double radians; radians = atan2(y, dist(x, z)); return (radians * (180.0 / M_PI)); } int main() { fd = wiringPiI2CSetup (0x68); wiringPiI2CWriteReg8 (fd,0x6B,0x00);//disable sleep mode printf("set 0x6B=%X\n",wiringPiI2CReadReg8 (fd,0x6B)); while(1) { acclX = read_word_2c(0x3B); acclY = read_word_2c(0x3D); acclZ = read_word_2c(0x3F); acclX_scaled = acclX / 16384.0; acclY_scaled = acclY / 16384.0; acclZ_scaled = acclZ / 16384.0; printf("My acclX_scaled: %f\n", acclX_scaled); printf("My acclY_scaled: %f\n", acclY_scaled); printf("My acclZ_scaled: %f\n", acclZ_scaled); printf("My X rotation: %f\n", get_x_rotation(acclX_scaled, acclY_scaled, acclZ_scaled)); printf("My Y rotation: %f\n", get_y_rotation(acclX_scaled, acclY_scaled, acclZ_scaled)); delay(100); } return 0; } |
C Code : Example 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#include <wiringPiI2C.h> #include <stdio.h> #include <math.h> int fd; int acclX, acclY, acclZ; int gyroX, gyroY, gyroZ; double acclX_scaled, acclY_scaled, acclZ_scaled; double gyroX_scaled, gyroY_scaled, gyroZ_scaled; int read_word_2c(int addr) { int val; val = wiringPiI2CReadReg8(fd, addr); val = val << 8; val += wiringPiI2CReadReg8(fd, addr+1); if (val >= 0x8000) val = -(65536 - val); return val; } int main() { fd = wiringPiI2CSetup (0x68); wiringPiI2CWriteReg8 (fd,0x6B,0x00);//disable sleep mode printf("set 0x6B=%X\n",wiringPiI2CReadReg8 (fd,0x6B)); while(1) { gyroX = read_word_2c(0x43); gyroY = read_word_2c(0x45); gyroZ = read_word_2c(0x47); gyroX_scaled = gyroX / 131.0; gyroY_scaled = gyroY / 131.0; gyroZ_scaled = gyroZ / 131.0; printf("My gyroX_scaled: %f\n", gyroX_scaled); printf("My gyroY_scaled: %f\n", gyroY_scaled); printf("My gyroZ_scaled: %f\n", gyroZ_scaled); delay(100); } return 0; } |
Python Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
#!/usr/bin/python import smbus import math import time # 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) while True: time.sleep(0.1) 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) 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) time.sleep(0.5) |
Downloads
Download MPU 6050 Datasheet | Pdf