Raspberry Pi GPIO Servo Control Without An External Controller!Monday, February 15, 2016
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.
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.
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)
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) + "%"
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