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.
Some of the new commands that I have planned for the servo controller will require that I load and save persistent settings from the ATMega’s eeprom. Having spent a little time looking at the example code in the datasheets it seems that you have to disable interrupts to safely read and write the eeprom. It’s not a problem to have interrupts disabled whilst I read the settings when the processor boots up but allowing new values to be written back to the eeprom as the result of a serial command will be problematic given the interrupt driven nature of our PWM pulse train.
This seems to require that we can stop the PWM generation completely and only allow the eeprom update commands to be executed when the controller is in ‘stopped’ mode. This isn’t too much of a problem as I envisage that these settings would be configured infrequently and doing so with the controller in a ‘paused’ state is OK.
A last minute addition to the currently available code was to add a servo controller information query command, send an [0x00] to the controller and it will return a four byte response [0x00] [versionMajor] [versionMinor] [numServos]. The current software returns 0x00 0x06 0x00 0x40 which is v6.0 supporting 64 servos. As I add new functionality any control software that uses the controller can determine if the new functionality is supported by the controller by querying the version.
Two additional commands, for safe eeprom programming are [0x01] to enable PWM generation and [0x02] to disable it. Commands that write to the eeprom can only be executed when PWM generation is disabled.
The easiest new commands that use the eeprom data store are to set the minimum and maximum position for a servo. Asking to move a servo beyond its minimum or maximum positions can either result in an error and no movement or movement that is curtailed by the limit that is exceeded. I expect whether it’s an error or whether the movement is constrained should be a controller configuration property; I don’t want to have to download new firmware to change the behaviour and I don’t yet know which behaviour is most appropriate… We already have a limit on the maximum servo position, set to 0xFE, so we simply need to check the maximum against our new, configurable value and add a check for a minimum. This expands the size of the ‘per servo data’ and we can load the values from eeprom when we boot and save them on demand. I expect it will be best to have one set of commands to query and set the min and max values for each servo and a separate command to write all updated values back to eeprom.