The new functionality in my servo control takes more memory to implement due to the more complex state that we need to maintain for each servo. The simple controller could support up to 64 PWM channels on the ATTiny2313, the more advanced controller can, at the present stage of the design, support around 15. There’s scope to optimise the storage of the expanded 2 byte pulse duration values; they’re 12 bit values and so will fit in 1.5 bytes, but even that will only save me 5.5 bytes. The increased complexity of the serial commands also requires more buffer space to hold the complete command before processing. All of these pressures on the limited memory space of the ATTiny2313 lead me to believe that I need a device with more memory to implement the 18 channel servo controller which is my minimum requirement for the hexapod robot.
I had thought that it would be a relatively painless move to move from the ATTiny2313 to the ATMega168; the 168 has ample memory and its instruction set possesses a multiplication instruction which, in itself, would save us 5 bytes of stack space if we can remove our own implementation. However apart from the issue of needing to adjust the code to run on the 168 (the concept of ’extended I/O registers’ means that we can’t use out and in for some operations and need to use more complex instructions, and the increased memory size has shown up some issues in how I was looping over ranges of memory (when looping a pointer, such as X, it seems easier to loop until X is something (testing XH and XL) rather than looping and decrementing a counter register (which is fine as long as the loop size fits in a single register))), the main pain, seems to be the fact that although the ATMega168 has more I/O pins than the ATTiny2313 the arrangement of them is less ideal for my design.
The ATTiny2313 has 3 output ports; A, B and D. A has 3 pins, D has 7 and B 8. Some of these pins are needed for the external clock and UART RX/TX lines but the whole 8 pins of port B are available to us and we make use of them to control the 8 channels of PWM that we generate at a time. It’s nice an easy as we have a single out instruction on port B that can control any of the pins that we’re using to generate PWM in one go.
The ATMega168 also has 3 output ports, B, C and D. B and D have 8 pins and C has 7 pins. Overall an increase of 5 pins but, unfortunately for us the location of the externally required pins has changed such that PB6 ad PB7 are required for the external clock, PC6 is required for external reset and PD0 and PD1 are needed for the UART’s RX and TX lines. This means that we don’t have a whole 8 pins on a single port for use with our PWM generation so the generation code will need to become more complex. I’ll need to use some pins on port B and some on port C, probably 4 on each so that the bit twiddling that needs to be done to separate the control data into two bytes for the two out instructions is relatively simple.
An alternative approach might be to use ATTiny2313’s without the CD74HCT238Es and simply generate 8 channels per controller and chain multiple controllers together via a common control bus. Unfortunately, due to the fact that the communication between servo controllers and the controlling computer is bi-directional (the controllers echo commands and respond asynchronously to the completion of incremental moves) the serial channel that we’re currently using isn’t really going to work. Whilst we could chain multiple controllers on a serial line if the communications is purely from computer to controller (by having controllers ignore commands that weren’t for them) we can’t do that when the controllers can talk back. It may be possible to use something like I2C or to use the USI in either 2 or 3 wire mode; however, it looks like the pins required for doing this also clash with port B and so would require the redesign that we’d be doing if we simply switched to the ATMega168 and continued to use the UART.
For now I think I’ll move the code towards the ATMega168 and then, perhaps, back port an 8 channel version to the ATTiny2313.