(Whoops… this post got mis-scheduled – fixed now)
Yesterday’s post illustrates an approach I’ve recently discovered for using the RF12 driver in a very simple way. This works in one very clear-cut usage scenario: sending wireless packets out periodically (without ACK).
Here’s the basic idiom:
What this does is completely ignore any incoming data, it just waits for permission to send when it needs to, and then waits for the send to complete by specifying “2” as last arg to rf12_sendStart().
No tricky loops, no idle polling, everything in one place.
With a few lines of extra code, the RFM12B module can be kept off while not used – saving roughly 15 mA:
And with just a few more lines using the Sleepy class, you get a low-power version which uses microamps instead of milliamps of current 99% of the time:
Note the addition of the watchdog interrupt handler, which is required when calling Sleepy::loseSomeTime().
The loseSomeTime() call can only be used with time ranges of 16..65000 milliseconds, and is not as accurate as when running normally. It’s trivial to extend the time range, of course – let’s say you want to power down for 10 minutes:
Another point to keep in mind with sleep modes, is that it isn’t always easy to keep track of time and allow other interrupts to wake you up again. See this recent post for a discussion about this.
But for simple Wireless Sensor Network node scenarios, the above idioms will give you a very easy way to turn your sketches into low-power mode which can support months of operation on a single set of batteries.
Update – it looks like the above RF12_sleep() arguments are completely wrong. They should be:
- rf12_sleep(N) turns the radio off with a wakeup timer enabled if N is 1..127
- rf12_sleep(0) turns the radio off
- rf12_sleep(-1) turns the radio back on
This list matches what is documented on the wiki page.