Now that we have the Rotator board, we have another Arduino microcontroller. This is slaved from the main Arduino which normally drives it, so there is no direct path from my development PC to the device which will make programming it a little difficult. we can't even go direct to it since its physically in the Chicken coop too.
So, how are we going to program it if we need to do a firmware update ?
Having already solved the problem of how to to remotely program an main Arduino, ideas circulate around a second serial port on another USB interface from the Pi, but then how will we swap from the "normal" Arduino to Arduino link to a Raspberry Pi to Arduino link when we need to ? We think again of the unstable SPI connection that would allow this to be trivially resolved, except for the fact that if we can't get a 30cm data path working reliably, then our hopes on a 3 meter path are far less likely.
The answer comes, like many others after having rested ones eyelids. Given that you an only get into the Arduino bootloader just after the device has been reset, then if we can do the reset at the correct time and connect through the RS232 connection between the main Arduino to the slave Arduino, then AVRDUDE should be able to see the remote device and program it successfully, we'll call this pass-through mode. Once pass-through mode has been enabled, it will just pass the information sent by one device to the other. The only way out of this mode is to reset the main device, which is a normal activity at the end of programming anyhow. Additionally, the main device as part of its normal setup resets all its slaves too, hence everything will come back on-line nicely.
So, we go about uplifting the remote Arduino programming functionality so that it can talk to either Arduino. Given that there may at some point in the future be other slave Arduino's, it makes sense to pass a code to the pass-through software to say which Arduino we want to talk to, this allows the main unit to know which serial port to use and which reset line to wiggle at the right time.
To permit debugging, the firmware on both Arduino's is uplifted so that any status messages from the slave unit can be displayed on the master device. The master will only filter the message it understands, and in that code, we can then provide higher level status messages if we want to.
Now we have an integrated way to handle programming and debugging of remote devices in a uniform manner, which is looking good.
The only other minor issues we discover are that as we are running the main Arduino at 115200 baud (between the Raspberry Pi and the main Arduino), but the bootloader code runs at 57600 baud. Given that neither device has any mechanism for serial hardware flow control, then there is no way to buffer information between the two, hence the logical thing to do is to change the serial speed on the master Arduino to match the slave at the point that we go into pass-through mode, that way, no buffering ever needs to occur.
We also hit the problem of when to actually reset the slave Arduino. If we go too early, then the device will have exited the bootloader by the time AVRDUDE starts talking to it and if we go too late, then it will have not initialised by the time that AVRDUDE wants to talk to it, so the best way is to hit the reset pin as we receive the first bytes of serial data, this is tested and works fine.
There is one exception that we can't easily handle with this approach, this is if the slave Arduino looses its bootloader, in this case we will need a screwdriver to get to the device, remove it, re-program the bootloader in the (human) house and replace the device in its board. Under normal situations, this should never occur, but we may as well plan for when it does.
For more info on the scripts that makes the remote update work, take a look at the remote programming page.