This article describes building a small (3.3 cm times 3.3 cm) RC servo controller using an avr microprocessor and an FT232RL USB-uart chip. All RC servo signals can be set to pulsewidths from 0 to 8.1 ms using the usb-serial interface.
RC Servos are popular among modelling and robotics enthusiasts because of their simplicity. They take a pulsewidth-encoded input, and turn accordingly with relatively high torque. They have their disadvantages, for example one cannot tell if the servo was able to get where it was sent, but their low price and the fact that driver and gear box are integrated make up for that. Also, Conrad sells them for 3 € a piece, so I bought some.
My first idea was to control them with firmware-usb, however, the high load imposed on the controller by usb makes software-pwm erratic, and also, implementing the usb communicating device class is not possible for low-speed devices.
The path I followed that resulted in the servo controller pictured above was, to use an FT232R usb-to-uart converter and an Attiny 2313a microcontroller to provide the software pwm. There are some other possibilities, like taking an at90usb or another microcontroller with usb, but FTDI has nice chips, good support, and one can get usb pids from them, and remans flexible. If 12 servos are not enough, the software should easily be portable to a bigger avr, the chips are widely avalable and low in cost: I got the attiny for about 1 € and the FT232RL for about 2.5 € at CSD.
This was my first project using kicad and my first project using surface mounted technology, and surprisingly both made few problems. Even soldering the tqfp-sized FT232RL without solder resist worked well, though i needed lots of light and a good magnifying glass.
You will need:
- One FT232RL USB-to-UART convertor
- One Attiny 2313a (or the older, nrfnd, attiny2313) avr microprocessor.
- An USB B-type connector
- A 6-pin connector for your AVR-ISP programmer.
- Connectors for the servos. I used simple multi-pin connectors and some colored insulating tape to mark plus, minus and signal.
- A connector for your power supply.
- An optional jumper to power the servos from usb. Since the device does not ask the usb host for more power, this is outside the usb specifications. however, with small miniservos it is convenient, as you do not need an extra power supply.
- One 4.7 µF electrolyte capacitor
- Three SMD 100 nF ceramic capacitors and two 10 kOhm resistors. The plan calls for size 0603, but the resistors I used were actually 0805, and fitted also well.
- A printed circuit board. With the right equipment, you can make this yourself. Or you can have one made for you at various companies
All the parts together cost about 5 € (with a self-made pcb).
The software provides a rather minimalistic interface. To send commands, open the serial port at 9600 baud, using your favorite terminal program, I used gtkterm.
The available commands are:
- Typing v shows the device name, a link here, and the software version.
- Typing l lists the servo numbers and the corresponding pwm settings. The pwm settings are the number of cpu cycles the servo should get a high signal level.
- Typing d shows the softpwm table, a list of when which signals should go from high to low. This list is calculated from the pwm settings, it’s mainly there for debugging purposes.
- Typing s (servonumber) (new value) sets the pwm value for the selected servo. Be sure to send a newline character or other whitespace to execute the command.
Since RC servos typically want a 1 ms pulse (at 8 MHz this are 8000 cpu cycles) for one end, and a 2 ms pulse (similarly, at 8 MHz this are 16000 cpu cycles) for the other end, you would in linux do something like
stty -F /dev/ttyUSB0 9600 echo "s 11 8000 " > /dev/ttyUSB0 echo "s 10 16000 " > /dev/ttyUSB0
to send servo 11 to one end and servo 10 to the other. If you have other serial devices, the device might not be /dev/ttyUSB0, but /dev/ttyUSB1 or so. Should this be a problem, you can create a udev rule to create a symlink. Note that the actual pulse lengths required to go to the mechanical end of the servo differ widely between servo types, I do not know if there is some standard, if you do, please tell me.
For some cases, like finding the end positions of the rc servos, it is convenient to have a graphical user interface, which is also available.
Usage with embedded linux devices
In most households, many devices run linux and have an usbport. however, without a modified firmware most cannot connect to serial usb devices. I tested a fritzbox 7270 (possible with alternative firmware freetz, not with the original firmware), a dreambox dm 7000(no success, and alternative firmwares are lost in the mists of time), and an Asus oplay hdp-r1(also no success, and alternative firmwares seem to be not yet available). So, unless you have a device that runs openwrt by default, chances are this won’t work without some work.
List of things still to do
- As seen on the pictures, the avr isp connector is slightly too large, so either a smaller one has to be used, or only 8 servo connectors have place. For testing purposes, this was enough, but a new hardware revsion is necessary.
usbservo_hardware.tar.gz (60.86 kiB, 2010-08-12)
usbservo_software.tar.bz2 (48.24 kiB, 2010-08-14)
qusbservoc.tar.gz (20.49 kiB, 2010-08-14)
usbservo_schematic.pdf (26.66 kiB, 2010-08-12)
usbservo_pcb.pdf (23.32 kiB, 2010-08-02)