Monday, December 22, 2014

60. Exploring the Pi B+'s Ports VI - Controlling Servos Using the MPU-6050

27,000 page views!!
Hopefully I'm getting a bit closer to a self-balancing platform.  The stage I'm at now effectively has the accelerometer signal being sent to the 2 servos, rotation of the MPU-6050 about its x-axis, rotating one servo, and rotation about the y-axis controlling the second servo.

Here's the code:


Here's the video:

The sensitivity can be changed by adjusting the code

Saturday, December 20, 2014

59. Exploring the Pi B+'s Ports V - Controlling Servos and Reading the MPU-6050

Controlling servos using an Arduino is very easy.  Remember the light follower at my post number 45, which used the Arduino Servo.h library HERE?

The Arduino chip is good at this because it can deliver what the servo needs - very accurate PWM (Pulse Width Modulation) signals.  This is not possible to do on a Pi (see the RasPi.tv article HERE) because there are so many routines running and interrupting. In any case, the Raspberry Pi has only one hardware and one software PWM output.

The way to do it on a Pi is to use the Adafruit 16 Channel 12 Bit PWM and Servo Driver Breakout Board which does all of the hard work while the Raspberry Pi just tells it what to do. This board is based on a PCA9685 chip which was actually designed to be an LED controller. It is a PWM driver, controlled by I2C with a fast built-in clock, capable of operating at frequencies up to 1MHz. The 16 channels allow up to 16 PWM devices to be connected - ideal for robotics with lots of servos. 

The board only requires a 3V3 power supply for the chip, GND, and two connections, SCL (the clock line) and SDA (the data line), both of which hang off the I2C bus.  There are 2 further ports for external power and GND for the servos, which the Raspberry Pi would not be able to deliver.  The Adafruit board cost £11.98 including delivery from ModMiPi.  I also bought 2 x YKS New NEW SG90 9g Mini Servo motors from Amazon for £2.30 (free delivery).  These have a 180 degree range - even better than the previous ones I used in the Light Follower, which can rotate about 135 degrees.

The photos below give an idea of the circuitry:
From above, you can see the Pi with the Cyntech paddle board, connected as before to the GY-521 breakout board with the MPU6050 (on the blue breadboard).  I have taken the I2C lines and the 3V3 power and GND from that to the Adafruit servo driver.  The external power to the Adafruit board comes from an adjustable Step Down Supply Power Module with a 4V to 40V input and a 1.5V to 35V output.  It is capable of supplying a current of 2A.  I bought it about a year ago for about £2.  That's it on the white breadboard at the top of the picture.  It is powered from a mains supply of nominal 12V (capable of up to 1 amp). 

I tuned the output of the step down module to 5V for the servos, using its adjustable potentiometerYou can see the 2 servos joined at right angles to each other on the left - each of them can draw currents of some hundreds of mA.  The servos are connected to channels 11 and 15 of the Adafruit board.

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: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --                       


This shows a map of the registers on the Pi's I2C bus.  Two extra entries at the hexadecimal addresses 0x40 and 0x70 show that two I2C devices (the 2 servos in this case) have been detected at those addresses. 
Here's the Python script which I put together from Andrew Birkett's and Adafruit's work.  This is another step on the way to controlling the servos from the signals from the MPU6050:


Note that the xrot and yrot outputs (rotations in degrees about the x- and y-axes respectively) which are printed on the screen at the beginning of the video, are calculated from accelerometer data only, even though the gyroscope data is read also.

And here's the video:
Hopefully I'm going in the right direction to make a self-balancing platform!!

Friday, December 12, 2014

58. Exploring the Pi B+'s Ports IV - Reading the MPU-6050 using Python

26,000 page views!!
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:

Andrew Birkett's really neat code reads the accelerometer part of the MPU-6050 and prints out the x- and y-axis rotations which are calculated by the program.  The output via the web page looks like this:
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:

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?