PIC Based Serial Port Servo Controller
Author: Ashley Roll, Sept 2000.
Some Photos: PicServo1.jpg (300kb) PicServo2.jpg (300kb)
As Published in Electronics Australia, September 2000.
Click here to read the Article. It describes the circuit its construction.
PICServo Serial Port Servo Controller
- 28 Jan, 2002 - Bug found in 8 Servo motor variant, refer to 8 servo code page for details.
- 28 Oct, 2001 - Serial Transfer Bug found.
- Dec, 2005 - This project is no longer supported. The information is here for you to use. A new version of the PIC Servo controller is in the works and it will use a more modern PIC and support much faster serial communication and better position control commands.
The PIC Based servo controller is a small project I designed to allow me to control some robotics. I then decided that I should publish it as it may be of interest to other people.
The Servo Controller uses a PIC16F84 microcontroller from Microchip to drive servo motors and digital outputs. It receives commands from a host computer via a standard RS232 serial interface.
You can download the PIC program which contains a HEX file which most PIC programmers can read; and a PIC Assembler code (ASM) file if you would like to see how it works or modify it.
I used the free PIC assembler from Microchip, the manufactures of the PIC range of Microcontrollers.
Several contributors have provided code samples that you can use to drive the PIC Servo project.
- Nov, 2001 - Jose Maria Diaz de la Cruz of the Polytechnical University of Madrid (Spain) has provided an ActiveX control (ocx) and a Visual Basic Project. Note you will need to compile the Visual Basic project as it contains source only.
- Feb 2002 - Richard Gardiner provided a Windows executable which is targeted at driving the 8 servo variant.
Here are some Acrobat files for the Schematic, Single sided PCB and Overlay artwork:
You will need an Acrobat reader available for free from www.Adobe.com to view and print these files.
Note that the PCB is a single sided board, about 88 mm by 53 mm (3.5 inches by 2.1 inches). I have provided the track patters viewed from both sides of the board so you can choose the one that suits your method of production.
I have been asked for a version that will control eight servos, so I have altered the code to support this.
Servo Controller Commands
To control the servos and outputs we need to send commands to the PIC. Some of the commands are single byte commands; some however require two bytes.
The first byte always contains the command and the channel to which the command applies. We will call this the 'Command' byte. The second byte (when needed) will contain data for the command; we will call this the 'Data' byte and is used when we need to set the servo offset or position for example.
The command byte is split into two nibbles (4 bits), the upper one defines the command to execute and the lower defines the channel (which servo or digital output) is to be affected.
|Bit 7||Bit 6||Bit 5||Bit 4||Bit 3||Bit 2||Bit 1||Bit 0|
Currently, the software recognises only channels zero, one, two and three. The following are the commands and their numerical value. To build command bytes add the command value to the channel number.
|00||0||Yes||Reset the controller. All outputs off, all servos disabled and all servos position and offset values are set to 128 (midrange). The data byte following this command MUST be zero. To ensure that a reset command it actually executed, send three consecutive zero bytes.|
|10||16||Yes||Set the servo output 'Position' value for the servo specified in the channel nibble. The data byte contains the new position value between 0 and 255.|
|20||32||Yes||Set the servo output 'Offset' value for the servo specified in the channel nibble. The data byte contains the new offset value between 0 and 255.|
|30||48||No||Enable Servo Output. Start generating the servo control pulse for the servo specified in the channel nibble.|
|40||64||No||Disable Servo Output. Stop generating the servo control pulse for the servo specified in the channel nibble.|
|50||80||No||Set Digital Output On (High). Set the digital output specified in the channel nibble high (5 volts).|
|60||96||No||Set Digital Output Off (Low). Set the digital output specified in the channel nibble low (0 volts).|
Special consideration needs to be given to the reset command as the state of the command parser in the PIC is not known when it is issued we actually need to be a little tricky. The parser could be waiting for a command in which case it would work, or it could be waiting for a data byte in which case it would get a little confused.
Therefore we will make the reset command a series of three zeros and have the parser on the PIC detect that there is an extra byte and ignore it.
When the servo controller receives a reset command it will turn everything off, set all the servos position and offset values to midrange and send the string "Reset" to the serial port with a 'carriage return' and a 'new line' character appended.
Example CommandsEnable Servo 0: 48 + 0 = 48 (ASCII '0')
Enable Servo 2: 48 + 2 = 50 (ASCII '2')
Disable Servo 0: 64 + 0 = 64 (ASCII '@')
Disable Servo 2: 64 + 2 = 66 (ASCII 'B')
Set Servo 1 Position to 180: 16 + 1 = 17 then 180
|Resistors (Metal Film 1% or 5%, 0.25 W)|
|C1, C2, C3, C4, C5||10uF 25 Volt Electrolytic|
|C6||47uF 25 Volt Electrolytic|
|C7, C8||22pF Ceramic|
|C9, C10||0.1uF MKT Polyester|
|U2||7805 voltage regulator|
|U3||PIC16F84 programmed with SERVOCTL.HEX|
|D2||5mm Red LED|
|Y1||4 MHz Crystal|
|8||3 pin PCB Header Pins. Buy a longer length and bread them up.|
|1||16 Pin IC Socket|
|1||18 Pin IC Socket|
|1||DB9 90 degree female connector|
|1||2.5mm PCB Mount DC Power socket|
|3mm bolts, nuts and PCB standoffs for mounting|
Contacting The Author
Contact Me on firstname.lastname@example.org for more information.
I'm interested in your feedback and I'll try to answer as many questions as I can, but I can't really offer construction advise or help fixing your project if it doesn't work, sorry.
I'm interesting in hearing about the applications you may find for this project, and any changes you may make to the PIC code. If you change the PIC code or write a driver program that you would like to share I'd be happy to place it here (and, of course, credit you).