L'Hexapod: Tweaking the servo controller

Previously published

This article was previously published on lhexapod.com as part of my journey of discovery into robotics and embedded assembly programming. A full index of these articles can be found here.

The 64 channel serial servo controller that I’ve been developing works pretty well for me but most of my development and testing was done in the AVR studio simulator. Once I actually started working with my hardware again I noticed a slight problem. Although my servo controller was operating to spec my spec was wrong.

The problem is that the data sheet I have for the Hitec HS-422 servo states that it requires a pulse length of between 900us and 2.1ms with a centre position of 1.5ms. That’s correct but it only gives a range of just over 90 degrees. The Pololu servo controller board that I’ve been using for my prototype work can send pulses of between 275us and 2.75ms which gives more range than I need but I’ve been using the servos with a range of 180 degrees with it. Further investigation showed that the HS-422 actually requires 600us to 2.4ms for 180 degrees.

Luckily the pulse generation code is pretty easy to adjust for this kind of range. Whilst we’d never be able to get the 275us to 2.75ms range that the Pololu controller manages due to the 64 channel (2.5ms cycle length) design, we can achieve a range of 611-2389 just by changing the multiplier we use from 6 to 7. Of course this also requires a change to the equate that provides our 1.5ms pulse for a control value of 127. The value changes from 738 to 611 for an 8.0MHz clock and from 620 to 493 for the 7.3728MHz clock that we’re using.

If we were to switch to allowing the serial interface to program the pulse lengths directly as two byte values we could extend the range slightly (as long as we never go beyond 2.5ms at the top end or below the maximum time it takes to perform the PWM setup code at the bottom end), I may do this later, but for now the slightly reduced range is OK for me.

The other thing that could be improved is that the servos are spread across all of the MUX chips in such a manner that servo 1 is on pin 0 of MUX1, servo 2 is on pin 0 of MUX2, etc. This makes it difficult to wire up a board so that the servo connections are sequential on the jumper blocks and it makes it hard to use the controller with fewer than 8 MUX chips.

A simple change to the PWM setup code can copy the data from the serial configuration buffer to the PWM generation buffer in such a way that the servos are numbered sequentially from MUX1 pin 0 to MUX8 pin 7. This means that servo 0 appears on MUX1 pin 0, servo 2 on MUX1 pin 1, etc. This means that supporting fewer channels can be achieved simply by reducing the number of MUX chips that you add to the circuit.

Source code is here.