Microcontrollers can be busy little beasts. That’s because we load them down with jobs to do – sometimes too many jobs.
In the main loop of an Arduino, AVR or whatever microcontroller takes your fancy, we often spend time polling sensors and then throwing away the data as uninteresting. On the robots I’ve built in the past, for example, that polling will include firing infra-red or ultrasonic rangefingers, waiting a moment for the readings to come back and then deciding whether the figures are significant. Much of the the time, they’re not.
In fact, I found I was mostly using infrared rangefinders as little more than glorified proximity sensors. Is the distance to the nearest surface less than a specified number? If not, who cares?
In those cases, I could have switched to actual proximity sensors that offer a digital yes/no signal. But it would be useful in some cases to get actual figures. Is there a surface too close? Yes. Well how close? Or one might want several thresholds.
And it might also be useful for a controlling computer to be able to get the proximity sensor to change the distance at which it triggers from time to time, without that being hard-coded.
This has led me to the idea of ‘smart’ sensors. Well, that and money. I was looking at the cost of ultrasonic rangefinders and found that the ones with I2C interfaces are significantly more than the basic sensors. That’s because they have microcontrollers on board. Well, if I add the microcontroller myself I might be able to do it cheaper – and even if not. it would provide the opportunity to add custom code to do clever things.
Let’s take the example of a rangefinder (infrared or ultrasonic, take your pick) which we want to use as part of the obstacle avoidance system of a motion control node.
The sensor’s microcontroller manages the sensor itself but also connects upstream to the motion control node via I2C or SPI (I’m going to assume I2C for now to keep the wire count as low as possible) and also via another connection that we’ll call the alert line.
The sensor controller is programmed to constantly make readings and store the latest one. If the motion control node decides it wants to know the distance to the nearest surface, it queries the sensor controller and is immediately given the last stored number without having to wait around for the whole fire-wait-read cycle.
When a distance falls below a certain threshold, the sensor controller takes the alert line low. This triggers an interrupt on the motion control node. Maybe the latter simply reacts to this warning. Maybe it queries the sensor controller for more information. That’s an algorithmic matter. The point is, the motion control node microcontroller doesn’t do any polling in its loop – it reacts only to interrupts. Much more responsive.
The other option might go something like this. The robot is moving slowly, so it instructs the sensor controller to change the trigger threshold to something small (ie, closer). When the robot speeds up, it changes again to a larger number, to provide reaction time.
If you build it…
So that’s the basic idea. Now all I have to do is build them and see if the idea works. In a future post (coming soon) I’ll be laying some of the groundwork.
I’ve settled (for now) on the AVR ATTINY88A as the microcontroller. It’s small and, better yet, cheap. But it has enough GPIO to provide plenty of options – maybe even controlling more than one sensor. It has no proper serial UART, but the Universal Serial Interface (USI) offers slightly cut-down yet still perfectly functional I2C and SPI options for communicating with the next microcontroller up the chain. There’s a good choice of pins for 10-bit or 8-bit analogue input. And did I mention it’s cheap?