Raspberry Pi GPIO Servo Control Without An External Controller!

Monday, February 15, 2016

A servo motor takes a PWM signal (Pulse Width Modulation) from the Raspberry Pi, which is the signal that tells the motor to which position it should move. You can control 3-wire servos without an external controller by connecting an external power source to the servo and have the control wire (and the ground) connect to the Raspberry Pi to get the PWM control signals. If you do want to control servos with an external controller, you can use a PS3 controller to control servos and DC motors very easily.

One way to control a 3-wire servo is by using Raspberry Pi GPIO pins. To do this, you use a PiCobbler but if you don't have one you can use header jumper wires to connect the servo to the Raspberry Pi. First things first, turn off your Raspberry Pi so there is no issues crossing pins while wiring the circuit. Now, attach one of these jumper wires to pin 11 and another jumper wire to ground.
You need a breadboard to breakout the leads from the Raspberry Pi to the servo motor circuitry. Connect a 3-pin jumper to the breadboard to attach the servo leads. A servo motor has three main leads which are ground (black wire), positive (red wire) and signal (yellow or white).

Now, connect the ground jumper wire on the Raspberry Pi to the jumper header with the black wire coming from the servo motor. Then, connect the jumper wire on pin 11 on the Raspberry Pi to the yellow (or white) lead coming from the servo motor. You can use an external source to power the servo motor or you could power the motor off the 5 volt rail from the header on the Raspberry Pi, which will be much easier. If you want to use an external power supply, then you simply connect the negative wire on the power supply to the black wire on the servo motor, and the positive wire on the power supply to the red cable on the servo motor.
Once that's done, you will need the code to operate the servo. To control the the Raspberry Pi's pins, you will need code that  tells the Raspberry Pi which pin numbers will be used to refer to the GPIO pins based on the P1 header. Most of the GPIO pins on the Raspberry Pi can be set to one of several modes, depending on the function that you want them to perform. In this case, we set physical pin 11's function to digital output.

To send a PWM signal, you need to create a PWM object and you do this by specifying a pin (pin 11) at a frequency of 50 Hertz.

In order to operate the servos using a PWM signal, the PWM signal has to be specified with pulse times of an absolute time rather than a percentage of the frequency since that's the way a servo works. Most servo motors require pulses of 0.5ms to 2.5ms, and unlike a motor, most servos cannot rotate a complete 360 degrees. Instead, a servo has a neutral position along with a maximum counter clockwise and clockwise rotation of zero and 180 degrees respectively. To set the servo to its neutral position, it needs a high pulse of 1.5ms. To set it to zero degrees, it needs a high pulse of 0.5ms; and to set it to 180 degrees it needsa high pulse of 2.5ms.

You will also need code that will covert an absolute pulse time to a percentage duty cycle, and for that you will need to know how many milliseconds there are per cycle. The formula for that is to divide 1000 by 50 Hertz, which is the value specified in the PWM object.

Next up, you need a loop sequence code that will iterate through the positions sequence 3 times and calculates the duty cycle percentage, which is the position converted to a percentage based on the milliseconds per cycle. This sequence code contains positions from left to right and then back again, and will move the servo motor to each position in order.

Finally, when the loop code has finished executing, you need a line of code that will send a signal to the PWM to terminate the signal and relax the motor, as well as a line of code that relinquishes all control of the hardware to any other processes that might be trying to use it. With that said, you end up with the following code to control a servo motor using Raspberry Pi GPIO pins without an external controller:

import RPi.GPIO as GPIO
GPIO.setup (11, GPIO.OUT)

frequencyHertz = 50
pwm = GPIO.PWM(11, frequencyHertz)

leftPosition = 0.5
rightPosition = 2.5
middlePosition = (rightPosition - leftPosition) / 2 + leftPosition
positionList = [leftPosition, middlePosition, rightPosition, middlePosition]

msPerCycle = 1000 / frequencyHertz

for i in range(3);
for position in positionList:
dutyCyclePercentage = position * 100 / msPerCycle
print "Position: " + str(position)
print"Duty Cycle: " + str(dutyCyclePercentage) + "%"
print ""



If you would like to take the easy way out, the easiest way of controlling a servo is by using a Raspberry Pi add-on such as servo daughter cards for the Raspberry Pi card that provide a multiple channel I2C controlled Servo driver that will allow your Raspberry Pi to control multiple servos. You can get one of these servo cards from Tindie or eBay

You Might Also Like


About Gadget Explained

Connect With Gadget Explained