Simple hardware for PC control of Radio control servos

For various hardware projects, radio control servos are a great way to get a PC to move things. They are relatively cheap, readily available, and compact. The output is a simple rotating shaft, that can be converted to a linear(ish) movement, with control horns and rods.
Control from a PC usually requires an interface (usually on the RS232 port), or special timing (on the parallel port).
The following describes a simple interface, that allows an RS232 port to connect to a servo, with just 3 components (2 diodes and a resistor). It uses simple software commands to select from 7 or 8 output positions (depends on the timing of the servo you use).

Radio control servo signals

Radio control servos have a simple three wire interface, Ground, Power, and Control.
The power is expected to come from a battery, so the range of 6V...4.5V is OK.
The Control signal is a positive pulse of around 1.5ms, repeated at about 20ms intervals. The length of this pulse, controls the servo's output position, with a duration of 1ms to 2ms usually covering the full sweep.
Old servos need the pulse to be repeated, while they drive to their target position, and also to prevent drift, but most modern servos don't need this.
You can read more at Wikipedia


Using a PIC or other micro controller, you can send pulses of controlled durations to the servo's control input. This will, reasonably accurately, set the servo's position to anywhere over it's range.
I've used the PC parallel port as the I/O interface for a number of projects. I've generated pulses on the parallel port to control a servo or two. But with modern OSs, accurate and repeatable timing is difficult. It usually requires taking over the CPU for a while. It's works OK, but it's not a great solution.
For many projects you just need a few positions, there is enough adjustment in the mechanical linkages to work it out.

RS232 timing

For a single byte, RS232 transmits this sequence:
IDDescriptionLogical valueActual voltage
iidle signal1-ve
0start bit0+ve
a..hthe data bits (LSB to MSB)0=0,1=10=+ve, 1=-ve
1the stop bit1-ve
Note: The stop bit is usually the length of the other bits, but some settings allow for 1.5x or 2x the time. For this usage it doesn't really matter, as we expect the stop bit to be followed by idle anyway.

Creating the right length pulses

When I looked at the timing of the RS232 port, I had a bit of eureka moment.
By sending a byte that starts with 0's, the start bit and the data bits form a positive pulse. The stop bit and the idle are negative.
Number of
0 data bits
Total 0 bits
(Inc start bit)
At 4800 baud, 1 bit takes 208.33us so:
30xF840.83333 msSame as 2400 baud 0xFE
40xF051.04166 ms
50xE061.25000 msSame as 2400 baud 0xFC
60xC071.45833 ms
70x8081.66666 msSame as 2400 baud 0xF8
80x0091.87500 ms
At 2400 baud, 1 bit takes 416.66us so:
10xFE20.83333 msSame as 4800 baud 0xF8
20xFC31.25000 msSame as 4800 baud 0xE0
30xF841.66666 msSame as 4800 baud 0x80
40xF052.08333 ms
50xE062.50000 ms
So we can use the RS232 TX line to generate a positive pulse, with the right timing, for the servo's control input. By clipping this signal to the power and ground pins of the servo, it will have the right signalling voltage as well.

The hardware

You do this at your own risk, it worked for me and I didn't break anything, but don't blame me if it goes wrong for you.
The hardware consists of two diodes and a resistor. I used 1N4001 diodes, and a 10K resistor, but the values aren't too critical.
The diodes clip the control signal voltage to the GND and PWR inputs of the servo. The resistor limits the current drawn from the RS232 port.
the diodes aren't perfect, to the control input will go out of range by the diode forward bais voltage, but it's not by much. Servos are designed to work in electrically noisy environments so this Should be OK.
In fact, most servos will have internal limiting diodes, so you could probably omit these two diodes, and just use the resistor, while this Should be OK, for the sake of adding the two diodes, I didn't think it was worth the risk.
               +   +----+
Control -------+---+    +--- TX data from RS232
If your are using a 9-pin connector for the RS232, then TX is Pin 2, GND is Pin 5. I tied 7+8 together. Then 1+4+6 together. This avoids handshaking issues.
I used a USB cable to provide a 5V power supply for the servo.


From a Linux command line, the following commands should move the servo from one end, to a mid-point, then the other end:
# First set permissions
sudo chmod 777 /dev/ttyS0
# Then set baud rate
stty -F /dev/ttyS0 2400
# 0xFE at 2400 baud = 0.83333 ms
echo -ne '\xFE' > /dev/ttyS0
# 0xF8 at 2400 baud = 1.66666 ms
echo -ne '\xF8' > /dev/ttyS0
# 0xE0 at 2400 baud = 2.50000 ms
echo -ne '\xE0' > /dev/ttyS0
Note: Setting the port to all access seems to work, trying to sudo the individual commands, generates extra characters on the serial port.


I used rs232-servo.c as a simple test program, and got these waveforms.
./rs232-servo 0

./rs232-servo 1

./rs232-servo 2

./rs232-servo 3

./rs232-servo 4

./rs232-servo 5

./rs232-servo 6

./rs232-servo 7

This page was lasted updated on Sunday, 25-May-2014 08:50:18 BST

This content comes from a hidden element on this page.

The inline option preserves bound JavaScript events and changes, and it puts the content back where it came from when it is closed.

Click me, it will be preserved!

If you try to open a new Colorbox while it is already open, it will update itself with the new content.

Updating Content Example:
Click here to load new content