This morning I tested the first version of my custom servo controller. It’s currently heavily based on the source for 16 channel servo controller that I’ve mentioned before. What I did was simply adjust that source for my target processor and the fact that I’m using it with a 4Mhz internal clock rather than the more standard “RS232 baud rate friendly” 3.6864 MHz that the original code used.
The main changes were to the reduce the controller from 16 channels to 8 since the ATtiny2313 doesn’t have enough pins to run 16 channels and to adjust the general setup to account for the new processor. The timing loops also changed a bit due to the clock change. Since I’m working from the other code as a base my code generates the PWM signals manually in the same way that it does. Although we have custom hardware inside the ATtiny2313 that can generate PWM signals for us the manual approach seems to work at the moment. Things may well change as I get a better understanding of what I’m doing.
I initially had some problems because although I’d set the code up for a 4Mhz internal clock and simulated with that I hadn’t changed the fuse bits on the processor so it was still running with the default 8Mhz internal oscillator with a divide by 8 to give a 1Mhz clock. The first hint that something was wrong with the timing was that I could see the test LED on one of the servo channels flashing rather than being solidly on; the frequency of the refresh of the pulse should be 50hz and that should look like the LED stays on rather than the flashing that I was getting at the 13hz or so that I was actually getting as a refresh. Once I calculated and set the new fuse bits (using this online calculator) the LED stabilised and plugging a servo in gave the expected results.
Since the servo controller uses the ‘standard’ three byte serial “SSC” protocol of 0xFF <servo> <position>, my existing control software works fine with it.
Right now the pulse frequency seems to be slightly off, which makes the servo vibrate in position a little. I’m not sure if this is down to my timing (which I expect it is) or if it’s because I really should be using a more stable external clock.
Once I’ve tested this a little more and have something that’s a little more stable I’ll upload the source. What I have now is a good base for the larger capacity controller that I’ll need. One of the next steps will be to reduce the number of I/O pins needed whilst increasing the number of channels supported by adding in the control of the address lines of some 74xxx138 multiplexors which can be wired into the I/O pins that I’m using for the actual PWM output. Another thing on the list is to enhance the serial protocol, and then the controller itself, to support the various ideas I have:
- Smooth blending between ‘key frame’ servo positions with the ability to stop the servo at any time before it reaches its final position.
- Storing of multiple ‘key frames’ per servo so that the leg controller/gait sequencer can hand off a sequence of moves to the servo controller to blend.
- Grouping of servos, so that we can have the blending apply across servos in the group (all 3 servos that make up a leg can arrive at their final ‘key frames’ at the same time).
Though the current servo controller design is very simplistic it seems to be a good base for these other requirements and, well, at least I now have AVR assembly code that I can build, simulate, program a device with and that actually seems to do what I expect it to do; that’s a major step forward.