Yesterday’s post described how to estimate the battery life of a JeeNode running the “rooms” sketch with the SHT11, ELV PIR, and LDR sensors. To summarize:
- the code started out using 370 µA average current, i.e. roughly 7 months on 3 AA cells
- of these, 200 µA were caused by the 1-second periodic wakeup “blip”
- another 120 µA were due to the actual measurements and packets sent every 30 seconds
- and finally, the remaining 50 µA come from the PIR + JeeNode current draw in sleep mode
Yesterday’s post was also about reducing that 200 µA blip consumption to somewhere around 20 µA.
Today, let’s tackle the other power “hog”: the 300 ms @ 12 mA spike. Here is that pattern again:
The high peak at the end is the RF transmission of a packet, followed by a “knee” during which the node is waiting for the ack packet in RF receive mode.
Note that the main power drain is NOT caused by wireless communication!
This period of over 300 milliseconds is when the ATmega is polling the SHT11, waiting for a fresh reading. Twice in fact: once for the temperature and once for the humidity measurement.
So the explanation is very simple: we’re polling and waiting in full-power mode. Quelle horreur!
The fix requires a small modification to the SHT11 driver in the Ports library. Instead of a fixed delay, it needs to be extended to allow using an arbitrary function to waste some time. Here’s the modified code:
A new second arg has been added, specifying an optional function to call instead of delay(). The code remains backward compatible, because this argument defaults to zero in Ports.h:
So now all we need to do is define a delay function which goes into real power down mode for a little while:
… and then adjust the two measurement calls to use this function:
Does all this make a difference? You betcha:
That’s a substantial fraction of a second in which the ATmega will draw considerably less than 12 mA. How much less? Let’s expand the vertical scale:
Most of the time, the voltage is around 50 mV, i.e. 1 mA over 47 Ω. That’s the SHT11 current draw while active. There are two measurements – so everything behaves exactly as expected!
A couple of quick wake-ups remain, to check whether the SH11 measurement is ready. And so does the wireless TX/RX peak, of course. Here is an isolated snapshot of that RF activity (200 mV/div and 4 ms/div):
Approximate current draw: TX = 35 mA, RX = 20 mA. Total time is about 10 ms.
Looks like we’ve reduced the power consumption of this once-per-30-second spike by perhaps 90%. As a result, the node now consumes about 20 (blip) + 20 (spike) + 50 (sleep) = 90 µA on average. Even with much smaller 800 mAh AAA cells, the battery life of these low-power nodes should now be over a year.
There are several conclusions to take home from this story, IMO:
- The biggest drain determines battery lifetimes.
- Measuring actual current profiles always beats guessing.
- A simple USB storage scope is plenty to perform such measurements.
If I had followed my hunches, I’d no doubt have spent all my time on getting the current draw of packet transmissions down – but as these experiments show, their effect on power drain is minimal.
There are more optimizations one could explore. There always are. But the gains will be limited, given that the ELV PIR sensor consumes 30..40 µA, and that it needs to be on at all times anyway, to be able to detect motion.
Sooo… end of story – for now :)
All source changes checked in. The entire rooms sketch still compiles to under 8 Kb of code.