Servo Control Stuff

In the past few months I have been playing around with some cheap servos.  I started by making a four-leg walking “thingie” out of oversized Popsicle sticks.  The hardest part was keeping it balanced when one of the legs was lifted for movement.  That exercise prompted me to build a 3-DOF (degrees of freedom) tester so that I could test servo movement in general and also verify pulse width settings for the desired positions of each 3-DOF leg.  More recently I decided to buy a cheap 4-DOF robot arm kit that did not include control electronics.  This article is sort of a mishmash of what I’ve learned so far about servo control and includes schematics and PIC software for the 3-DOF tester and the 4-DOF robot arm controller.

Cheap Servos

The cheap servos available from online suppliers have a rotation range of 180 degrees.  They consist of a small motor, some gears, and a control circuit that requires a PWM (pulse width modulation) input.  In general, the PWM frequency is set to 50-Hz for servos and the servo position is varied by sending a pulse width of about 500 microseconds to about 2.5 milliseconds (1.5 milliseconds centers the servo).  The first information I found online indicated a range of 1ms to 2ms but that only moved the servos 45 degrees either side of center.



One of my earlier projects (posted on my website) talked in detail about PWM so I won’t repeat that information here.  Check out the Model Train Controller for those details.  In my previous projects I used the PWM capability built into one of the PIC microcontrollers but that is insufficient when you have more than one servo to control.  There are a variety of ways to handle multiple servos and that includes external modules that do the PWM for you.  When I built the four-leg walker I used three servos per leg so I needed to control 12 altogether.  Fortunately, there is a module that accepts I2C serial command inputs to generate up to 16 separate PWM outputs.    Just search for “PCA9685” on ebay.  There are also some simple PWM modules that have either an LED or LCD and can output 2 or 3 separate PWM signals.  Mostly they are for manual control via the onboard buttons but they can also be controlled using a 9600 baud RS-232 type of interface.  I don’t recommend these for servo control because multiple PWM outputs can be generated in software for a PIC.  I used the PIC 16F688 chip for both the 3-DOF servo tester and the 4-DOF robot arm controller.

Software Generated PWM

As I indicated earlier, a typical PWM frequency for servos is 50-Hz and the servos are positioned by sending a pulse during each frequency period.  The 50-Hz interval is set in the PIC software using Timer0.  When it times out, an interrupt is generated and a flag is set to let the main routine know that it is time to send pulses to the servos.  Given that 50-Hz is a 20ms period it is easy to fit control pulses for several servos within each time frame.  For simplicity, the pulses for each servo are sent out sequentially.  That means that the PIC only has to use a single timer to generate the desired pulse widths.  For instance, Timer1 is loaded with the desired pulse time for servo1, the control output for servo1 is set high, the software waits for the timeout, and then the control output for servo1 is set low.  The sequence is repeated for each of the remaining servos.  The maximum pulse width for each servo is 2.5ms so four servos only use about half of each 20ms period.  The servos don’t care where the pulse occurs within the time frame.

3-DOF Servo Tester


The servo tester uses potentiometers to allow variance of the servo pulse widths.  There is also a switch for forcing all servos to the center position.  An LCD is included so that the actual pulse width values can be observed without having to connect to an oscilloscope.  Each potentiometer forms a simple voltage divider between +5 volts and ground and is connected to a PIC pin that is set for use as an ADC (analog-to-digital conversion) input.  Based on the voltage read, a calculation is performed to convert the voltage to a servo pulse width.  Basically, the formula is: (V * 7.5) + 600.  I found that 600 was the “real” minimum pulse width for my servos as opposed to the stated value of 500.  Remember that “V” in the formula is actually the truncated 8-bit ADC value (0-255) of the input voltage from the potentiometer.  On its own, the PIC doesn’t do multiplies or divides so the simple method for getting 7.5 was to left shift the ADC value three times (multiply by 8) and then subtract the right shift of the ADC value (0.5).

The LCD interface uses just 3 PIC pins but requires the addition of a 74HC164 shift register.  The details of the hardware are discussed in the “3-wire, 8-bit LCD Interface” project on my website.  The LCD shown in the picture is an oversized, single line one that I picked up as surplus but the software will work with the standard 1602 LCD.

Servo Tester 3DOF

Servo tester 3DOF

4-DOF Robot Arm Controller



The kit for the robot arm shown in the picture can be bought for $25-$30 online.  I opted for one with servos that have metal gears so it was at the high end of that range.  I attached the flat robot arm base to a large project box which contains the control circuitry.  The hardware/software was base lined off of the 3-DOF servo tester.  A fourth potentiometer was added to the hardware, limit checks were added to the software, and the routines for the LCD were stripped out.  I used the 3-DOF servo tester to get a feel for the maximum ranges I wanted for each servo.  The range checks are not essential but I thought they might be a good idea given that I let my young grandkids play with it.  I’ve debated adding simple Bluetooth control for the robot arm so I specifically left the PIC serial ports pins available.  Otherwise, the hardware/software could be modified for 5-DOF.  You might think that you could go to 6-DOF with 12 I/O lines but RA3 is an input only and digital only pin.

Robot Arm1


Check out my other projects at: