You wire it all up. You plug it in. You turn it on… and nothing happens.
Most of the time in this project was spent scratching my head and swearing at it. Most of that time was spent debugging software. So here’s my tips on debugging Picaxe code and complicated projects like this:
1) Put an LED directly on the microcontroller. Flick the LED from within the program, so you can tell if the code is running at all. Bonus points for connecting the LED to the power supply, not ground, coz the Picaxe outpin pins all drop to ground then a download starts. This gives you a clear indication of whether the download is starting.
2) Switchable behaviour within programs is most handy for turning on debugging from within the code. The Picaxe complier supports conditional directives but I found myself using a debug_flag variable, for idioms like:
if debug_flag=0 then // No debugging elseif debug_flag=1 then sertxd ("OMG ponies!\t", #num_ponies, cr, lf) elseif debug_flag=2 then sertxd ("OMG flying ponies!\t", #num_ponies, "\t", #altitude, cr, lf) endif
3) If your code isn’t too long, use the debugging switch to test subroutines, use cases, and so on.
4) The debug command is a pain in the arse. Use sertxd instead, to send you just the data you need in, along with labels indicating where you’ve got to in the program.
5) Code and circuit simulation are all well and good and should be used, but they’re not much help when your circuit includes other logic devices. My VSM can’t simulate the LED drivers, for instance.
6) Main cause of bugs for me – Variables reused. Subroutine A uses the variable loop_counter, hopes that nothing else will change loop_counter, and calls sub B. Sub B needs a counter and reuses uses loop_counter, resulting in everything turning to custard very quickly. The correct solution is scoping (and maybe namespaces) but Picaxe BASIC doesn’t scope. The next solution is a vast number of variables. The 40X1 has 28 bytes for variables. The solution I ended up with was to shuffle as much of the runtime data off into the scratchpad to free up the variables so that they could be used as named pretend local variables, with names like A_loop_counter and B_loop_counter.
7) Pointers are evil. However, they do let you use one byte of variable space to refer to the 128 bytes of scratchpad space and let you make pseudo-arrays in the scratchpad. This can go horribly wrong and stab you in the face but I expect that. I used to be a C programmer.
Looking back, the main causes of failure have been:
1) Not having regulated power to the microcontroller. Always do this. Otherwise, turning lots of LEDs on in the same millisecond can drop the supply voltage enough to crash your microcontroller.
2) Wiring coming loose. IDC connectors are passable, but any other kind of connection? Ugh. Soldered joints might be covered in heatshrink, but they still fatigue and snap. Soldered joints covered in heatshrink and hot melt glue still fatigue and snap. Bolt everything up good and tight and don’t take any mechanical loading through the solder.
Here’s how I made the joints between the five circuit boards:
3) Dry solder joints. If bending the board causes crashes, or makes it start working, then it’s probably a dry joint.
4) Batteries dying. Don’t put NiMH battery packs in parallel. Just no. They end up fighting each other, both on charge and on discharge, until one cell just craps out. If, for instance, you’ve the perfect space for two packs of four cells to give you five Volts, maybe you’re trying to fit AAA cells into a one-inch tube like me, resist the temptation to put those packs in parallel. Suck it up, put them in series and live with having the wrong voltage. What’s one more DC-DC converter anyway?