Embedded PWM Driver

For one of my robotics projects I needed to turn an antenna from side-to-side.  So I pulled out my servos, breadboard, 555 timer, assorted gates, resistors, caps, and other crap to start putting together a driver.  I've probably did this dozens of times over the years.  As I was looking through the bins of assorted electronics stuff I found my box of uContollers.  At that point the 'duh' light goes on.

Pulse Width Modulation (PWM) is a form of signal modulation where the widths or pulses correspond to specific data values.  For servos, the different pulse widths would correspond to different positions of the servo.  The picture below (right) shows the pulse train going to the servo.  The period (1/freq)  is about 3mS or a 333Hz pulse train.  This frequency will vary depending on the servos you are using but most are in the hundreds of Hz to lower Khz range.  There is usually a dead-band at both extremes, maybe less than 5% and greater than 95%.  Here no change will happen.  If a PWM signal with a 50% duty cycle were sent the servo would go to its 180 degree position. A 5% duty cycle may send it to 20 degrees and 95% to 340 degree.  The ratios and actual positions depends on the servos.

The coding of the uController is pretty straight forward.  Basically you need to create a real time delay using the uController on-board crystal or timer.  I set mine up for 1uSec increments.  The rest is just shifting in 1s or 0s into the register which cooresponds to the desired output pin.  The Atmel MEGA-1284P demo board I used just happens to have an LED wired to the same output register.  Code snippet below.

I will note you need to be careful how you write the code.  Remember, the servo will go to and stop at a position but you need to continuously send the PWM signal.  If the pulse train stops like when a delay or interrupt is sent the servo will slip back if torqued.  One of the simple ways to code is just to know the position-to-position travel time and add the extra time needed in the loop.  The snippet below drives the servo to a position and allows for it to stay in that position for 1sec.

Why not just use a uController?!?!  After all, these are the kinds of applications they were designed for.  Years of conditioning makes you want to grab wire and a breadboard but here we have a programmable solution all in one chip.
To begin with, a servo (or servomotor) is an error-sensing, error-correcting motor.  They're a digital / analog hybrid containing a motor and either a potentiometer for position sensing or an encoder which provides both speed and positioning using proportional integral derivative (PID).  Most servos have a less than 360 degree rotation (but not always) and are driven using pulse width modulation (PWM).     

Embebbed PWM Driver

PWM Generator - Source Code

A lot easier than the breadboard route.