The Mitochondrion M4.2.3 code was a bit of a mess. It wasn’t bad, but it wasn’t great either that it was put together in a bit of a hurry for last summer’s festivals. And then I tweaked it further over the summer while running out of program memory (Arduino Nano/ATmega328 so only 32 kb). And then I left it alone for a month or so, to get sufficient distance from that code base before thinking about what it could be. The vast majority of the code sat in one big library file, the control logic say in one big function, and inter-object dependencies were bloody everywhere, to the point where I didn’t want to mess with any part of it.
Clearly the solution was to mess with all of it. So it was major refactor time, starting with a clean sheet of paper, then scribbling all over it to come up with a design that was pretty close to the existing approach but without all the knobbles. And then coding and testing and more coding.
The Mark 4.2.4 now has co-operative multitasking with flexible time-based scheduling; one task object per sensor, output, or pattern generator; a message queue for asynch inter-object comms; and a nice and tidy state/event table for controlling switching between different modes and smoothly handling those transitions. Objects have much more responsibility to handle their own transitions and modes, leading to fewer cross-object tangles and asynchronous behaviour where a mode change sends a message to every object, those objects can finish doing what they are doing before changing modes and reporting those changes back.
This may be overkill and right now, the external behaviour doesn’t look any different. This is mostly all preparation, because I’d like to be writing some code that enables more complex behaviour and can be reused for the Mark 5, where I plan on having the computational grunt to implement that behaviour. And it’s just so much less stressful to be working on code that’s been around the “try, learn, try again” cycle a few times.
Oh, and a whole bunch of tidying up, both structural and idiomatic. For instance, the Arduino approach to libraries makes it annoyingly hard to do something as basic and tidy as one class per file (NoMi has an advanced tip on using the #include “Library/utility/class.h” trick). I want all my constants defined in one place, but I also want to be able to pretty print enum values. Cue x-macros and feeling displeased that such hoop-jumping is necessary.
After a month of so of sorting the software out, it all seemed to be behaving itself, both on the bare Nano dev board and on the metre-and-a-half real thing. Tweaks to the motion-sensing code required me to wave it around substantially, so I unplugged the USB cable and everything turned to shit.
Bother, or words to that effect.
Plug USB cable back in to get debugging info, it works. Gargh!
Unplug cable, status LED on the Arduino flashes rapidly enough to just look dim, implying that it’s starting but then crashing almost immediately. Ok, USB cable supplies data but also a nice steady five Volts to power the Arduino. Unplugging that switches to the internal little converter that’s supposed to turn 24 Volts of battery power into 5 Volts using a MAX5033 step-down. Looking at the output from that shows:
So it’s starting up, getting to 3ish Volts, then dying. At which point, a year ago, I’d have tried to work out what was wrong in the circuit I’d built around the MAX5033. However, I’ve now been around the “try, learn, try again” loop enough times to realise that a) this could be a huge time sink and b) I’m crap at circuit design. Instead, I just bought the smallest DC-DC converter in a box that I could and then I bodged it in (a Recom half-Watt switch-mode replacement for a three-pin voltage reg). The MAX5033 has an on/off pin, shorting that to ground with a blob of solder turns it off without ripping components off the board.
The three pin converter just connects to battery +ve, ground, and +5 Volts output. Here’s it in place, before fixing and reinforcing with hot melt glue.
It’ll make the standby life even worse, but WTH, it cost $15, ten minutes to plan out, about an hour to install, and it works. For now, at least.