I've spent some time writing smooth movement routines for the motors for the HullPixelBot. I want the motor movement to run in the background, so that the program can do other things as the robot moves. This will make the drive very like the behaviour that you get from a traditional "servo" motor that starts turning when the program switches it on.
Thing is, the stepper motors only turn if the program sends the appropriate set of signals to the coils in them. The solution to this problem is to use the timer on the Arduino processor. This can repeatedly trigger a bit of program code at regular intervals using a hardware technique called an interrupt.
Interrupts are used by a computer to respond to real world events. Tapping a touch sensitive screen, moving the mouse or pressing a key are all things that interrupt a running program and cause the computer to run a special piece of code called an interrupt handler which deals with the event. In the case of a key press, for example, the operating system (perhaps Windows 10) responds to the interrupt by sending a keyboard message to the currently active program.
In the case of the HullPixelBot I'm using a timer to produce a sequence of interrupts at regular events which are then used to trigger code which moves the stepper motors to their next position. The code required to do this is quite tiny, and so once the move has been completed the "normal" program can be resumed.
I don't reckon you can call yourself a programmer unless you've written an interrupt handler or two. I've done quite a few and they are rather fraught bits of code. You're not allowed to touch any of the things used by the "normal" program (in case you confuse it), and you must complete your action in the shortest possible time, otherwise you'll bring the computer to a halt. Programming ninjas can write code that uses multiple interrupts from different sources at the same time.
Which is what I want to do.
I want programs to be able to use the distance sensor and the motors, and for both of these devices to work using interrupts. Now, I think of myself as a bit of a programming ninja, so I knock out the code and fire it up. And it doesn't work.
I can have motors, or distance sensor, but not both.
I'm not surprised by this because it can be tricksy if interrupts occur during interrupt handlers. So I check the hardware manual for the processor and get myself into a state where I'm convinced it should work, but it doesn't. Hmm. Perhaps I'm not a ninja after all.
So it was back to the start, and a careful re-write of the code to make it as smooth as possible, and remove any ways in which the two handlers (one for the timer, one for the distance sensor) could interact. And it still didn't work. No fair.
Of course, I eventually figured it out (otherwise you would not be reading this blog post). It turns out that it had nothing to do with the interrupts. It was just that when the program turned the motors on it dropped the voltage level in the robot power supply to such a low level that the distance sensors stopped working. I was testing the code on a machine on my desktop and I'd left the motor power supply turned off so that the robot wouldn't try to run away. That lack of power was my undoing.
The good news is that I'm now pretty confident that the code I've written is solid, and the HullPixelBot can move in a very nice, precise way, measuring distance values as it goes. And I've learnt something about motor power and distance sensors, which is useful.
I'll be showing the code off at the hardware meetup on Thursday this week.