The simple servo sequencer that I’ve been working on has exposed a bug in the servo controller firmware. The bug is due to stack corruption during movement completion notifications, so it only happens if you use the ‘multi-move’ commands or the delay move command. The problem is that at the end of SerialSendMoveCompletionNotification we jump back to the serial data accumulation loop rather than using a ret to return… Since we enter SerialSendMoveCompletionNotification via a call rather than a jump we are failing to balance the stack and so eating two bytes each time we call the function.
Whilst playing around with my servo controller I realised that the power used by a servo goes up considerably when it’s under heavy load (such as when it’s pressing against the table and still trying to move). I can, potentially, get an idea of this load by measuring the current that each servo is using and using this feedback somehow. I’ve yet to work out how, but at the very least it could be used to protect the servos against overloading; if the load gets above a certain threshold then stop moving!
This is the AVR Studio project and assembly language source code files for the latest version (v7.0) of my 64 channel serial servo controller.
This is the latest version of the ATMega168 version of the code which includes all of the new servo commands that I wrote about here including the multi-move command and the unit tests that I spoke of here. The controller allows you to set minimum, maximum and startup servo positions for each servo which can be saved into eeprom and used every time the controller is powered up.
The latest version of the serial servo controller is now fully operational (I’ll upload the source code shortly). There are still some bugs that I’m finding but the work I put in to getting the unit tests in place makes fixing these bugs pretty straight forward. Whilst I have pretty much 100% coverage for the simpler serial commands I’ve stopped writing tests for the ‘multi-move’ command now and I’ve switched to “Just in time” testing; that is I write a test in response to finding a bug.
It’s taken me almost a month but I’m finally back to working on integrating the multiple servo move command into the rest of the code. Well, the integration was done long ago, unfortunately the debugging was the bit that was taking up my time.
I decided that putting ‘printf’ style debug output into the routine to attempt to debug it from my PC based control software was just the wrong way to go about finding the problems and so I set off on a mission to finally get some unit testing into my code.
The test code for the serial command processing code for my serial servo controller is turning out to be the largest piece of assembly language that I’ve written. This means that all of a sudden I’m coming across “Relative branch out of reach” errors during the compile. I’ve got to a point where every time I add a test I have shuffled the code to such an extent that several relative branches need adjusting from rjmp to jmp or rcall to call.
I’m in the process of integrating the stand alone code that implements my ‘multi-servo move’ command and the rest of the controller. It’s harder than it should be, probably because I’m not experienced enough yet with assembly language not to have made some school boy errors. Once again I’ve run out of registers, mainly because I’m trying not to have to push stuff on the stack that often. I’ve been juggling with the limited number of registers and up until now it’s worked but…
The work on turning my excel spreadsheet into AVR assembler code which can move multiple servos to arrive at their target locations at the same time is proceeding well. I have the required code operating in a stand alone environment in the simulator and all I need to do now is merge that in with the rest of the code… Once that’s done my servo controller is complete and whilst I already know that there are at least two further versions in the pipeline I expect I’ll move onto something more before working on them.
The final command for my serial servo controller is the most complex. The idea behind it is that with a hexapod leg you will want to be able to move the leg to a new position where the new position requires all three of the servos that manage the leg to move to potentially new locations. Ideally you want the “foot” to arrive at the final resting place in such a way that all of the servos complete their moves at the same time.
Work on the latest version of the serial servo controller is going well. I’d accumulated a pile of random nice to have ideas, some of which then necessitated some other ideas, and then there was the one must have command (the one which moves several servos to new positions over time and ensures that they all arrive at their final resting places at the same time). Of course I’ve worked on some of the nice to haves rather than dealing with the final ‘must have’ command that I need before I can move on to writing some gait controlling software to move multiple legs in sequence…