SERVOS AND PICS Dear EPE, There have been several queries recently in [i]Readout[r] regarding PICs and R/C servos. Last year I built my first PIC project. It used a 20MHz PIC16F877 to simultaneously control eight R/C servos as well as sensing four pushbutton switches. It is probably worth sharing the knowledge that I obtained in doing this project, and the assembler code routines that drive the servos. The key points to understand when driving servos are as follows: Each servo needs to be refreshed with a pulse about 50 times a second, so the main loop in the program must not take longer 20 milliseconds. The pulse has to be of a precise length between 1ms and 2ms that defines the servo position (typically 1ms gives one end of the servo movement range and 2ms the other end). A simple delay loop can be used to time the pulse duration between switching the pulse on and switching it off (by setting the relevant Port bit on and then off after the delay). If you send at worst case a 2ms pulse to each of eight servos one after each other this takes 16ms, so you have 4ms (or 20,000 machine instructions) left to do anything else you want, such as in my case sensing the switches. If you send a shorter pulse than 2ms, you should wait for the remainder of the time so that the overall loop speed stays constant. If you want to move the servos in a defined sequence you need a list of positions for each servo, so I had eight tables with up to 20 items in each. In my code there is a routine that converts the one byte servo position field into the relevant length pulse. With a one byte field we get 256 possible servo positions, or better than one degree of positioning accuracy. To adjust the speed of movement of the servos you need to control how many times you use a value before you move onto the next one from the relevant table (with each time taking one fiftieth of a second). In my case this is variable using the speed-up and slow-down switches. This, however, can give a somewhat jerky movement on the servos as it jumps from one position in the tables to the next. If you want smooth movement you need to interpolate between the values in the table, which is what the interpolate routine in the program does. The servo lists were set up dynamically, rather than as initial constants, and this allows them to be changed at will while the program is running in response to the switch inputs, i.e. to switch to a different servo sequence. On a wiring-up note, servos have three wires, positive, ground and a control signal feed. I used a separate supply (four rechargeable batteries) for the power feed to the servo for the positive and ground connections, and another for the PIC supply (a PP9 battery with a 5V regulator), so that the heavy load and any electrical spikes from the servos did not affect the PIC. The control signal only needs a small current and can be driven directly from the PIC output ports, the eight Port B outputs in my case. Finally, if you are sensing push-switches you need to debounce them. A good way is to check on two consecutive times round the main loop that the value is still the same as it was last time. In my case the servos controlled the hip and knee joints on a 4-legged walking robot that made it to the heats of [i]Techno Games[r], but there will be lots of other applications where sequencing or animatronics need a similar bit of functionality. The code was developed using the FED PIC assembler and was run initially on a FED development board, but should be easily made to work with other development tools. I don't claim the code to be optimised or perfect, after all it was my first PIC project, but it works just fine, and might just save readers a few months working out how to drive those servos. I am happy for you to put the code on your web site. It is supplied as assembler file [bo]robotleg1_MPL.asm[r]. David Hannaford, Henley-in-Arden, via email That looks very useful, David. I'll put your code in the PIC Tricks folder on our Downloads page. Many thanks for sharing it with us. And congratulations on attempting something so sophisticated for your first PIC project. I have long maintained that one of the best ways to learn something is to get stuck into an idea that you want to achieve, and solve each step along that route as a separate item, experimenting with various options until you find a workable solution. At the end of the day, it doesn't matter whether your code is "optimised" or not. If it does the job you want, then it's a satisfactory method!