# Computing stuff tied to the physical world

## 3 years on one set of batteries

In AVR, Hardware on Sep 8, 2013 at 00:01

Ok, so maybe it’s getting a bit boring to report these results, but one of the JeeNodes I installed long ago has just reached a milestone:

That “buro JC” node has been running on a single battery charge for 3 years now:

And it’s not even close to empty: this is a JeeNode USB with a 1300 mAh LiPo battery tied to its back, and (as I just measured) it’s still running at 3.74 V, go figure.

Let’s do the math on what’s going on here:

• the battery is specified as 1300 mAh, i.e. 1300 mA for one hour and then it’s empty
• in this case, it has been running for some 1096 x 24 = 26,304 hours total
• so the average current consumption must have been under 1300 / 26304 = 50 µA
• well… in that case, the battery should be empty by now, but it isn’t
• in fact, I suspect that the average power consumption is more like 10..25 µA

Two things to note: 1) LiPo batteries pack a lot of energy, and 2) they have a really low self-discharge rate, so they are able to store that energy for a long time.

The other statistic worth working out, is the amount of energy consumed by a single packet transmission. Again, first assuming that the battery would be dead by now, and that the microcontroller and the rest of the circuit are not drawing any current:

• 1,479,643 packets have been sent out, i.e. ≈ 1300 / 1500000 = under 1 µAh per packet
• since 60 packets are sent out per hour: about 60 µAh per hour, i.e. 60 µA continuous
• energy can also be expressed in coulombs, i.e. 60 µC gets used per packet transmission (3,600 seconds to the hour, but there were 60 packets sent out during that period)
• so despite the fact that the RFM12B draws a substantial 25 mA of current during transmission, it does it so briefly that overall it’s still extremely low-power (a few ms every 1s, so that’s a truly minute duty cycle)

The conclusion here is: for these types of uses, with occasional brief wireless sensor data transmissions, the power consumption of the wireless module is not the main issue. It’s far more important to keep the idle (i.e. sleep mode) of the entire circuit under control.

The 2nd result is also a record, a JeeNode Micro, running over 6 months on a coin cell:

This one is running the newer radioBlip2 sketch, which also measures and reports the battery voltage before and after packet transmission. As you can see, the coin cell is struggling a bit, but its voltage level is still fine: it drops to 2.74 V right after sending out a packet (drawing 25 mA), and then recovers the rest of the time to a fairly high 2.94 V. This battery sure isn’t empty yet. Let’s see how many more months it can keep this up.

The 3rd result (penlight test), is this setup, based on the latest JNµ v3:

The timing values are way off though: it has also been running for over 6 months, but I accidentally caused it to reset when moving things around earlier this summer. This one is running with a switching boost regulator. The Eneloop battery started out at 1.3 V and has now dropped slightly to 1.28 V – it should be fine for quite some time, as these batteries tend to run down gradually to 1.2V before they start getting depleted. This is a rechargeable battery, but Eneloop is known to hold on to its charge for a surprisingly long time (losing 20% over 2 years due to self-discharge, if I remember correctly).

You can see the boost regulator doing its thing, as the output voltage sent to the ATtiny is the same 3.04 V as it was on startup. That’s the whole idea: it regulates to a fixed level, while sucking the battery dry along the way…

Note that all these nodes are not sensing anything. They’re just bleeping once a minute.

Anyway… so much for the progress report on a pretty long-running experiment :)

## A thousand days!

In AVR, Hardware on Jun 6, 2013 at 00:01

It’s getting a bit repetitive, but I just noticed this:

That’s over 1000 days of sending out one packet a minute on this thing:

… and over 100 days on the recent JeeNode Micro v3:

The battery boost version runs off a single Eneloop AA battery, and is doing fine too:

Onwards!

## Idling in low-power mode

In AVR, Software on May 28, 2013 at 00:01

With a real-time operating system, going into low-power mode is easy. Continuing the recent ChibiOS example, here is a powerUse.ino sketch which illustrates the mechanism:

```#include <ChibiOS_AVR.h>
#include <JeeLib.h>

const bool LOWPOWER = true; // set to true to enable low-power sleeping

// must be defined in case we're using the watchdog for low-power waiting
ISR(WDT_vect) { Sleepy::watchdogEvent(); }

while (true)
chThdSleepMilliseconds(1000);
}

void setup () {
rf12_initialize(1, RF12_868MHZ);
rf12_sleep(RF12_SLEEP);

}

NORMALPRIO + 2, (tfunc_t) Thread1, 0);

while (true)
loop();
}

void loop () {
if (LOWPOWER)
Sleepy::loseSomeTime(16); // minimum watchdog granularity is 16 ms
else
delay(16);
}
```

There’s a separate thread which runs at slightly higher priority than the main thread (NORMALPRIO + 2), but is idle most of the time, and there’s the main thread, which in this case takes the role of the idling thread.

When LOWPOWER is set to `false`, this sketch runs at full power all the time, drawing about 9 mA. With LOWPOWER set to `true`, the power consumption drops dramatically, with just an occasional short blip – as seen in this current-consumption scope capture:

Once every 16..17 ms, the watchdog wakes the ATmega out of its power-down mode, and a brief amount of activity takes place. As you can see, most of these “blips” take just 18 µs, with a few excursions to 24 and 30 µs. I’ve left the setup running for over 15 minutes with the scope background persistence turned on, and there are no other glitches – ever. Those 6 µs extensions are probably the milliseconds clock timer.

For real-world uses, the idea is that you put all your own code in threads, such as `Thread1()` above, and call `chThdSleepMilliseconds()` to wait and re-schedule as needed. There can be a number of these threads, each with their own timing. The lowest-priority thread (the main thread in the example above) then goes into a low-power sleep mode – briefly and repeatedly, thus “soaking” up all unused µC processor cycles in the most energy-efficient manner, yet able to re-activate pending threads quickly.

What I don’t quite understand yet in the above scope capture is the repetition frequency of these pulses. Many pulses are 17 µs apart, i.e. the time `Sleepy::loseSomeTime()` goes to sleep, but there are also more frequent pulses, spread only 4..9 ms apart at times. I can only guess that this has something to do with the ChibiOS scheduler. That’s the thing with an RTOS: reasoning about the repetitive behavior of such code becomes a lot trickier.

Still… not bad: just a little code on idle and we get low-power behaviour almost for free!

## 90 days on a coin cell

In Hardware on May 26, 2013 at 00:01

Just saw that my JeeNode Micro test setup has been running and “blipping” for 90 days:

The voltage is starting to drop a bit, and the voltage drop before and after using the radio has increased from 0.08 to 0.16 V (reported with a granularity of 0.02 V), but everything seems to be fine. It has pumped out over 120,000 packets so far.

The other test is a JeeNode Micro with boost regulator, running of one Eneloop AA battery. That battery voltage has also dropped a bit, but as you can see, the boost regulator is doing its thing and still providing the exact same 3.04 V as it did when the test was started.

It’ll be interesting to see how long each of these setups holds out. I have no idea, really. It’s not just a matter of capacity – with the coin cell, it’ll also depend on how long the battery can continue to provide these brief 20..20 mA power bursts for each transmission.

Onwards!

## Zero-power measurement – part 2

In Hardware on May 18, 2013 at 00:01

After a great suggestion by Max, on yesterday’s post, here’s a another circuit to try:

It adds a capacitor and a resistor, but it allows using a P-MOSFET and a divider ratio which can now use the entire ADC range, not just 1 V or so as in yesterday’s circuit. Note however that if VCC is not fixed to the same value under all conditions, then the ADC’s reference voltage can float, and use of the 1.1V bandgap may still be needed.

Here’s the voltage at the top of the divider, showing how it switches on and off:

That’s with the pull-up resistor value R set to 1 MΩ, which takes 208 ms to turn the MOSFET back off. We don’t need that long, a 10 kΩ resistor for R will do fine:

That still gives us 2 ms to measure the supply level. Note that turn-off is automatic. DIO needs to be turned high again, but that can happen later. In my test code, I left it low for 1s to, then high for 7s.

Here’s a neat set of superimposed measurements (using persistence), while varying the high voltage from 3.5 to 12.0 V in 0.5 V steps:

Warning: for 12V, the divider ratio must be changed so the centre tap stays under VCC.

Note that with higher voltages, the MOSFET will turn off sooner – this is because there is now more current flowing through the pull-up resistor. But still plenty of time left to measure: 1 ms is more than enough for an ADC.

Tomorrow, an example of how these measurements can sometimes go awry…

## Zero-power battery measurement

In Hardware on May 17, 2013 at 00:01

As promised, here’s a circuit which can be used to measure a voltage higher than VCC without drawing any current while not measuring:

Besides the fact that this needs an N-FET + I/O pin, there are several finicky details.

First of all, note that the following circuit will not drop the power consumption to zero:

The idea in itself is great: set DIO to logic “0” before performing a measurement, acting as GND level for the resistor divider (10 + 10 kΩ would be fine here). Then, to switch it off, set DIO to an input, so that the pin becomes high-impedance.

The problem is that the pin divider is still connected and that the AIO pin cannot float any higher than VCC + 0.6 (the drop over the internal ESD protection diode). The top resistor remains connected between PWR and VCC + 0.6, therefore it’s still leaking some current.

That also explains why the first circuit does better: the MOSFET disconnects all I/O pins from that PWR line, so that there is just a resistor from AIO to ground (which is harmless).

But there’s a catch: we need to be able to turn the N-channel MOSFET on and off, which means we need to be able to apply a voltage to its gate which is a few volts above the drain pin (the bottom one, attached to AIO). With a resistive divider of 10 + 10 kΩ on a 6V PWR line, that voltage will immediately rise to 3V, and there’s no way the DIO pin can keep the MOSFET on (it can only go up to logic “1”, i.e. 3.3V).

The solution is to use a different divider ratio: say 50 + 10 kΩ. Then, a 6V PWR level leads to a 1V level on the AIO pin, i.e. on the drain of the MOSFET. With DIO set to “1”, that means the MOSFETs gate will be 2.3V above the drain – enough to keep it turned on.

BTW, all this tinkering over the past few days has left me with a bunch a funky headers :)

Anyway, to summarise the zero-power battery monitor:

• to work with 6V PWR, use a 50 (or 47) kΩ top resistor and 10 kΩ for the bottom one
• use an N-channel MOSFET with low turn-on voltage (called a “logic level MOSFET”)
• to measure the voltage, set DIO to “1”
• measure the voltage on the AIO pin, where 0..1V will correspond to 0..6V on PWR
• to turn off the divider, set DIO to “0”

As you can see, this approach requires an active component to switch things and an extra I/O pin, but then you do end up with a circuit which can completely switch off.

For simple uses, I’d just use yesterday’s setup – sub-microamp is usually good enough!

## Measuring the battery without draining it

In Hardware on May 16, 2013 at 00:01

In yesterday’s post, a resistive voltage divider was used to measure the battery voltage – any voltage for that matter, as long as the divider resistor values are chosen properly.

With a 6V battery, a 10 + 10 kΩ divider draws 0.3 ma, i.e. 300 µA. Can we do better?

Sure: 100+100 kΩ draws 30 µA, 1+1 MΩ draws 3 µA, and 10+10 MΩ draws just 0.3 µA.

Unfortunately there are limits, preventing the use of really high resistor divider values.

The ATmega328 datasheet recommends that the output impedance of the circuit connected to the ADC input pin be 10 kΩ or less for good results. With higher values, there is less current available to charge the ADC’s sample-and-hold capacitor, meaning that it will take longer for the ADC to report a stable value (reading it out more than once may be needed). And then there’s the leakage current which every pin has – it’s specified in the datasheet as ± 1 µA max in or out of any I/O pin. This means that a 1+1 MΩ divider may not only take longer to read out, but also that the actual value read may not be accurate – no matter how long we wait or how often we repeat the measurement.

So let’s find out!

The divider I’m going to use is the same as yesterday, but with higher resistor values.

Let’s go all out and try 10 + 10 MΩ. I’ll use the following sketch, which reads out AIO1..4, and sends out a 4-byte packet with the top 8 bits of each ADC value every 8 seconds:

```#include <JeeLib.h>

void setup () {
rf12_initialize(22, RF12_868MHZ, 5);
DIDR0 = 0x0F; // disable the digital inputs on analog 0..3
}

void loop () {
for (byte i = 0; i < 4; ++i) {
}

delay(8000);
}
```

This means that a reported value N corresponds to N / 255 * 3.3V.

With 5V as supply, this is what comes out:

``````L 10:18:14.311 usb-A40117UK OK 22 193 220 206 196
L 10:18:22.675 usb-A40117UK OK 22 193 189 186 187
L 10:18:31.026 usb-A40117UK OK 22 193 141 149 162
L 10:18:39.382 usb-A40117UK OK 22 193 174 167 164
L 10:18:47.741 usb-A40117UK OK 22 193 209 185 175
``````

The 193 comes from AIO1, which has the 10 + 10 kΩ divider, and reports 2.50V – spot on.

But as you can see, the second value is all over the map (ignore the 3rd and 4th, they are floating). The reason for this is that the 10 MΩ resistors are so high that all sorts of noise gets picked up and “measured”.

With a 1 + 1 MΩ divider, things do improve, but the current draw increases to 2.5 µA:

``````L 09:21:25.557 usb-A40117UK OK 22 198 200 192 186
L 09:21:33.907 usb-A40117UK OK 22 198 192 182 177
L 09:21:42.256 usb-A40117UK OK 22 197 199 188 183
L 09:21:50.606 usb-A40117UK OK 22 197 195 187 183
L 09:21:58.965 usb-A40117UK OK 22 197 197 186 181
L 09:22:07.315 usb-A40117UK OK 22 198 198 190 184
``````

Can we do better? Sure. The trick is to add a small capacitor in parallel with the lower resistor. Here’s a test using 10 + 10 MΩ again, with a 0.1 µF cap between AIO2 and GND:

Results – at 5V we get 196, i.e. 2.54V:

``````L 10:30:27.768 usb-A40117UK OK 22 198 196 189 186
L 10:30:36.118 usb-A40117UK OK 22 198 196 188 183
L 10:30:44.478 usb-A40117UK OK 22 198 196 186 182
L 10:30:52.842 usb-A40117UK OK 22 198 196 189 185
L 10:31:01.186 usb-A40117UK OK 22 197 196 186 181
``````

At 4V we get 157, i.e. 2.03V:

``````L 10:33:31.552 usb-A40117UK OK 22 158 157 158 161
L 10:33:39.902 usb-A40117UK OK 22 158 157 156 157
L 10:33:48.246 usb-A40117UK OK 22 158 157 159 161
L 10:33:56.611 usb-A40117UK OK 22 158 157 157 159
L 10:34:04.959 usb-A40117UK OK 22 159 157 158 161
``````

At 6V we get 235, i.e. 3.04V:

``````L 10:47:26.658 usb-A40117UK OK 22 237 235 222 210
L 10:47:35.023 usb-A40117UK OK 22 237 235 210 199
L 10:47:43.373 usb-A40117UK OK 22 236 235 222 210
L 10:47:51.755 usb-A40117UK OK 22 237 235 208 194
L 10:48:00.080 usb-A40117UK OK 22 236 235 220 209
``````

Perfect!

Note how the floating AIO3 and AIO4 pins tend to follow the levels on AIO1 and AIO2. My hunch is that the ADC’s sample-and-hold circuit is now working in reverse: when AIO3 is read, the S&H switches on, and levels the charge on the unconnected pin (which still has a tiny amount of parasitic capacitance) and the internal capacitance.

The current draw through this permanently-connected resistor divider with charge cap will be very low indeed: 0.3 µA at 6V (Ohm’s law: 6V / 20 MΩ). This sort of leakage current is probably fine in most cases, and gives us the ability to check the battery level in a wireless node, even with battery voltages above VCC.

Tomorrow I’ll explore a setup which draws no current in sleep mode. Just for kicks…

## Maxing out the Hameg scope

In AVR, Hardware on May 10, 2013 at 00:01

Yesterday’s post was about how test equipment can differ not only in terms of hardware, but also the software/firmware that comes with it (anyone hacking on the Owons or Rigols yet to make the software more feature-full?).

Here’s another example, where I’m using just about all the bells and whistles of the Hameg HMO series scopes – not for the heck of it, but because it really can help gain more insight about the circuit being examined.

This is my second attempt at understanding what sort of start up currents need to be available for the new JeeNode Micro v3 to properly power up:

I’m applying a 0..2V power up ramp (yellow line) as power supply, using a 1 Hz sawtooth signal. This again simulates an energy harvesting setup where the power supply slowly ramps up (the real thing would actually rise far more slowly, i.e. when using a solar cell + supercap, for example). The current consumed by the JNµ v3 (blue line) is measured by measuring the voltage drop across a 10 Ω resistor – as usual.

The current consumption starts at about 0.85V and rises until the power supply reaches about 1.4V. At that point, the current consumption is about 77 µA. Then the ATtiny84A comes out of reset, enters a very brief high-current mode (much higher than the peak shown, but this is averaged out), and then goes into ultra low-power sleep mode. The sketch running on the JNµ is the latest power_down.ino, here in simplified form:

```#include <JeeLib.h>

void setup () {
cli();
Sleepy::powerDown();
}

void loop () {}
```

Note that since this is the new JNµ v3, the RFM12B module never even gets powered up, so there’s no need to initialise the radio and then put it in sleep mode.

The red line uses the Hameg’s advanced math features to perform digital filtering on top of the averaging already performed during acquisition: the averaging keeps the power-up spike visible (albeit distorted), at the cost of leaving some residual noise in the blue trace, while the IIR digital low-pass filter applied to that result then makes it possible to estimate the 77 µA current draw just before the ATtiny84A starts running.

Here’s the zoomed-in view, showing the interesting segment in even more detail:

The IIR filtering seen here is slightly different, with a little spike due to the following power-up spike, so the 86 µA reported here is slightly on the high side.

Note how the Hameg’s storage, high sensitivity, averaging, adjustable units display, variable vertical scale, math functions, on-screen measurements, on-screen cursors, and zooming all come together to produce a pretty informative screen shot of what is going on. Frankly, I wouldn’t know how to obtain this level of info in any other way.

So what’s all this fuss about measuring that 77 µA level?

Well, this is how much current the JNµ draws before it starts running its code. There’s nothing we can do to reduce this power consumption further until it reaches this point. In the case of energy harvesting, the supply – no matter how it’s generated – will have to be able to briefly deliver at least 77 µA to overcome the startup requirements. If it doesn’t, then the supply voltage (presumably a supercap or rechargeable battery) will never rise further, even though a JNµ can easily draw less than a tenth of that current once it has started up and goes into ultra-low power with brief occasional wake-ups to do the real work.

What I’m taking away from this, is that a solar energy setup will need to provide at least 0.1 mA somewhere during the day to get a JNµ started up. Once that happens, and as long as there is enough power to supply the average current needed, the node can then run at lower power levels. But whenever the supercap or battery runs out, another period with enough light is needed to generate that 0.1 mA again.

It all sounds ridiculously low, and in a way it is: 0.1 mA could be supplied for over two years by 3 AA batteries. The reason for going through all this trouble, is that I’d really like to find a way to run off indoor solar energy light levels. Even if it only works near a window, it would completely remove the need for batteries. It would allow me to just sprinkle such nodes where needed and collect data … forever.

## Automated + manual 230V

In Hardware on Apr 20, 2013 at 00:01

(This is based on an idea by Ard Jonker, who planted a seed and watched the coin drop, if you excuse the mixed metaphors…)

The recent experiment with direct relay switching suggests that it is possible to switch a latching relay with just two I/O pins tied together plus a 100 µF cap.

The thing about that circuit, is that it draws no current in either ON or OFF state – it only needs a little energy to change the state.

That means it could in principle be powered by a very low-power source, such as this other fun projects I had to shelve a while back. The reasons for this remain as valid as ever: I can’t realistically turn this into a safe kit, given the direct connection to AC mains. So while the thought of having 80 of these sprinkled around the house and consuming under 1 Watt total is a tempting thought, it just isn’t going to happen.

Which doesn’t prevent ME from using it anyway, of course…

Ok, now let’s bring a couple of components together:

• a JeeNode Micro
• a 12 mW AC mains supply
• a directly-powered latching relay
• a toggle switch
• power cabling

Here they are, with a nice plastic case (whoops, forgot to include the JNµ, oh well):

The toggle switch is the small but essential ingredient here. Let me explain:

This is a switch which can be operated manually and remotely. Flipping the switch or the relay has the same effect: toggling power, regardless of the state of the other component!

This means it can be operated even when the automated system is off or disconnected, or has crashed. And likewise, the power remains under remote control regardless of the state of the manual toggle switch. This solves a key problem with all those cheap remote power switches out there: the necessity to find the remote, because there is no local switch anymore. And the fact that it breaks down when the home automation system fails.

Given the relay used, I doubt that this solution will be able to control more than 30..50 W, but there are plenty of such devices around the house these days, even LED lighting.

I think I’m gonna have to start messing with AC mains again… with caution, of course.

## (9)50 days and counting

In AVR, Hardware, Software on Apr 18, 2013 at 00:01

The new JeeNode Micro has joined the ranks of the test nodes running here to determine battery life in real time. The oldest one has been running over 2 and a half years now:

That LiPo battery has a capacity of 1300 mAh, and since it’s still running, this implies that the average current draw must be under 1300/24/950 = 57 µA, including self-discharge.

The other two battery tests now running here are based on the new JeeNode Micro v3, i.e. this one – using a boost converter:

… and another one using a coin cell. Here’s a picture of a slightly older version:

The boost version is running off a rechargeable AA battery, of type Eneloop, which I use all over the house now. These batteries hold 1900 mAh, but there’s a substantial penalty for running off one AA cell with a boost converter:

• energy is not free, i.e. drawing 10 µA at 3.3V means we will need to draw 30 µA at 1.1V, even if we could use a 100% efficient boost converter
• real-world efficiency is more like 70..80% at these levels, so make that 40..45 µA
• the boost converter has some idle current consumption, probably 10..20 µA, so this means we’ll draw 50..65 µA even if the JeeNode Micro only uses up 10 µA at 3.3V (actually, it’s 3.0V in the latest JNµ)

This would translate to 1900/.065/24/365, i.e. ≈ 3-year life. Or perhaps 2, if we account for the Eneloop’s 85% per year self-discharge.

The coin cell option runs off a CR2032 battery, which is rated at about 225 mAh, i.e. considerably less than the above options. Still, since there are no boost converter losses, this translates to 225/0.010/24/365, i.e. ≈ 2.5 years of life if the JNµ draws only 10 µA.

These figures look excellent, but keep in mind that 10 µA average power consumption is a very very optimistic value, particularly when there are sensors hooked up and packets are being sent out. I’d be quite happy with a 6-month battery life for a single AA or a coin cell.

For reference, here is an earlier post about all these power calculations.

Here are the current reports I’m getting via HouseMon:

That’s just about 50 days off a coin cell. Let’s see how it holds up. The nice bit in these tests is that the new nodes now report several different voltage level measurements as well (this also consumes some energy!). They haven’t dropped much yet, but when they do, I hope that we’ll be able to use the drop as a predictor.

Onwards!

## JeeNode Micro start-up power

In AVR, Hardware on Mar 29, 2013 at 00:01

The JeeNode Micro v3 includes a P-channel MOSFET to control power to the RFM12B radio. This isn’t just a new gimmick – the goal was to “fix” the RFM12B wireless radio’s startup power consumption, which can prevent an ultra-low power source from ever building up a high enough supply voltage for a JeeNode to start up.

Now that the JNµ is in production, it’s time to measure how well such an approach works. Get ready for a bunch of scope screenshots, all based on the same circuit as before:

… except that now the entire JeeNode Micro is in there, and I’m using a 10 Ω resistor.

I’ll be applying a 1 Hz ramp signal going from 0.0 to 3.0V using the power booster behind a signal generator, to see exactly what amount of current is being drawn. In all the images below, the yellow trace is the input voltage (i.e. a simulated power supply), and the blue trace is the voltage over the 10 Ω resistor – that means 1 vertical division on the blue trace corresponds to 0.5 mA when the display shows 5 mV/div:

The above image is just a baseline: a simple blink sketch which never enables the radio, and which then toggles some I/O pins every 500 ms. As you can see, the ATtiny84 comes out of power-on reset at about 1.4V and ends up drawing about 3.5 mA at 3.0V.

Fuses are set to low=C2 high=D7 ext=FF, i.e. BOD disabled, startup asap on RC @ 8Mhz.

Now let’s look at the same setup with the JNµ running radioBlip2.ino:

This time, the sketch enables the MOSFET to power up the radio, measures the battery voltage, tries to send out a packet (this will fail at 1.4V), and goes into deep sleep. A short but very quick (and high!) blip before power consumption drops to almost zero.

The third measurement is with a sketch doing nothing but powering down right away:

```#include <JeeLib.h>

void setup () {
cli(); // disable all interrupts
Sleepy::powerDown();
}

void loop () {}
```

Which produces this result:

I’ve bumped the scope sensitivity up to its maximum of 1 mV/div (i.e. 100 µA/div) and am now adding a lot of averaging to try and keep the displayed noise levels low. The “blip” is the ATtiny getting out of reset and powering down completely.

As last test, I repeated the above, but now using a sweep of 10 s (0.1 Hz), and filtering the signal through the lowest low-pass setting available, i.e. 5 Hz. This loses the important spike at 1.4V, which is of course still there, but improves the readout of the baseline:

As you can see, the power consumption now never rises above ≈ 60 µA – that’s a ten-fold improvement over what we get with the RFM12B connected to power in the standard way.

The shape of this curve is quite interesting: it’s essentially resistive (since it’s more or less linear), but the current starts at 1.2V, i.e. after overcoming two extra diode drops.

This is the power-up “hump” which any ultra-low power supply based on solar cells or other energy harvesting techniques will need to overcome, so that the ATtiny can switch itself into power down mode and let the supply voltage rise further.

I think that’s an excellent result, and am looking forward to trying a few things out!

## Direct relay switching – final

In Hardware on Mar 19, 2013 at 00:01

To conclude this little excursion into relay switching, here is the final circuit:

I’ve re-wired everything to use two DIO pins, and removed the extra 10 Ω resistor:

Bottom side:

The sketch can now switch both I/O pins using a single instruction, and avoid the brief shorting out of the I/O pins on the ATmega:

```void setup() {
digitalWrite(5, 0);
digitalWrite(6, 0);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
}

static void setLatch (bool on) {
// change both I/O pins in the same clock cycle
if (on)
PORTD |= bit(5) | bit(6);
else
PORTD &= ~ (bit(5) | bit(6));
}

void loop() {
setLatch(true);
delay(1000);
setLatch(false);
delay(1000);
}
```

This also gets rid of the inductive kickback, or rather, it “diffuses” that effect into the slow capacitor charge and discharge ramps. All in all, I think this setup is a viable circuit for low-power switching of this tiny relay.

I’ve ordered a few more of these units, and intend to try them out with live 230 VAC mains switching. Note that this is pushing it, and that it will most definitely not meet all rules and regulations for mains separation and isolation – but for just controlling small lights, and other small devices such as power adapters and chargers, I think it’s still usable, and am willing to try it – at least for personal use around the house here at JeeLabs.

Onwards!

## Direct relay switching

In Hardware on Mar 16, 2013 at 00:01

There are small relays which are just weak enough to be switched directly by the ATmega’s I/O pins, even at 3.3V. I’ve been chasing and trying out these types of relays for some time, especially the latching types which only require power to switch, not to stay on.

Today, I received a very nice surprise package from @eljonco, who sent me a nice little latching relay (from eBay) which I’ve immediately mounted on a Proto Board:

Bottom side connects DIO2 + AIO2 to one side of the coil, and DIO3 + AIO3 to the other:

Why both? Because one pin drive is not strong enough to make these units switch at 3.3V:

…whereas driving them both in parallel works, resulting in a clear clicking sound and a very nasty “inductive kick-back” switching pulse across the coil on power-off:

There are horrific things going on here, electrically speaking, which I’ll look into later.

For now, let me just explain what’s going on and how this single-coil latching relay is being switched, using four I/O pins (port 2 and 3 on a JeeNode in this case):

The relay core can be switched with a brief pulse, reversing the polarity to reverse the action. So we connect it to two different I/O pins and drive it as an H-bridge. When both pin levels are the same (or when the I/O pins are floating), nothing happens. By putting one pair in “0” state and the other in “1” state, current flows through the coil.

So to turn the relay on, the actions are:

• set DIO2 = AIO2 = 0
• set DIO3 = AIO3 = 1
• wait 3 ms
• set DIO3 = AIO3 = 0 (same as DIO2 and AIO3), or make them float, i.e. inputs

To turn it off, we simply exchange the 0’s and 1’s in the above.

More on this tomorrow. Stay tuned…

## Hot spots on a JeeNode USB

In Hardware on Mar 13, 2013 at 00:01

Recently, a blower door test was done here at JeeLabs, as a way to measure – not guess – how air currents are affecting the house, and what sort of insulation measures would be most effective. This was a fascinating and very extensive test, combined with a thorough scan of the entire house – inside and outside – using a high-end thermal imaging camera.

While the guys from Bergenbos were doing their tests, I asked them to take some close-ups of a JeeNode which had been running RF12demo for a while (i.e. not in sleep mode):

Fantastic resolution, as you can see. No big surprises, but nice pictures nevertheless…

## JNµ battery tests

In AVR, Hardware on Mar 4, 2013 at 00:01

With the LiPo battery “blipping” along happily for years now, I’ve started two new tests, based on the JeeNode Micro v3. Here’s the boost unit, running an updated radioBlip2.ino:

This one converts the incoming 1.2 .. 1.4 V from a single-cell Eneloop AA battery to roughly 3.0 V, as you can see in this overview in HouseMon (using an updated “radioBlip” driver):

The other new node runs off a CR2032 coin cell, which is struggling a bit to maintain a stable voltage each time a packet gets sent out, as indicated by the 3.20 -> 3.08 V drop. In case you’re wondering how a node can report its battery voltage after already having sent the data, simple: measure the voltage and send it out in the next packet.

The technique used to measure one’s own battery voltage was described in a post last year. Measuring the battery voltage in this way does not consume very much power in itself, since the ATtiny is placed in a special low-power “ADC-only” sleep mode while doing so:

The energy used for the measurement is the area under those last four little “blips” after the main packet transmission: there’s almost no penalty in performing this measurement before and after each packet transmission. Over time, hopefully the trend of the before + after voltages can be used as predictor for the amount of life left in them little coin cells…

PS – The main change in the radioBlip2 sketch, apart from adapting it to work on the ATtiny, is that the packet now includes a “sender ID” byte. This way all the battery test nodes can re-use the same node ID here at JeeLabs – since the number of ID’s used is starting to become a concern (there are 30 unique ID’s in each net group). For nodes like these, which only send, it’s no problem at all to “re-use” node ID’s this way.

Update – I’ve added a “BOOST” option to report the battery input voltage, which is much more useful. It’s measured with a jumper from PWR to the AIO pin (PA0, analog 0).

## Taking the JNµ to 3.0 V

In AVR, Hardware on Mar 1, 2013 at 00:01

As mentioned in yesterday’s post, lower supply voltages lead to lower power consumption.

There’s a new JeeNode Micro v3 revision coming which applies this logic to try and get the power consumption as low as possible. It also has changed slightly in its pinout:

The main physical changes are: it’s now 16 x 43 mm, and the ISP pins are no longer 2×3.

Let’s just focus on the power side of things for now, though. The JNµ v3 can be operated from several power sources:

• Direct power: this runs without regulation, and requires a 2.2V .. 3.8V power source
• Boost power: using the same circuit as the AA Power Board, runs from 0.9V .. 5.0V

The boost power circuit is very flexible as you can see, but it adds a certain amount of quiescent power consumption of its own, making the whole setup draw more idle current than when it is directly powered. What you do get with the boost power hookup, is that it’ll try to stay running as long as possible, down to a 0.5 V input under ideal conditions, so this thing will squeeze the last drop of energy out of its power source. Great for “empty” AA’s!

Boost power supplies are very clever and useful circuits, but they can’t break the laws of physics: a 100% efficient boost supply will draw 15 mA when asked to generate a 3.3 V @ 5 mA output from a 1.1 V input source. The current it draws will be triple that which it produces (more like four times, in fact, since the real circuit is far from 100% efficient).

Note that – in the light of yesterday’s story – it would really make no sense to pump up the voltage to say 5V, only to end up with a more wasteful circuit. That’s not just a quadratic increase, those losses would in fact be proportional to the third power of the voltage!

With a boost circuit, it really pays to work with as low an output voltage as possible. Which is why the JeeNode Micro v3 now comes with a 3.0V version of the boost chip, not 3.3V.

Let’s do the math, assuming a 100% efficient boost supply:

• a 3.0 V booster draws 3.0 / 3.3 ≈ 91% of the current in comparison to a 3.3 V one
• running at 3.0 V instead of 3.3 V consumes ≈ 83% of the power (with a resistive load)
• combined, that means we’ll be using 3.0 ^ 3 / 3.3 ^ 3 ≈ 75% of the power at 3.0 V
• so the total power consumed is 25% less at 3.0 V compared to what it’d take at 3.3V

That translates to 3 more months on a battery lifetime of 1 year – quite a bit!

This doesn’t just apply to the boost regulator: coin cells often have a 3.0V rating, and so do 2 alkaline AA batteries in series. Note also that 2 rechargable AA batteries will still work fine, as these will supply 2.4..2.6 V, well within the direct power range of the JNµ v3.

Note that for all the standard JeeNodes, nothing changes: these will continue to be populated with 3.3V regulators. One key reason for this is that they are already operating slightly beyond their specs (“overclocked”) with the clock running at 16 MHz. We shouldn’t push our luck with these settings, which are standard in the Arduino world. So the JN, JN SMD, and JN USB will all continue to be operated at 3.3V – no changes!

As for the many different JeePlugs: these all run at 3.3V, and the chips used on these plugs are normally qualified to run at either 3.0 .. 3.6V or 2.7 .. 3.3V, so we’re still fully in range.

Is it all win, then? Well, yes, but note that the noise margins are slightly reduced at 3.0V, which can slightly affect the accuracy of analog pin measurements and the cable lengths at which I2C chips still operate reliably. These effects are going to be minimal, I expect, but it’s something to watch out for.

Update – As pointed out in the comments, the above calculations are not correct. There is a small effect on booster circuit efficiency in all this, but the power savings are closer to 20% than 25% – not quite 3 months per year, as I claimed.

## Dropping below 3.3 V

In AVR, Hardware on Feb 28, 2013 at 00:01

One of the departures from the Arduino world has always been that JeeNodes operate at 3.3 V, whereas the standard Arduino’s all ran at 5 V. Things are changing, with the ARM-based “Arduino Due”, for example, which also runs at 3.3 V. There’s not really a choice: ARM chips all run at 3.3V or less (3.6V max actually, which leaves a nice safety margin).

So what’s this trend towards lower voltages all about, eh?

Well… you may have seen an older post in the Easy Electrons series (whoa, over two years ago.. time flies!). If you think about it for a moment, all the electric energy pumped into a circuits will end up being converted into some other form of energy: a teeny tiny bit of radiated RF energy in the case of a JeeNode, but mostly heat, really.

Odd as it may seem, all that electronic stuff is just a way to turn current into heat. There is a purpose for this, since we’re usually interested in the side effects: some physical sensing and some computation, leading to the information we’re interested in. But the electricity consumption is just an (unavoidable) side-effect.

Whenever we can lower the voltage and/or current consumption, we’ll end up consuming less power as a result (W = I x V). Lowering the voltage on a circuit often leads to a dramatic reduction in power, since part of a circuit is always resistive. Ohm’s law says that voltage = resistance x current, or to put it differently: current = voltage / resistance. So halving the voltage (V) over a resistor also halves the current (I) it draws. The effect: half the voltage leads to a quarter of the power consumption, in purely resistive circuits:

Unfortunately, you can’t just use 0.1 V to power a circuit: bipolar semiconductors such as diodes and transistors have a 0.6V threshold voltage, anything below that renders them useless. In the real world, running digital circuits at under 1.0 V is rarely done. Even that 1.8 V level down to which an ATmega and ATtiny can be operated is pushing some limits.

Another reason is that lower voltages make capacitive effects more dominant. The lower you go, the longer it takes to charge or discharge a capacitor. Which explains why the ATmega’s maximum clock speed must drop to 4 MHz with a supply voltage of 1.8 V.

But lowering the clock speed is somewhat self-defeating, as this means that the ATmega and ATtiny have to remain powered-up longer before going back into deep-sleep mode! Lots of trade-offs. Still: a low supply voltage is often a good idea – generally speaking.

Tomorrow, I’ll describe the choices made for the next revision of the JeeNode Micro…

## Solar fingernails

In Hardware on Feb 11, 2013 at 00:01

A couple of weeks ago, I described a little indoor solar energy test setup, based on a couple of fingernail-sized CPC1824 solar cell chips, with 0.47 Farad supercaps for storage:

It has been an interesting setup to keep running for a while, and now that 20 days have passed, it’s sort of intriguing to see how well, or badly, these solar energy cells performed. To summarise, here is what the four different test were about:

1. One CPC1824, very lightly loaded with 20 MΩ, i.e. a 0.15..0.20 µA current draw
2. One CPC1824, lightly loaded with 2 MΩ, i.e. a 1.5..2.0 µA current draw
3. One CPC1824, moderately loaded with 0.2 MΩ, i.e. a 15..20 µA current draw
4. Two CPC1824’s in parallel, moderate load with 0.2 MΩ, again 15..20 µA current draw

In addition, there is a top-up voltage cycling once per ≈ 2 hours, to prevent any the supercaps from discharging much further than about 2.7V. This is not a realistic situation if this setup were to be used for real, but I wanted to prevent a total discharge of the supercaps, to try and find out whether the supercaps would get better (i.e. less leaky) over time, as the constant charge conditions those membranes full of useable electrons.

Here are the results of 20 days, superimposed one upon the other:

(click two times to see it in full scale – X axis is in minutes since midnight UTC)

• #1 = blue, #2 = bright green, #3 = orange (dotted), #4 = red (longer dots)
• the last day is marked in black for all four cases
• around noon, all cells fall into the shadow, so energy generation almost stops
• note how only the blue lines stay above 3.0V (except in the first 2..3 days)

This was a wintery mix of sunny and cloudy days, which has a huge effect on the charge / discharge curves. Looks like indoor solar with these tiny cells is not going to work…

One conclusion is that only the lightest load of 0.15..0.20 µA allows the supercap to retain a decent amount of charge through each night. On the other end of the range: with two solar cells in parallel, a 15..20 µA load might be able to stay alive for a few hours each day.

Ehm, well, just maybe – this will really depend on the startup power consumption curves!

## Solar… again – first results

In Software on Jan 23, 2013 at 00:01

Sorry for keeping you in suspense after presenting yesterday’s code. I had to let this run for a few days to collect enough data worth graphing…

Some raw output:

``````L 15:01:00.818 usb-A40117UK OK 20 90 27 224 25 128 26 224 26
L 15:02:01.232 usb-A40117UK OK 20 68 27 224 25 128 26 224 26
L 15:03:01.663 usb-A40117UK OK 20 64 27 224 25 128 26 224 26
L 15:04:02.075 usb-A40117UK OK 20 64 27 222 25 127 26 224 26
L 15:05:02.486 usb-A40117UK OK 20 64 27 195 25 128 26 224 26
L 15:06:02.901 usb-A40117UK OK 20 64 27 192 25 123 26 224 26
L 15:07:03.314 usb-A40117UK OK 20 63 27 192 25 124 26 224 26
L 15:08:03.728 usb-A40117UK OK 20 38 27 192 25 111 26 224 26
L 15:09:04.140 usb-A40117UK OK 20 32 27 192 25 104 26 224 26
L 15:10:04.557 usb-A40117UK OK 20 32 27 169 25 99 26 224 26
``````

And here some readings with DIO1 turned on:

``````L 16:01:24.894 usb-A40117UK OK 20 30 51 0 51 128 51 32 51
L 16:02:25.293 usb-A40117UK OK 20 159 51 128 51 0 52 160 51
L 16:03:25.677 usb-A40117UK OK 20 0 52 224 51 107 52 0 52
L 16:04:26.061 usb-A40117UK OK 20 64 52 55 52 192 52 96 52
L 16:05:26.461 usb-A40117UK OK 20 128 52 113 52 0 53 160 52
L 16:06:26.849 usb-A40117UK OK 20 192 52 160 52 61 53 192 52
L 16:07:27.224 usb-A40117UK OK 20 224 52 192 52 96 53 0 53
L 16:08:27.622 usb-A40117UK OK 20 0 53 237 52 128 53 32 53
L 16:09:28.011 usb-A40117UK OK 20 32 53 12 53 160 53 64 53
L 16:10:28.406 usb-A40117UK OK 20 64 53 32 53 192 53 96 53
``````

In decimal, this is what I see:

``````a0: 13952 a1: 13914 a2: 14144 a3: 14017
``````

Here are the first eight hours after sunset – no energy coming in at all, just conditioning:

Top to bottom: orange = 2 MΩ, red = 20 MΩ, blue = 2-C 200 kΩ, green = 1-C 200 kΩ. Some variation probably due to resistor / supercap tolerances.

Since we’re measuring half the voltage of the supercaps, you can see that they have all reached around 2.8V at this point. The interesting bit will be to see whether the voltage ever rises in the time between DIO1 “on” cycles – indicating a charge surplus!

Here’s the next 24 hours, only the 2 and 20 MΩ loads benefit from this cloudy winter day:

Another day, some real sunlight, not enough yet to survive the next night, even w/ 20 MΩ:

Note that the only curves which hold any promise, are the ones which can permanently stay above that hourly on/off cycle, since that DIO-pin top-up won’t be there to bail us out when using these solar cells as a real power source.

I’ll leave it for now – and will collect data for some more days, or perhaps weeks if there’s any point with these tiny solar cells. Will report in due time … for now: patience!

PS. Note that these fingernail-sized CPC1824 chips are a lot more than just some PV material in an SOIC package. There appears to be a switching boost regulator in there!

## Solar… again – the code

In Software on Jan 22, 2013 at 00:01

With the hardware ready to go, it’s time to take that last step – the software!

Here is a little sketch called slowLogger.ino, now in JeeLib on GitHub:

It’s pretty general-purpose, really – measure 4 analog signals once a minute, and report them as wireless packet. There are a couple of points to make about this sketch:

• The DIO1 pin will toggle approximately once every 64 minutes, i.e. one hour low / one hour high. This is used in the solar test setup to charge the supercaps to about 2.7V half of the time. The charge and discharge curves can provide useful info.

• The analog channel is selected by doing a fake reading, and then waiting 100 ms. This sets the ADC channel to the proper input pin, and then lets the charge on the ADC sample-and-hold capacitor settle a bit. It is needed when the output impedance of the signal is high, and helps set up a more accurate voltage in the ADC.

• The analog readings are done by summing up each value 32 times. When dividing this value, you get an average, which will be more accurate than a single reading if there is noise in the signal. By not dividing the value, we get the maximum possible amount of information about the exact voltage level. Here, it helps get more stable readings.

As it turns out, the current values reported are almost exactly 10x the voltage in millivolts (the scale ends up as 32767 / 3.3), which is quite convenient for debugging.

Having said all this, you shouldn’t expect miracles. It’s just a way to get minute-by-minute readings, with hopefully not too many fluctuations due to noise or signal spikes.

Tomorrow, some early results!

## Solar… again – setup

In Software on Jan 21, 2013 at 00:01

With the purpose out of the way, it’s time start building.

It’s all a big hack, and since I didn’t plan the board layout, it all ended up being hard to hookup to a JeeNode, so I had to tack on a Proto Board:

Those solar cells are tiny! – if they don’t work, I’ll switch to more conventional bigger ones.

On the back, some resistors and diodes:

I used a JeeNode USB (about 60 µA consumption in power-down, due to the extra FTDI chip), but am powering it all via a 3x AA battery pack to get full autonomy. The idea is to place this thing indoor, facing south through a window:

Tomorrow, the code…

## Solar… again

In Hardware on Jan 20, 2013 at 00:01

These dark and cold winter days are not really effective for solar energy: the entire month of January will probably not generate more power energy than two peak days in July!

Still, it’s a good baseline to try things with. And one of the experiments I haven’t given up on is making nodes run off solar power, using a supercap to hold the charge. Maybe they’ll not last through the night, but that’s fine – there are still various uses (especially outdoor) where being able to run during daytime with nodes that never need to have their batteries changed would be really nice.

In previous attempts, I’ve always immediately tried to power the actual node, but now I’d like to try something simpler: a solar cell, a supercap, and a resistor as load. Like this:

I’m using a tiny solar cell by Clare again, the CPC1824, with the following specs:

Not much, but then again, it’s a cell which is just the size of a fingernail. As SOIC-16 package, and with the specs of the available current next to it:

In fact, I’d like to try this out with 4 different resistive loads:

• one cell, 2x R = 20 MΩ = 0.2 µA current draw at full output
• one cell, 2x R = 2 MΩ = 2 µA current draw at full output
• one cell, 2x R = 200 KΩ = 20 µA current draw at full output
• two cells in paralel, 2x R = 200 KΩ = 20 µA current draw at full output

There may be a flaw in this approach, in that the leakage of the supercap could completely overshadow the current draw from the resistors. But my hope is that supercaps get better over time when kept charged. Hmmm… not sure it applies if they run down every night.

So the second part of the idea, is to alternate solar cell use and dumb charging – just to measure how that affects output voltage over time. One hour, DIO will be on, and put the supercap on about 2.7V, the other hour it’ll be off and the solar cell takes over. With a bit of luck, the output voltage changes might show a pattern, right?

I think it’s worth a try and have made a setup with 4x the above – more tomorrow…

## Remote node discovery

In Software on Jan 14, 2013 at 00:01

The current use of the wireless RF12 driver is very basic. That’s by design: simple works.

All you get is the ability to send out 0..66 bytes of data, either as broadcast or directed to a specific node. The latter is just a little trick, since the nature of wireless communication is such that everything goes everywhere anyway – so point to point is simply a matter of receivers filtering out and ignoring packets not intended for them.

The other thing you get with the RF12 driver, is the ability to request an acknowledgement of good reception, which the receiver deals with by sending an “ACK” packet back. Note that ACKs can contain data – so this same mechanism can also be used to request data from another node, if they both agree to use the protocol in this way, that is.

So there are three types of packets: data sent out as is, data sent out with the request to send an ACK back, and packets with this ACK. Each of them with a 0..66 byte payload.

But even though it all works well, there’s an important aspect of wireless sensor networks which has never been addressed: the ability for nodes to tell other nodes what/who they are. As a consequence, I always have to manually update a little table on my receiving server with a mapping from node ID to what sketch that node is currently running.

Trivial stuff, but still a bit inconvenient in the longer run. Why can’t each node let me know what it is and then I don’t have to worry about mixing things up, or keeping that table in sync with reality every time something changes?

Well… there’s more to it than a mapping of node ID’s – I also want to track the location of each node, and assign it a meaningful name such as “room node in the living room”. This is not something each node can know, so the need to maintain a table on the server is not going to disappear just by having nodes send out their sketch + version info.

Another important piece of information is the packet format. Each sketch uses its own format, and some of them can be non-trivial, for example with the OOK relay sending out all sorts of packets, received from a range of different brands of OOK sensors.

It would be sheer madness to define an XML DTD or schema and send validated XML with namespace info and the whole shebang in each packet, even though that is more or less the level of detail we’re after.

Shall we use JSON then? Protocol buffers? Bencode? ASN.1? – None of all that, please!

When power is so scarce that microcoulombs matter, you want to keep packet sizes as absolutely minimal as possible. A switch from a 1-bye to a 2-byte payload increases the average transmit power consumption of the node by about 10%. That’s because each packet has a fixed header + trailer byte overhead, and because the energy consumption of the transmitter is proportional to the time it is kept on.

The best way to keep packet sizes minimal, is to let each node pick what works best!

That’s why I play lots and lots of tricks each time when coming up with a remote sketch. The room node gets all its info across in just 4 bytes of data. Short packets keep power consumption low and also reduce the chance of collisions. Short is good.

Tomorrow, I’ll describe an idea for node discovery and packet format description.

## RFM12B startup power consumption

In Hardware on Dec 29, 2012 at 00:01

For quite some time, I’ve wanted to know just how much current the RFM12B module draws on power-up. Well, time for a test using the power booster described recently:

So the idea is to apply a sawtooth signal to the RFM12B, rising from 0 to 3V at the rate of say 10 Hz, and to measure the voltage drop across a 100 Ω resistor at the same time. This will have a slight effect on measurement accuracy – but no more than 2%, so I’m ok with it.

Here is the outcome:

The yellow trace is VCC, the supply voltage – from 0..3V. The magenta trace is the current consumption, which turns out to be 0..650 µA. As you can see, the current draw quickly rises between 1 and 2V, and then continues to increase sort of linearly.

Note that this power consumption can’t be reduced: we don’t have the ability to send any commands to the RFM12B until it has started up!

This type of analysis can also be done using the X-Y mode on most oscilloscopes:

It’s essentially the same picture as before, because the sawtooth is a straight line, and so voltage rise is the same thing as time in this case. Here’s what happens when the input signal is switched to a sine wave:

As expected, the essence of the curve hasn’t changed one bit. Because it really doesn’t matter how we vary VCC over time. But there’s an intriguing split in the curve – this is most likely caused by a different current consumption when VCC is rising vs when it is dropping. Keep in mind that the changes are occurring at 10 Hz, so there’s bound to be some residual charge in the on-board capacitors of the RFM12B module.

Anyway. It’s a bit of a silly distraction to do things this way, but now I do have a better idea of how current consumption increases on startup. This relatively high 0.65 mA current draw was the main reason for including a MOSFET in the new JeeNode Micro v2, BTW.

## Watts, Amps, Coulombs

In Hardware on Nov 26, 2012 at 00:01

Sometimes I see some confusion on the web regarding the units to measure power with.

Here’s a little summary, in case you ever find yourself scratching your head with this stuff:

• Electric potential is sort of a “pressure level” when using the water analogy, expressed in Volts (V)
• Current is the flow of electrons, and is expressed in Amperes (A)
• Charge is the “amount of electricity”, and is expressed in Coulombs (C)
• Power is the product of volts and amperes, and is expressed in Watts (W)

Another measure of power is Volt-Amperes, this is not the same as Watts in the case of alternating current with reactive loads, but let’s not go there for now…

To summarise with the water analogy:

• Volts = how high has the water been pumped up
• Amps = how much water is flowing
• Coulombs = the amount of water
• Watts = how much energy is being used (or generated)

You can probably guess from this list that pumping water up twice as high (V) takes twice as much energy, and that pumping up twice as much (A) also takes twice as much energy. Hence the formula:

``````    Watt = Volt * Ampere
``````

Other equations can also help clarify things. They all add time into the mix (in seconds).

Current is “charge per second”:

``````    Ampere = Coulomb / second
``````

This is also the way I estimate average current consumption when diving into ultra-low power JeeNode stuff: using the oscilloscope to integrate (sum up) all the instantaneous current consumptions over time, I get a certain Coulomb (or micro-coulomb) value. If that’s a periodic peak and the system is powered-down the rest of the time, then the estimate becomes: X µC used per Y sec, hence the average current consumption is X / Y µA. The advantage of working with Coulombs in this way, is that you can add up all the estimates for the different states the system is in and still arrive at an average current level.

Another one: power consumption is the amount of energy consumed over time. This is often expressed in Watt-hour (Wh) or kilowatt-hour (kWh):

• two 100 W lightbulbs running for 5 hours = 2 x 100 x 5 = 1000 Wh = 1 kWh
• one LED strip drawing 2 A at 12 V for 3 hours = 2 x 12 x 3 = 72 Wh

And then there’s the “mAh” unit used with batteries, i.e. milli-ampere-hour. Quite simple again, once you get used to this metric system, and realise that you also need the voltage:

• 2 AA batteries of 1.5V @ 2000 mAh each provide 2 x 1.5 x 2000 = 6000 mWh = 6 Wh
• a 5 mA load on batteries of 2000 mAh will run for 2000 / 5 = 400 hours

Battery capacities are roughly as follows for the most common types:

• an AA cell has 2500 mAh @ 1.5V = 3.75 Wh
• an AA rechargeable cell has 2000 mAh @ 1.2V = 2.4 Wh
• an AAA cell has 1000 mAh @ 1.5V = 1.5 Wh
• an AAA rechargeable cell has 800 mAh @ 1.2V = 0.96 Wh
• a CR2032 coin cell has 200 mAh @ 3V = 0.6 Wh

Wanna be able to run for a week on a coin cell? Better make sure your circuit draws no more than 200 / (24 x 7) = 1.2 mA on average under optimal conditions.

Wanna make it run a year on that same coin cell? Stay under 22 µA average, and it will.

With 2 or 3 AA batteries, you get an order of magnitude more to consume, so if you can get the average under 200..220 µA, those batteries should also last a year (ignoring the fact that batteries always have some self-discharge, that is).

The difference between 2, 3, or 4 AA batteries in series only affects the voltage you get out of them. Chips do not run more efficiently on more voltage – on the contrary, in fact!

For low-power use: run your circuit on as low a voltage as possible, but no lower (wink).

## Ultra-low power op-amp

In Hardware on Nov 17, 2012 at 00:01

Op-amps are one of the building blocks of the modern analog electronics industry.

Here’s an interesting one, the MAX4470 .. MAX4474 series:

Simple layout, again in a tiny SMD package:

The other members of this family are dual and quad versions, if you need more op-amps.

This chip is nice because of its phenominally low current consumption: 750 nA at 5V. It gets even better: at 3.3V, I measured a ridiculously low 190 nA!

Here are some more specs from the Maxim datasheet:

Might not be the highest-performance op-amp out there, but still – this thing could be quite handy to implement comparators, voltage followers, oscillators, amplifiers, filters, and more. Especially when the “power budget” is really really low.

PS. I’m assuming this chip isn’t oscillating with the above test setup, but in normal use you really need to tie the input pins to something to avoid that.

## Nanoampere regulator

In Hardware on Nov 16, 2012 at 00:01

The TPS78233 from Texas Instruments looks like a standard LDO linear voltage regulator:

It takes an input voltage up to 5.5V and regulates it down to 3.3V (the above image from the datasheet is the 2.7V regulator). Not a spectacular voltage range, but it has a very nifty trick up its sleeve:

This regulator only draw 450 nA, i.e. 0.45 µA, when unloaded!

That’s about a quarter of the current consumption of the already-spectacular MCP1702 and MCP1703 used in JeeNodes – a ridiculously low 2.5 microwatts.

Here’s a little test setup (yep, those SMD’s are small – can you see the two 10 µF caps?):

To get a sense of this level of current consumption: 3x AA batteries of 2000 mAh would last 5 centuries (ehm, well, except for their pesky self-discharge) – which is a bit silly, of course.

To get another idea: when I measure the output voltage with a multi-meter, the current consumption “jumps” to about 750 nA. Why this relatively big change? Because most multi-meters have a 10..11 MΩ input impedance, and 3.3V over 11 MΩ is… 300 nA!

In case you’re wondering: measuring minute currents is easy with Dave Jones’ µCurrent.

The fascinating thing about the TPX82xx series is that it achieves this extremely low idle current while still being able to regulate and supply up to 150 mA. Furthermore, that enable pin might come in very handy for certain ultra-low energy harvesting scenario’s.

But I’m not going to replace the regulator on JeeNodes for a number of reasons:

1. The MCP1702 can handle input voltages up to 13V (vs only 5.5V for the TPS78233).

2. There’s no through-hole version, so this would not work for standard JeeNode kits.

3. Those extra savings only kick in when you get everything into the few-µA range, and so far, things like Room Nodes still draw a few dozen µA’s.

4. In many cases, when the max is 5.5V anyway, no regulator will be needed at all (note that running only the RFM12B on it may create a problem with signal levels).

But hey, it’s good too know that these chips exist. A few microwatts… wow!

## The difference between 2 and 3

In AVR, Software on Nov 13, 2012 at 00:01

One. Ok, next post :)

I was curious about the difference between Power-down and Standby in the ATmega328p. Power-down turns off the main clock (a 16 MHz resonator in the case of JeeNodes), whereas standy keeps it on. And quite surprised by the outcome… read on.

There’s an easy way to measure this, as far as software goes, because the rf12_sendWait() function has an argument to choose between the two (careful: 2 = Standby, 3 = Power-down – unrelated to the values in the SMCR register!).

I tweaked radioBlip.ino a bit, and came up with this simple test sketch:

With this code, it’s just a matter of hooking up the oscilloscope again in current measurement mode (a 10 Ω resistor in the power line), and comparing the two.

Here’s the standby version (arg 2):

… and here’s the power-down version (arg 3), keeping the display the same:

I’ve zoomed in on the second byte transmission, and have dropped the baseline by 21 mA to properly zoom in, so what you’re seeing is the ATmega waking up to grab store a single byte out of into the RFM12B’s reception FIFO, and then going back to sleep again.

The thing to watch is the baseline level of these two scope captures. In the first case, it’s at about 0.5 mA above the first division, and the processor quickly wakes up, does it’s thing, and goes into power-save again.

In the second case, there’s a 40 to 50 µs delay and “stutter” as the system starts its clock (the 16 MHz resonator), does its thing, and then goes back to that ultra-low power level.

There are bytes coming in going out once every 200 µs, so fast wakeup is essential. The difference is keeping the processor drawing 0.5 mA more, versus a more sophisticated clock startup and then dropping back to total shutdown.

What can also be gleaned from these pictures, is that the RF12 transmit interrupt code takes under 40 µs @ 16 MHz. This explains why the RF12 driver can work with a clock frequency down to 4 MHz.

The thing about power-down mode (arg 3), is that it requires a fuse setting different from what the standard Arduino uses. We have to select fast low-power crystal startup, in 258 cycles, otherwise the ATmega will require too much time to start up. This is about 16 µs, and looks very much like that second little hump in the last screen shot.

Does all this matter, in terms of power savings? Keep in mind that this is running while the RFM12B transmitter is on, drawing 21 mA. This case was about the ATmega powering down between each byte transmission. Using my scope’s math integral function, I measured 52.8 µC for standby vs 60.0 µC for power-down – so we’re talking about a 12 % increase in power consumption during transmit!

The explanation for this seemingly contradictory result is that the power-down version adds a delay before it actually sends out the first byte to transmit. In itself that wouldn’t really make a difference, but because of the delay, the transmitter stays on noticeably longer – wiping out the gains of shutting down the main clock. Check this out:

Standby is the saved white reference trace, power-down is yellow.

See? Ya’ can’t always predict this stuff – better measure before jumping to conclusions!

PS. While I’m at it – enabling the RF12’s “OPTIMIZE_SPI” mode lowers charge usage only a little: from 52.8 to 51.6 µC, i.e. using fast SPI @ 8 MHz i.s.o. 2 MHz for sending to the RFM12B. Hardly worth the trouble.

## Switching with a lower voltage

In Hardware on Nov 10, 2012 at 00:01

The SMA Bluetooth relay described yesterday has to switch the power to the RN-42 module using an I/O pin on the ATmega. Currents are fairly small: up to about 50 mA.

I tried directly powering the RN42 from two I/O pins in parallel, but it looks like they don’t have enough current drive capacity for this purpose. So the task is to find a simple way to switch on power somehow.

The simplest solution would seem to be a P-MOSFET in the “high side” supply, i.e. between PWR and the RN-42’s supply pin, but there is a problem: PWR will be somewhere between 3.3 and 5V (actually it’s more like between 3.6 and 4.0V with the 3xAA Eneloop batteries I’m using), but the I/O pin on the ATmega won’t be more than 3.3V – since the ATmega sits behind a 3.3V voltage regulator. I tried the P-MOSFET, before realising that it’d always be driven on – the I/O pin voltage is sufficiently low to switch the MOSFET on, even with a logic “1” – not good!

MOSFETs are driven by voltage whereas transistors are driven by current, so an obvious thing to try next is to use a PNP transistor in more or less the same configuration. Voltage differences wouldn’t be so critical, if no current flows. Also, there’s the extra base-to-emitter voltage drop or so that each normal transistor has. Still, a simple PNP transistor might switch on if the difference in voltage is large enough – this can be overcome with a PNP Darlington transistor, which is simply two PNP transistors, cascaded in a certain way. The property of these things – apart from their high amplification (hFE) – is that you need to drive the base with a slightly larger voltage. A lower voltage in this case, with PNP types. Could also have used two discrete PNP transistors.

Here’s the circuit:

And sure enough, it works. I happened to have an SMD “BCV 28” lying around:

The 10 kΩ resistor in series with the base limits the drive current to under 1 mA – more than enough to drive the Darlington into saturation, i.e. the state where the collector-to-emitter voltage drop is at its lowest.

That’s it. Every 5 minutes, a reading arrives on the central JeeLink, as shown by JeeMon:

Drat, cloudy again! Oh well, just the usual gray November day…

## Using watchdog resets

In AVR, Hardware, Software on Nov 9, 2012 at 00:01

The Bluetooth readout node running the “smaRelay” code is ready to go:

As mentioned yesterday, I’ve decided to take the easy way out and completely power down the Bluetooth module and go through a full powerup/connect/readout cycle about once every 5 minutes.

The advantage for me of a battery-powered unit, is that I don’t have to locate this thing near a power outlet – it can be placed out of sight, unobtrusively doing its work.

I seem to have developed an allergy for power cables and wall warts all over the place…

The power on/off logic held a little surprise, about which I’ll report tomorrow.

Here’s is the new part of the updated smaRelay.ino sketch:

Quite a different use of the watchdog here:

• on powerup, go into low-power mode and wait for 5 minutes
• prepare the watchdog to perform a reset in 8 seconds
• power up Bluetooth, connect to the SMA, and read out some values
• then power down Bluetooth and power up the RFM12 radio
• send out a data packet over RF12
• lastly, turn the radio off and power down
• let the watchdog do the reset and make this sketch start over

This approach has as “benefit” that it’ll fail gracefully: even if anything goes wrong and things hang, the hardware watchdog will pull the ATmega out of that hole and restart it, which then starts off again by entering an ultra-low power mode for 5 minutes. So even if the SMA is turned off, this sketch won’t be on more than about 1% of the time.

Here’s the energy consumption measurement of an actual readout cycle:

The readings are a bit noisy – perhaps because I had to use 1 mV/div over a 1 Ω resistor (the 10 Ω used before interfered too much with this new power-switching code).

As you can see, the whole operation takes about 4 seconds. IOW, this node is consuming 153 milli-Coulombs every 300 seconds. That’s 0.5 mC/sec, or 0.5 mA on average. So the estimated lifetime on 3x AA 1900 mAh Eneloops is 3800 hours – some 5 months.

Update – The first set of batteries lasted until March 18th, 2013 – i.e. over 4 months.

Good enough for now. Deploy and forget. Onwards!

## Bluetooth power consumption

In Hardware on Nov 8, 2012 at 00:01

The Bluetooth module in yesterday’s setup has a nasty power consumption profile:

The yellow line is total power consumption, which to over 60 mA at times, and the smaRelay.ino sketch is querying the SMA inverter roughly every 10.5 seconds. The drop in baseline is the ATmega going to sleep as it waits for the next period, so you can clearly see what the Bluetooth module is doing – while kept on and connected to the SMA in fact.

I’m not sure that the Hameg’s math integral function is up to summing such fast-changing values, but it’s the best I’ve got to measure power consumption here at JeeLabs at the moment (well, either this or tracking the discharge on a hefty electrolytic capacitor).

Note the baseline consumption of about 5 mA, and the frequent but highly irregular brief power consumption pulses. That’s BT doing its frequency hopping thing, I assume.

Anyway, my goal was to get an estimate of the average power consumption, so here we go:

• two cursors were used to peg the integral (summed) value over one cycle
• charge usage over one 10.5 second period turns out to be 134 millicoulombs
• that’s 134 / 10.5 ≈ 12.75 mC per second, i.e. 12.75 mA average

Whoa… not much of a candidate for battery-power this way!

That leaves a couple of options:

• just power it via a USB adapter and move on
• explore the RN-42’s low-power mode, which is claimed to go as low as 300 µA
• completely turn off power to the RN-42

I’m inclined to go for the latter. I don’t really need solar PV readings that often, since the SMA accumulates its daily and total generated power anyway. And during the night, all this reading and reporting activity is also quite useless.

That would also solve – or rather: work around – the intermittent problems present in the current code, in which the sketch stops relaying after a few minutes. It always seems to get stuck after a while, waiting for incoming data from the Bluetooth module.

One readout every 10 minutes would probably be plenty for me, and since the SMA has a time-of-day clock which can be read out over BT, I can stop readouts during the night (or even simpler: add an LDR and switch off when it’s dark).

It looks like powering up, establishing a connection, and reading out one set of values can be done in under 6 seconds, so that leads to a 1% duty cycle. Let’s say 200 µA on average – this ought to run a year on 3x AA Eneloops.

Sometimes, sophisticated solutions are just distractions – whatever works, right?

## Verifying synchronisation over time

In AVR, Software on Nov 5, 2012 at 00:01

(Perhaps this post should be called “Debugging with a scope, revisited” …)

The syncRecv.ino sketch developed over the last few days is shaping up nicely. I’ve been testing it with the homePower transmitter, which periodically sends out electricity measurements over wireless.

Packets are sent out every 3 seconds, except when there have been no new pulses from any of the three 2000 pulse/kWh counters I’m using. So normally, a packet is expected once every second, but at night when power consumption drops to around 100 Watt, only every third or fourth measurement will actually lead to a transmission.

The logic I’m using was specifically chosen to deal with this particular case, and the result is a pretty simple sketch (under 200 LOC) which seems to work out surprisingly well.

How well? Time to fire up that oscilloscope again:

This is a current measurement, collected over about half an hour, i.e. over 500 reception attempts. The screen was set in 10s trace persistence mode (with “false colors” and “background” enabled to highlight the most recent traces and keep showing each one, so all the triggers are superimposed on one another.

These samples were taken with about 300 W consumption (i.e. 600 pulses per hour, one per 6s on average), so the transmitter was indeed skipping packets fairly regularly.

Here’s a typical single trigger, giving a bit more detail for one reception:

Lots of things one can deduce from these images:

• the mid-level current consumption is ≈ 8 mA, that’s the ATmega running
• the high-level current increases by another 11 mA for the RFM12B radio
• almost all receptions are within 8..12 ms
• most missing packets cause the receiver to stay on for up to some 18 ms
• on a few occasions, the reception window is doubled
• when that happens, the receiver can be on, but still no more than 40 ms
• the 5 ms after proper reception are used to send out info over serial
• the ATmega is on for less than 20 ms most of the time (and never over 50 ms)
• it looks like the longer receptions happened no more than 5 times

If you ignore the outliers, you can see that the receiver stays on well under 15 ms on average, and the ATmega well under 20 ms.

This translates to a 0.5% duty cycle with 3s transmissions, or a 200-fold reduction in power over leaving the ATmega and RFM12B on all the time. To put that in perspective: on average, this setup will draw about 0.1 mA (instead of 20 mA), while still receiving those packets coming in every 3 seconds or so. Not bad, eh?

There’s always room for improvement: the ATmega could be put to sleep while the radio is receiving (it’s going to be idling most of that time anyway). And of course the serial port debugging output should be turned off for real use. Such optimisations might halve the remaining power consumption – diminishing returns, clearly!

But hey, enough is enough. I’m going to integrate this mechanism into the homeGraph.ino sketch – and expect to achieve at least 3 months of run time on 3x AA (i.e. an average current consumption of under 1 mA total, including the GLCD).

Plenty for me – better than both my wireless keyboard and mouse, in fact.

## Predicting the next packet time

In AVR, Software on Nov 4, 2012 at 00:01

The problem described in the last post was caused by the receiver losing track of what the transmitter is doing when packets are missing.

Here are the key parts of an improved syncRecv.ino, with several refinements:

• on powerup, an estimate is chosen as before, using a few iterations
• we save the best estimate in EEPROM and reuse it after a restart
• the loop then switches to predicting the next arrivals each time
• failure to capture within 20 packets restarts a full estimation run
• every 4, 8, 12, etc lost packets, the window size is doubled (up to a maximum)
• on each successful capture, the window size is halved (down to a minimum)
• the cycle time estimate is averaged with a 6-fold smoothing filter

The estimation logic is roughly the same as before:

And here’s the main loop, with the rest of the logic described above:

The code will lock onto packets even when some of them are missing. It does so by simply ignoring the last miss, and predicting another packet again exactly one cycle later.

Here are some first results, illustrating synchronisation loss:

Still some rough spots, but this algorithm should receive properly with a < 1% on/off cycle.

In AVR, Software on Nov 3, 2012 at 00:01

Yesterday’s code has a nasty side-effect of getting into a corner out of which it almost can’t recover at times. Here’s a somewhat longer run, edited for brevity (note the indented lines):

On one occasion, it took 238 retries (12 minutes) to get back into sync!

Note how the code is sailing slightly too close to the edge, by always being at 0 or 1 ms from the expected time, just because this watchdog timer “happens” to run at a particular rate.

One fix is to gradually widen the window again when too many receptions in a row fail:

The other step is to always leave a bit more time when calculating a new estimate – it’s better to err on the side of receiving too early than to miss the start of the packet:

Whoops, looks like this doesn’t get it right – but it illustrates the widening:

This change works a lot better (i.e. plus 2, instead of minus 2):

Here’s the sample output:

The syncRecv code on GitHub has been updated with this tweak. More to come!

## Synchronised reception

In AVR, Software on Nov 2, 2012 at 00:01

That homeGraph setup brought out the need to somehow synchronise a receiver to the transmitter, as illustrated in a recent post. See also this forum discussion, which made me dive in a little deeper.

Let’s take a step back and summarise what this is this all about…

The basic idea is that if the transmitter is transmitting in a fixed cycle, then the receiver need not be active more than a small time window before and after the expected transmission. This might make it possible to reduce power consumption by two orders of magnitude, or more.

Here’s the initial syncRecv.ino sketch I came up with, now also added to JeeLib:

The idea is to turn the radio off for T – W milliseconds after a packet comes in, where T is the current cycle time estimate, and W the current +/- window size, and then wait for a packet to come in, but no later than T + W.

Each time we succeed, we get a better estimate, and can reduce the window size. Down to the minimum 16 ms, which is the granularity of the watchdog timer. For that same reason, time T is truncated to multiples of 16 ms as well. We simply cannot deal with time more accurately if all we have is the watchdog.

Here are some results from three different JeeNodes:

(whoops – the offset sign is the wrong way around, because I messed up the subtraction)

Note that for timing purposes, this sketch first waits indefinitely for a packet to come in. Since the transmitter doesn’t always send out a sketch, some of these measurement attempts fail – as indicated by multiple R’s.

That last example is a bit surprising: it was modified to run without powering down the radio in between reception attempts. What it seems to indicate is that reception works better when the radio is not put to sleep – not sure why. Or maybe the change in current consumption affects things?

As you can see, those watchdog timers vary quite a lot across different ATmega chips. These tests were done in about 15 minutes, with the sending sketch (and home power consumption levels) about the same during the entire period.

Still, these results look promising. Seems like we could get the estimates down to a few milliseconds and run the watchdog at its full 16 ms resolution. With the radio on less than 10 ms per 3000 ms, we’d get a 300-fold reduction in power consumption. Battery powered reception may be feasible after all!

## Debugging with a scope

In Hardware, Software on Oct 30, 2012 at 00:01

Good, but not perfect… I was curious about the actual current consumption of this latest version of the homeGraph.ino sketch. So here’s another timing snapshot:

This has trace persistence turned on, collecting multiple samples in one screen shot.

As you can see, the radio is turned on for ≈ 75 ms in this case (different JeeNode, slightly different watchdog timer period). Then after 30..35 ms the sketch goes to sleep again.

The second case is when nothing has been received after 150 ms: the “radioTimer” fires, and in this case the sketch turns off the radio as well, assuming there will be no packet coming in anymore.

But the interesting bit starts on the next packet coming in after one has been omitted. The logic in the code is such that the radio will be left on indefinitely in this case. As you can see, every late arrival then comes 100 ms later than expected: same radio-off + power down signature on the right-hand side of the screen capture, just much later.

Here is the code again:

And the main loop which calls this code:

That “if (!timingWasGood) …” code is probably wrong.

But it’s not so easy to fix, I’m afraid. Because the timing gets even more tricky if two or more packets are omitted, not just occasionally a single one. Sometimes, the radio doesn’t get switched off quickly – as you can see in this 30-minute capture at the end of the day, when power levels are starting to drop:

Maybe I need to try out a software PLL implementation after all. The other reason is that there seems to be a fair amount of variation in watchdog clock timing between different ATmega’s. For one, I had to use 2800 as value for recvOffTime, with another 3000 worked a lot better. A self-locking algorithm would solve this, and would let us predict the next packet time with even more accuracy.

But this is still good enough for now. Normally the radio will only be on for about 100 ms every 3s, so that’s a 30-fold power reduction, or about 0.6 mA on average for the radio.

This still ought to run for a month or two on a 3x AA battery pack, at least for daytime use. Which brings up another idea: turn the whole thing off when it’s dark – the display is not readable without light anyway.

Oh well. Perfection is the enemy of done.

## Final HomeGraph setup

In Hardware, Software on Oct 29, 2012 at 00:01

This concludes my little gadget to track home energy use and solar energy production:

The graph shows production vs total consumption in 15-minute intervals for the last 5 hours. A summary of this infomation is shown at the bottom: “+” is total solar production in the last 5 hours, “-” is total energy consumption in that same period.

The actual consumption values are not yet correct because the home energy pulse counter is wired incorrectly, but they will be once that is fixed. The total home consumption is currently 1327 – 1221 + 7 = 113W, since the home counter is currently driven in reverse.

The graph is auto-scaling and I’m storing these values in EEPROM whenever it scrolls, so that a power-down or reset from say a battery change will only lose the information accumulated in the last 15 minutes.

Power consumption is “fairly low”, because the backlight has been switched off and the radio is turned off between predicted reception times. The mechanism works quite well when there is a packet every 3 or 6 seconds, but with longer intervals (i.e. at night), the sketch still keeps the receiver on for too long.

A further refinement could be to reduce the scan cycle when there are almost no new pulses coming in – and then picking up again when the rate increases. Trouble is that it’s impossible to predict accurately when packets will be skipped, so the risk is that the sketch quickly goes completely out of sync when packet rates do drop. The PLL approach would be a better option, no doubt.

But all in all, I’m quite happy with the result. The display is reasonably easy to read in daylight, even without the backlight. I’ll do a battery-lifetime test with a fresh new battery once the pulse counter wiring has been fixed.

The code has become a bit long to be included in this post – it’s available as homeGraph on GitHub, as part of the GLCDlib project. I’m still amazed by how much a little 200-line program can do in just 11 KB of flash memory, and how it all ends up as a neat custom gadget. Uniquely tailored for JeeLabs, but it’s all open source and easy to adapt by anyone.

Feel free to add a light sensor, a PIR motion detector, an RTC, whatever…

Onwards!

## It’s all about timing – part 2

In Software on Oct 28, 2012 at 00:01

Yesterday’s optimisation was able to achieve an estimated 60-fold power consumption, by turning on the radio only when a packet is predicted to arrive, and going into a deep sleep mode for the rest of the time.

That does work, but the problem is that the sending node isn’t sending out a packet every 3 seconds. Sometimes no packet is sent because there is nothing to report, and sometimes a packet might simply be lost.

Yesterday’s code doesn’t deal with these cases. It merely waits after proper reception, because in that case the time to the next packet is known and predictable (to a certain degree of accuracy). If a packet is not coming in at the expected time, the sketch will simply continue to wait indefinitely with the radio turned on.

I tried to somewhat improve on this, by limiting the time to wait when a packet does not arrive, turning the radio off for a bit before trying again. But that turns out to be rather complex – how do you deal with uncertainty when the last known reception is longer and longer ago? We can still assume that the sender is staying in its 3s cycle, but: 1) the clocks are not very accurate on either end (especially the watchdog timer), and 2) we need a way to resync when all proper synchronisation is lost.

Here’s my modified loop() code:

And here’s the slightly extended snoozeJustEnough() logic:

Yes, it does work, some of the time – as you can see in this slow scope capture:

Four of those blips are working properly, i.e. immediate packet reception, drop in current draw, and then display update. Two of them are missed packets (probably none were sent), which are again handled properly by turning the receiver off after 150 ms, instead of waiting indefinitely.

But once that first packet reception fails, the next try will be slightly too late, and then the receiver just stays on for the full 3 seconds.

And that’s actually just a “good” example I picked from several runs – a lot of the time, the receiver just stays on for over a dozen seconds. This algorithm clearly isn’t sophisticated enough to deal with periodic packets when some of ’em are omitted from the data stream.

I can think of a couple of solutions. One would be to always send out a packet, even just a brief empty one, to keep the receiver happy (except when there is packet loss). But that seems a bit wasteful of RF bandwidth.

The other approach would be to implement a Phase Locked Loop in software, so that the receiver tracks the exact packet frequency a lot more accurately over time, and then gradually widens the receive window when packets are not coming in. This would also deal with gradual clock variations on either end, and if dimensioned properly would end up with a large window to re-gain “phase lock” when needed.

But that’s a bit beyond the scope of this whole experiment. The point of this demonstration was to show that with extra smarts in the receiving node, it is indeed possible to achieve low-power periodic data reception without having to keep the receiver active all the time.

Update – With the following timing tweak, everything works out a lot better already:

The receiver is now staying in sync surprisingly well – it’s time to declare victory!

In Software on Oct 27, 2012 at 00:01

The previous post showed that most of the power consumption of the homeGraph.ino sketch was due to the RFM12B receiver being on all the time. This is a nasty issue which comes back all the time with Wireless Sensor Networks: for ultra-low power scenarios, it’s simply impossible to keep the radio on at all times.

So how can we pick up readings from the new homePower.ino sketch, used to report energy consumption and production of the new solar panels?

The trick is timing: the homePower.ino sketch was written in such a way that it only sends out a packet every 3 seconds. Not always, only when there is something to report, but always exactly on the 3 second mark.

That makes it possible to predict when the next packet can be expected, because once we do receive a packet, we know that we don’t have to expect one for another 3 seconds. Aha, so we could turn the receiver off for a while!

It’s very easy to try this out. First, the code which goes to sleep:

The usual stuff really – all the hard work is done by the JeeLib library code.

And here’s the new loop() code:

In other words: whenever a packet has been received, process it, then go to sleep for 2.8 seconds, then wake up and start the receiver again.

Here’s the resulting power consumption timing, as voltage drop over a series resistor:

I can’t say I fully understand what’s going on, but I think it’s waiting for the next packet for about 35 ms with the receiver enabled (drawing ≈ 18 mA), and then another 35 ms is spent generating the graph and sending the new image to the Graphics Board over software SPI (drawing 7 mA, i.e. just the ATmega).

Then the µC goes to sleep, leaving just the display showing the data.

So we’re drawing about 18 mA for say 50 ms every 3000 ms – this translates to a 60-fold reduction in average current consumption, or about 0.3 mA (plus the baseline current consumption). Not bad!

Unfortunately, real-world use isn’t working out quite as planned… to be continued.

## Reducing power consumption

In Software on Oct 26, 2012 at 00:01

The problem with yesterday’s setup is power consumption:

There’s no way the sketch will run for a decent amount of time on just a single AA battery.

Let’s take some measurements:

• total power consumption on a 5V supply (via the USB BUB) is 20 mA
• total power consumption on 3.3V is almost the same: 19 mA
• the battery drain on the Eneloop at 1.28V is a whopping 95 mA

(the regulator on the AA board was selected for its low idle current, not max efficiency)

That last value translates to a run time of 20 hours on a fully charged battery. Fine for a demo, but definitely not very practical if this means we must replace batteries all the time.

Let’s try to reduce the power consumption of this thing – my favourite pastime.

The first obvious step is to turn off the Graphics Board backlight – a trivial change, since it can be done under software control. With the dark-on-light version of the GLCD this is certainly feasible, since that display is still quite readable in ambient light. But the net effect with a 5V power is that we now draw 16.5 mA … not that much better!

The real power consumer is the RFM12B module, which is permanently on. Turning it off drops the power consumption to 6.0 mA (with the Graphics Board still displaying the last values). And putting the ATmega to sleep reduces this even further, down to 0.5 mA. Now we’re cookin’ – this would last some 6 months on 3 AA batteries.

Except that this variant of the “homeGraph” sketch is next to useless: it powers up, waits for a packet, updates the display, and then goes to sleep: forever… whoops!

But maybe there’s a way out – stay tuned…

## Delayed power-up

In AVR, Hardware on Sep 9, 2012 at 00:01

To recall yesterday’s reasoning, I’m looking for a way to keep the RFM12B from starting up too soon and drawing 0.6 mA before the microcontroller gets a chance to enable it’s ultra-low power sleep mode.

The solutions so far require an extra I/O pin, allowing the microntroller to turn power on and off as needed, with the extra detail that power stays off until told otherwise.

But all I’m really interested in, is to keep that RFM12B from powering up too soon. After that, I never need to power it down again (and lose its settings) – at 0.3 µA, the RFM12B’s sleep mode will be just fine.

One solution is to use a dedicated chip for this, which can reliably send out a trigger when a fixed voltage threshold has been exceeded. That would still need a MOSFET, though, so this increases the cost (and footprint) of such a solution.

The other way would be to create a low-speed RC network, gradually charging a cap until a threshold is reached and turns on the MOSFET switch. Lower cost, no doubt, but in fact not flexible enough in case of a very slow power-on voltage ramp, as in the case of a solar cell charging a supercap or small battery. There is just no way to determine how long the delay needs to be – it might take days for the power rail to reach a usable level!

Yet another option is this little gem (thanks for the initial suggestion, Martyn!):

No I/O pin, no pull-up, nothing!

This trick takes advantage of what was originally considered a drawback of MOSFET switching: the fact that the gate voltage has to reach a certain level before the MOSFET will switch. Assuming that voltage is say 1.5V, then the MOSFET will be turned off as long as the power rail has not yet reached 1.5V, and once it rises above that value, it’ll automatically switch on. Magic!

Does it work? Well, I’m still waiting for some P-MOSFETs to arrive, but I’ve done a little test with an N-MOSFET, connected the other way around and using a 1 kΩ resistor as load. We can look at that combination as a component which has only two pins: a power rail and ground.

If the circuit works as expected, then when applying an increasing voltage, no current will flow until the threshold has been reached, and then it’ll switch on and start drawing current.

As it turns out, this is very easily observable using a Component Tester – like the one built into my scope:

The horizontal scale is the applied voltage (from about -5V to +5V), the vertical scale is the current through that component (from about -5 mA to +5 mA). The straight slanted line is characteristic of a 1 kΩ resistor.

But the interesting bit is that little dent: from under 0V to about 1.5V, the circuit draws no current at all. Once 1.5V or more are applied, the circuit starts conducting, and behaving like a plain 1 kΩ resistor again.

Woohoo, this might actually work: just a single P-MOSFET would be all that’s needed!

## Switching with a P-MOSFET

In AVR, Hardware on Sep 8, 2012 at 00:01

One reason for yesterday’s exploration, is to figure out a way around a flaw of the RFM12B wireless radio module.

Let me explain – the RFM12B module has a clock output, which can be used to drive a microcontroller. The idea being that you can save a crystal that way. Trouble is that this clock signal has to be present on power-up, even though it can be configured over SPI in software, because otherwise the microcontroller would never start running and hence never get a chance to re-configure the radio. A nasty case of Catch 22 (or a design error?).

In short: the radio always powers up with the crystal oscillator enabled. Even when not using that clock signal!

The problem is that an RFM12B draws about 0.6 mA in this mode, even though it can be put to sleep to draw only 0.3 µA (once running and listening to SPI commands). In the case of energy harvesting, where you normally get very tiny amounts of energy to run off, this startup hurdle can be a major stumbling block.

See my low-power supply weblog post about how hard that can be, and may need extra hardware to get fixed.

So I’m trying to find a way to keep that radio powered down until the microcontroller is running, allowing it to be put to sleep right away.

For ultra-low power use, yesterday’s PNP transistor approach is not really good enough.

This is where an interesting aspect of MOSFETs comes in: they make great power switches, because all they need is a gate voltage to turn them on or off. When on, their resistance (and hence voltage drop) is near zero, and the voltage on the gate doesn’t draw any current. Just like a water faucet doesn’t consume energy to keep water running or blocked, only to change the state – so do MOSFETs.

But many MOSFETs typically require several volts to turn them on, which we may or may not have when running at the lower limit of 1.8V of an ATmega or ATtiny. So the choice of MOSFET matters.

Just like yesterday, we’ll need a P-channel MOSFET to let us switch the power supply rail:

Note the subtly different placement of the resistor. With a PNP transistor, it was needed to limit the current through the base (which then got wasted, but that current is needed to make the transistor switch). With a MOSFET there is no current, but now we need to make sure that the MOSFET stays off until a low voltage is applied.

Except that now R can be very large. It’s basically a pull-up, and can be extremely weak, say 10 MΩ. That means that when pulled low, the leakage current will be only 0.3 µA.

The trick is to find a P-MOSFET type which can switch using a very low gate voltage, so that it can still be fully switched on. I’ve ordered a couple of types to test this out, and will report once they arrive and measurements can be made.

All in all, this is a very nice solution, though – just 2 very simple components. The main drawback is that we still need to reserve an I/O pin for this.

Tomorrow, I’ll explore a refinement which does not even need an extra I/O pin.

## Low power – µA’s in perspective

In AVR, Hardware on Jun 23, 2012 at 00:01

Ultra-low power computing is a recurring topic on this weblog. Hey – it’s useful, it’s non-trivial, and it’s fun!

So far all the experiments, projects, and products have been with the ATmega from Atmel. It all started with the ATmega168, but since some time it’s now all centered around the ATmega328P, where “P” stands for pico power.

There’s a good reason to use the ATmega, of course: it’s compatible with the Arduino and with the Arduino IDE.

With an ATmega328 powered by 3.3V, the lowest practical current consumption is about 4 µA – that’s with the watchdog enabled to get us back out of sleep mode. Without the internal watchdog, i.e. if we were to rely on the RFM12B’s wake-up timer, that power-down current consumption would drop considerably – to about 0.1 µA:

Whoa, that’s a factor 40 less! Looks like a major battery-life improvement could be achieved that way!

As always, the answer is a resounding “that depends” – because there are other power consumers involved, and you have to look at the whole picture to understand the impact of all these specs and behaviors.

First of all, let’s assume that this is a transmit-only sensor node, and that it needs to transmit once a minute. Let’s also assume that sending a packet takes at most 6 ms. The transmitter power consumption is 25 mA, so we have a 10,000:1 sleep/send ratio, meaning that the average current consumption of the transmitter will be 2.5 µA.

Then there’s the voltage regulator. In some scenarios, it could be omitted – but the MCP1702 and MCP1703 used on JeeNodes were selected specifically for their extremely low quiescent current draw of 2 µA.

The RFM12B wireless radio module itself will draw between 0.3 µA and 2.3 µA when powered down, depending on whether the wake-up timer and/or the low-battery detector are enabled.

That’s about 5 to 7 µA so far. So you can see that a 0.1 µA vs 4 µA difference does matter, but not dramatically.

I’ve been looking at some other chips, such as ATXmega, PIC, MSP430, and Energy Micro’s ARM. It’s undeniable that those ATmega328’s are really not the lowest power option out there. The 8-bit PIC18LF25K22 can keep its watchdog running with only 0.3 µA, and the 16-bit MSP430G2453 can do the same at 0.5 µA. Even the 32-bit ARM EFM32TG110 only needs 1 µA to keep an RTC going. And they add lots of other really neat extra features.

In terms of low power there are at two more considerations: other peripherals and battery size / self-discharge.

In a Room Node, there’s normally a PIR sensor to detect and report motion. By its very nature, such a sensor cannot be shut off. It cannot even be pulsed, because a PIR needs a substantial amount of time to stabilize (half a minute or more). So there’s really no other option than to keep it powered on at all times. Well, perhaps you could turn it off at night, but only if you really don’t care what happens then :)

Trouble is: most PIR sensors draw a “lot” of current. Some over 1 mA, but the most common ones draw more like 150..200 µA. The PIR sensor I’ve found for JeeLabs is particularly economical, but it still draws 50..60 µA.

This means that the power consumption of the ATmega really becomes almost irrelevant. Even in watchdog mode.

The other variable in the equation is battery self-discharge. A modern rechargeable Eneloop cell is quoted as retaining 85% of its charge over 2 years. Let’s assume its full charge is 2000 mAh, then that’s 300 mAh loss over 2 years, which is equivalent to about 17 µA of continuous self-discharge.

Again, the 0.1 µA vs 4 µA won’t really make such a dramatic difference, given this figure. Definitely not 40-fold!

As you can see, every microamp saved will make a difference, but in the grand scheme of things, it won’t double a battery’s lifetime. There’s no silver bullet, and that Atmel ATmega328 remains a neat Arduino-compatible option.

That doesn’t mean I’m not peeking at other processors – even those that don’t have a multi-platform IDE :)

## Low-power waiting – interrupts

In AVR, Hardware on Jun 17, 2012 at 00:01

Following yesterday’s trial, here is the code which uses the pin-change interrupt to run in a continuous cycle:

The main loop is empty, since everything now runs on interrupts. The output signal is the same, so it’s working.

Could we somehow increase the cycle frequency, to get a higher time resolution? Sure we can!

The above code discharges the cap to 0V, but if we were to discharge it a bit less, it’d reach that 1.66V “1” level more quickly. And sure enough, changing the “50” loop constant to “10” increase the rate to 500 Hz, a 2 ms cycle:

As you can see, the cap is no longer being discharged all the way to 0V. A shorter discharge cycle than this is not practical however, since the voltage does need to drop to a definite “0” level for this whole “cap trick” to work.

So how do we make this consume less power? Piece of cake: turn the radio off and go to sleep in the main loop!

The reason this works, is that the whole setup continuously generates (and processes) pin-change interrupts. As a result, this JeeNode SMD now draws about 0.23 mA and wakes up every 2 ms using nothing more than a single 0.1 µF cap tied to an I/O pin. Mission accomplished – let’s declare (a small) victory!

PS. Exercise for the reader: you could also use this trick to create a simple capacitance meter :)

## Low-power waiting

In AVR, Hardware on Jun 16, 2012 at 00:01

This continues where yesterday left off, trying to wait less than 16 milliseconds using as little power as possible.

First off, I’m seeing a lot of variation, which I can’t explain yet. I decided to use a standard JeeNode SMD, including regulator and RFM12B radio, since that will be closer to the most common configuration anyway.

Strangely enough, this sketch now generates a 704 µS toggle time instead of 224 µs, i.e. 44 processor cycles per loop() iteration. I don’t know what changed since yesterday, and that alone is a bit worrying…

The other surprise is that power consumption varies quite a bit between different units. On one JN SMD, I see 1.35 mA, on another it’s only 0.86 mA. Again: I have no idea (yet) what causes this fairly substantial variation.

How do we reduce power consumption further? The watchdog timer is not an option for sleep times under 16 ms.

The key point is to find some suitable interrupt source, and then go into a low-power mode with all the clock/timing circuitry turned off (in CMOS chips, most of the energy is consumed during signal transitions!).

Couple of options:

1. run the ATmega off its internal 8 MHz RC clock and add a 32 KHz crystal
2. add extra circuitry to generate a low-frequency pulse and use pin-change interrupts
3. connect the RFM12B’s clock pin to the IRQ pin and use Timer 2 as divider
4. add a simple RC to an I/O pins and interrupt on it’s charge cycle
5. use the RFM12B’s built-in wake-up timer – to be explored in a separate weblog post

Option 1) has as drawback that you can’t run with standard fuse settings anymore: the clock will have to be the not-so-accurate 8 MHz RC clock and the crystal oscillator needs to be set appropriately. It does seem like this would allow short-duration low-power waiting with a granularity of ≈ 30 µs.

Option 2) needs some external components, such as perhaps a low-power 7555 CMOS timer. This would probably still consume about 0.1 mA – pretty low, but not super-low. Or maybe a 74HC4060, for perhaps 0.01 mA (10 µA) power consumption.

Option 3) may sound like a good idea, since Timer 2 can run while the rest of the ATmega’s clock circuits are switch off. But now you have to keep the RFM12B’s 10 MHz crystal running, which draws 0.6 mA … not a great improvement.

Option 4) seems like an option worth trying. The idea is to connect these components to a spare I/O pin:

By pulling the I/O pin low as an output, the capacitor gets discharged. When turning the pin into a high-impedance input, the cap starts charging until it triggers a transition from a “0” to a “1” input, which could be used as pin-change interrupts. The resistor value R needs to be chosen such that the charge time is near to what we’re after for our sleep time, say 1 millisecond. Longer times can then be achieved by repeating the process.

It might seem odd to do all this for what is just one thousandths of a second, but keep in mind that during this time the ATmega can be placed in deep-sleep mode, consuming only a few µA’s. It will wake up quickly, and can then either restart another sleep cycle or resume its work. This is basically the same as a watchdog interrupt.

Let’s first try this using the internal pull-up resistor instead, and find out what sort of time delays we get:

(several typo’s: the “80 µs” comment in the above screen shot should be “15 µs” – see explanation below)

This code continuously discharges the 0.1 µF capacitor connected to DIO1, then waits until it charges up again:

With the internal pull-up we get a 3.4 ms cycle time. By adding an extra external resistor, this could be shortened. The benefit of using only the internal pull-up, is that it also allows us to completely switch off this circuit.

We can see that this ATmega switches to “1” when the voltage rises to 1.66V, and that its internal pull-up resistor turns out to be about 49 kΩ (I determined this the lazy way, by tweaking values on this RC calculator page).

Note that discharge also takes a certain amount of time, i.e. when the output pin is set to “0”, we have to keep it there a bit. Looks like discharge takes about 15 µs, so I adjusted the asm volatile (“nop”) loop to cycle 50 times:

In other words, this sketch is pulling the IO pin low for ≈ 15 µs, then releases it and waits until the internal pull-up resistor charges the 0.1 µF capacitor back to a “1” level. Then this cycle starts all over again. Easy Peasy!

So there you have it: a single 0.1 µF capacitor is all it takes to measure time in 3.4 µs ms increments, roughly. Current consumption should be somewhat under 67 µA, i.e. the current flowing through a 49 kΩ resistor @ 3.3V.

Tomorrow, I’ll rewrite the sketch to use pin-change interrupts and go into low-power mode… stay tuned!

## Waiting without the watchdog

In AVR, Hardware on Jun 15, 2012 at 00:01

The watchdog timer in the ATmega has as shortest interval about 16..18 milliseconds. Using the watchdog is one of the best ways to “wait” without consuming much power: a fully powered ATmega running at 16 MHz (and 3.3V) draws about 7 mA, whereas it drops thousandfold when put to sleep, waiting for the watchdog to wake it up again.

The trouble is: you can’t wait less than that minimum watchdog timer cycle.

What if we wanted to wait say 3 ms between transmitting a packet and turning on the receiver to pick up an ACK?

Short time delays may also be needed when doing time-controlled transmissions. If low power consumption is essential, then it becomes important to turn the transmitter and receiver on at exactly the right time, since these are the major power consumers. And to wait with minimal power consumption in between…

One approach is to slow down the clock by enabling the built-in pre-scaler, but this has only a limited effect:

The loop toggles an I/O bit to allow verification of the reduced clock rate. The above code draws about 1.6 mA, whereas the same code running at full speed (16 MHz) draws about 8.8 mA. Note that these measurements ended up a bit lower, but that was as 3.3V – I’m running from a battery pack in these tests, i.e. at about 4.0V.

The I/O pin toggles at 2.23 KHz in slow mode, vs 573 KHz at full speed, which indicates that the system clock was indeed running 256 times slower. A 2.23 KHz rate is equivalent to a 224 µs toggle cycle, which means the system needs 14 processor cycles (16 µs each) to run through this loop() code. Most of it is the call/return stack overhead.

So basically, we could now wait a multiple of 16 µs while consuming about 1.6 mA – that’s still a “lot” of current!

Tomorrow, I’ll explore ways to reduce this power consumption further…

## Boost revisited

In Hardware on Jun 4, 2012 at 00:01

The AS1323 boost converter mentioned a while back claims an extra-ordinarily low 1.65 µA idle current when unloaded. At the time, I wasn’s able to actually verify that, so I’ve decided to dive in again:

A very simple circuit, but still quite awkard to test, due to its size:

Bottom right is incoming power, bottom left is boosted 3.3V output voltage. Input voltage is 1.65V for easy math.

The good news is that it works, and it shows me an average current draw of 4.29 µA:

The yellow line is the output voltags, with its characteristic boost-decay cycle. For reference: the top of the graph is at 3.45V, so the output voltage is roughly between 3.30 and 3.36V (it rises a bit with rising supply voltage).

The blue line is the voltage over a resistor inserted between supply ground and booster ground. I’m using 10 Ω, 100Ω, or 1 kΩ, depending on expected current draw (to avoid a large burden voltage). So this is the input current.

The red line is the accumulated current, but it’s not so important, since the scope also calculates the mean value.

Note that there’s some 50 Hz hum in the current measurement, and hence also in its integral (red line).

Aha! – and here’s the dirty little secret: the idle current is specified in terms of the output voltage, not the input voltage! So in case of a 1.65V -> 3.3V idle setup, you need to double the current (since we’re generating it from an input half as large as the 3.3V out), and you need to account for conversion losses!

IOW, for 100% efficiency, you’d expect 1.6 µA * (3.3V / 1.65V) = 3.2 µA idle current. Since the above shows an average current draw of 4.29 µA, this is about 75% efficient.

Not bad. But not that much better than the LTC3525 used on the AA Power Board, which was ≈ 20 µA, IIRC.

More worrying is the current draw when loaded with 10 µA, which is more similar to what a sleeping JeeNode would draw, with its wireless radio and some sensors attached:

Couple of points to note, before we jump to conclusions: the boost regulator is now cycling at a bit higher frequency of 50 Hz. Also, I’ve dropped the incoming voltage to a more realistic 1.1V, i.e. 1/3rd of the output.

With a perfect circuit, this means the input current should be around 30 µA, but it ends up being about 52 µA, i.e. 57% efficiency. I have no idea why the efficiency is so low, would have expected about 70% from the datasheet.

Further tests with 1.65V in show that 1 µA out draws 6.72 µA, 10 µA out draws 29.6 µA, 100 µA out draws 261 µA, 1 mA out draws 2.51 mA, and 10 mA out draws 30.9 mA. Not quite the 80..90% efficiency from the datasheet.

My hunch is that the construction is affecting optimal operation, and that better component choices may need to be made – I just grabbed some SMD caps and a 10 µH SMD inductor I had lying around. More testing needed…

For maximum battery life, the one thing which really matters is the current draw while the JeeNode is asleep, since this is the state it spends most of its time in. So minimal consumption with 5..10 µA out is what I’m after.

To keep things in perspective: 50 µA average current drawn from one 2000 mAh AA cell should last over 4 years. A JeeNode with Room Board & PIR (drawing 50 µA, i.e. 200 µA from the battery) should still last almost a year.

Update – when revisiting the AA Power Board, I now see that it uses 25 µA from 1.1V with no load, and 59 µA with 10 µA load (down to 44 µA @ 1.5V in). The above circuit works (but does not start) down to 0.4V, whereas the AA Power Board works down to 0.7V – low voltages are not really that useful, since they increase the current draw and die quickly thereafter. Another difference is that the above circuit will work up to 2.3V (officially only 2.0V), and the AA Power Board up to at least 6V (which is out of spec), switching into step-down mode in this case.

In AVR, Hardware, Software on May 29, 2012 at 00:01

When running off solar power, ya’ gotta deal with lack of (sun-) light…

As shown in a recent post, a 0.47F supercap appears to have enough energy storage to get through the night, at least when assuming that the day before was sunny and that the nights are not too long.

There are still a couple of issues to solve. One which I won’t go into yet, is that the current approach won’t start up properly when there is only a marginal power budget to begin with. That’s a hard problem – some other time!

But another tactic to alleviate this problem, is to try and sail through a low-power situation by reducing power consumption until (hopefully) more energy becomes available again, later on.

Here’s my first cut at implementing a “survival strategy”, using the radioBlip2 sketch:

It’s all in the comments, really: when power is low, try to avoid sending packets, since turning on the transmitter is by far the biggest power “hog”. And when power is really low, don’t even measure VCC – just slow down even more in maximally efficient sleep mode – I’ve set the times to 5 and 60 minutes. The 1-hour sleep being a last effort to get through a really rough night…

But I’ve also added some kamikaze logic: when running low, you don’t just want the sketch to go into sleep mode more and more and finally give up without having given any sign of life. So instead, when the sketch is about to decide whether it should send a packet again, it checks whether the voltage is really way too low after what was supposedly a long deep-sleep period. If so, and before power runs out completely, it will try to send out a packet anyway, in the knowledge that this might well be its last good deed. That way, the central node might have a chance to hear this final swan song…

The thresholds are just a first guess. Maybe there are better values, and maybe there is a better way to deal with the final just-about-to-die situation. But for now, I’ll just try this and see how it goes.

One last point worth mentioning: all the nodes running this sketch can use the same group and node ID, because they are transmit-only. There is never a need to address packets sent towards them. So the BLIP_ID inside the payload is a way to still disambiguate incoming packets and understand which exact node each one came from.

Re-using the same node ID is useful in larger setups, since the total number of IDs in a group is limited to 30.

I’ll do some tests with the above logic. Let’s hope this will keep nodes alive in long and dark winter days nights.

## Through the night on a supercap!

In Hardware on May 26, 2012 at 00:01

Yeay! – The JeeNode made it through the night on a 0.47F supercap, for the first time ever at JeeLabs:

Sorry for the awkward / missing scale, here’s some context:

• vertical is voltage: 50 = 2V, 100 = 3V, 150 = 4V, 200 = 5V
• blue is VCC before sending, green is VCC after sending
• graph runs from 11:45 yesterday to 10:45 the next morning, i.e. 23 hours
• that’s two VCC measurements and one packet transmission every minute

The supercap had been charged by the solar cell for 3 days, no load. When connecting the JeeNode (BOD set to 1.8V, on-board 100 µF i.s.o. regulator, already running), I placed it in a cardboard box to block out the light:

• the first upward blip is at 12:45, during 5 minutes of exposure to sunlight
• then back into the box until 18:30, depleting the supercap for a few hours
• after that, the node was kept in the light to try and charge up enough for the night
• at 20:00, the charge had gone up to 4.42V and 3.86V, respectively
• at around 6:30 the next morning, the lowest point was reached: 3.44V and 2.88V
• from then on, the cell started charging again from the morning light (no direct sunlight yet)
• looks like about 10% of the packets never arrived (probably mostly due to collisions)

At noon, the cap voltage had risen to 4.9V (note that the RFM12B is now operating above its official 3.8V max).

So there you have it: one packet per minute powered by solar energy, harvested indoor near a window.

Update – FWIW, this setup lasted a second day, but then it died again… we’re not done yet!

## New solar setup

In Hardware on May 15, 2012 at 00:01

Time for another experiment, this time combining my small solar panel with the 3.4 mAh Lithium battery which seems to work so well. The circuit I’m going to try is as follows:

Here’s the construction, cozily attached to the back of the solar cell:

Same solar cell, I think it can supply up to 4.5V @ 1 mA in full sunlight.

The tricky bit is that the rechargable lithium cell needs to be treated with care. For maximum life, it needs to be hooked up to a voltage source between 2.8V and 3.2V, and the charge current has to be limited.

Note that the 1 kΩ resistor is put in series with the battery not only to charge it, but also when taking charge out of it. Seems odd, but that’s the way the datasheet and examples show it. Then again, with a 10 µA current draw the voltage drop and losses are only about 10 mV. A diode bypass could be added later, if necessary.

The diode after the regulator has the nice effect of dropping the 3.3V output to an appropriate value, as well as blocking all reverse current flow. There is no further circuitry for the regulator, since I don’t really care what it does when there is too much or too little power coming from the solar cell. Let’s assume it’s stable without caps.

It all looks a bit wasteful, i.e. linearly regulating the incoming voltage straight down to 3.3V regardless of PV output levels and discarding the excess. But given that this little 3V @ 3.4 mAH battery has already supported a few days of running time when fully charged, maybe it’s still ok.

I’ll let this charge for a day or two.

## Watching it go down

In AVR, Hardware, Software on May 13, 2012 at 00:01

Now that there’s low-power vccRead() code to measure the current power supply voltage, we can finally get a bit more valuable info from the radioBlip sketch, which sends out one packet per minute.

So here’s a new radioBlip2 sketch which combines both functions. To support more test nodes, I’m adding a byte to the payload for a unique node ID, as well as a byte with the measured voltage level:

As a quick test I used a JeeNode without regulator, running off an electrolytic 1000 µF cap, charged to 5V via a USB BUB, and then disconnected (this is running the RFM12B module beyond its 3.8V max specs, BTW):

Here’s a dump of the received packets:

``````    L 16:56:32.032 usb-A600dVPp OK 17 1 0 0 0 1 209
L 16:57:35.859 usb-A600dVPp OK 17 2 0 0 0 1 181
L 16:58:39.543 usb-A600dVPp OK 17 3 0 0 0 1 155
L 16:59:43.029 usb-A600dVPp OK 17 4 0 0 0 1 134
L 17:00:46.323 usb-A600dVPp OK 17 5 0 0 0 1 115
L 17:01:49.431 usb-A600dVPp OK 17 6 0 0 0 1 98
L 17:02:52.314 usb-A600dVPp OK 17 7 0 0 0 1 82
L 17:03:55.016 usb-A600dVPp OK 17 8 0 0 0 1 66
L 17:04:57.526 usb-A600dVPp OK 17 9 0 0 0 1 50
``````

Or, more graphically, as voltage – showing 8 minutes before the sketch runs out of juice:

This consumes only marginally more power than without the VCC measurements: the original radioBlip sketch lasted 1 minute longer under similar conditions, i.e. one extra packet transmission.

## Improved VCC measurement

In AVR, Software on May 12, 2012 at 00:01

As shown in this post, it is possible to read out the approximate level of VCC by comparing the internal 1.1 V bandgap with the current VCC level.

But since this is about tracking battery voltage on an ultra-low power node, I wanted to tinker with it a bit further, to use as little energy as possible when making that actual supply voltage measurement. Here’s an improved bandgap sketch which adds a couple of low-power techniques:

First thing to note is that the ADC is now run in noise-canceling-reducing mode, i.e. a special sleep mode which turns off part of the chip to let the ADC work more accurately. With as nice side-effect that it also saves power.

The other change was to drop the 250 µs busy waiting, and use 4 ADC measurements to get a stable result.

The main delay was replaced by a call to loseSomeTime() of course – the JeeLib way of powering down.

Lastly, I changed the sketch to send out the measurement results over wireless, to get rid of the serial port activity which would skew the power consumption measurements.

Speaking of which, here is the power consumption during the call to vccRead() – my favorite graph :)

As usual, the red line is the integral of the current, i.e. the cumulative energy consumption (about 2300 nC).

And as you can see, it takes about 550 µs @ 3.5 mA current draw to perform this battery level measurement. The first ADC measurement takes a bit longer (25 cycles i.s.o. 13), just like the ATmega datasheet says.

The total of 2300 nC corresponds to a mere 2.3 µA average current draw when performed once a second, so it looks like calling vccRead() could easily be done once a minute without draining the power source very much.

The final result is pretty accurate: 201 for 5V and 147 for a 4V battery. I’ve tried a few units, and they all are within a few counts of the expected value – the 4-fold ADC readout w/ noise reduction appears to be effective!

## Not long enough

In Hardware on May 9, 2012 at 00:01

My second solar setup did not fare well:

Started during the day, with the supercap charged up in bright daylight behind a window, it was able to power the JeeNode for about 16 hours – and then in the middle of the night it gave up:

``````    L 02:36:44.743 usb-A600dVPp OK 17 30 4 0 0
L 02:37:48.074 usb-A600dVPp OK 17 31 4 0 0
L 02:38:51.402 usb-A600dVPp OK 17 32 4 0 0
L 02:39:54.725 usb-A600dVPp OK 17 33 4 0 0
``````

Times are in UTC and we’re in the CEST time zone, so this was two hours later – i.e. around 4:30 AM.

I left it there for another few days, but unfortunately once dead this setup never recovers. The main reason for this is probably that the RFM12B starts up in a very power hungry mode (well, relatively speaking anyway) with a 0.6 mA current consumption – because it starts with the crystal oscillator enabled.

Maybe the self-leakage of the supercap was still too high, and would be (much) lower after a few days in the mostly-charged state, so I’m not ruling out using supercaps just yet. But as it stands, not getting through even a single night is not good enough – let alone being used in darker spots or on very dark winter days.

More experimentation needed!

## How low can it go?

In AVR, Hardware on May 7, 2012 at 00:01

While experimenting with various alternate power sources for a JeeNode, I was curious as to just how low it could go in terms of voltage and still function as a simple wireless transmit node.

Made the following mods to push things a bit more than usual:

• adjusted the fuses to set the brownout level to 1.8V iso 2.7V (efuse: 0x06)
• changed the RFM12B’s low-battery level to 2.2V iso 3.1V (rf12_control: 0xC040)
• removed the voltage regulator from a JeeNode, and keep just the electrolytic cap
• changed the radioBlip sketch to run at 8 MHz, i.e. 16 MHz clock % 2

This is the same setup as with the Tiny Lithium discharge setup described a few days ago, BTW.

Here’s the JeeNode-under-test (JUT?) – the cap I used here is again 100 µF:

One pair of wires is from the power supply, the other from the multimeter.

And then it’s just a matter of hooking it up to a power supply and gradually lowering the supply voltage.

And the result is … 3.0, 2.9, 2.8, 2.7, 2.6, 2.5, 2.4, 2.3, 2.2, 2.1, 2.0, 1.9, 1.85 Volt still works!

Anything lower than that and the sketch stops sending out packets once a minute – but then again, that’s probably just the brownout detector of the ATmega kicking in!

To get it back up, I re-connected the power supply at 2.1 V and the node started its blips again… lower didn’t work, my hunch is that the RFM12B’s clock circuit needs that slightly higher voltage level to start oscillating.

## Measuring VCC via the bandgap

In AVR, Hardware, Software on May 4, 2012 at 00:01

The ATmega’s (and ATtiny’s for that matter) all have a 10-bit ADC which can be used measure analog voltages. These ADC’s are ratiometric, meaning they measure relative to the analog reference voltage (usually VCC).

On a 5V Arduino, that means you can measure 0..5V as 0..1023, or roughly 5 mV per step.

On a 3.3V JeeNode, the measurements are from 0 to 3.3V, or roughly 3.3 mV per step.

There’s no point connecting VCC to an analog input and trying to measure it that way, because no matter what you do, the ADC readout will be 1023.

So can we figure out what voltage we’re running at? This would be very useful when running off batteries.

Well, there is also a “bandgap reference” in each ATmega/ATtiny, which is essentially a 1.1V voltage reference. If we read out that value relative to our VCC, then a little math will do the trick:

• suppose we read out an ADC value “x” which represents 1.1V
• with 5V as VCC, that value would be around 1100 / 5000 * 1023 = 225
• whereas with 3.3V as VCC, we’d expect a reading of 1100 / 3300 * 1023 = 341
• more generally, 1100 / VCC * 1023 = x
• solving for VCC, we get VCC = 1100 / x * 1023

So all we have to do is measure that 1.1V bandgap reference voltage and we can deduce what VCC was!

Unfortunately, the Arduino’s analogRead() doesn’t support this, so I’ve set up this bandgap demo sketch:

Sample output, when run on a JeeNode SMD in this case:

There’s a delay in the vccRead() code, which helps stabilize the measurement. Here’s what happens with vccRead(10) – i.e. 10 µs delay instead of the default 250 µs:

Quite different values as you can see…

And here’s the result on an RBBB with older ATmega168 chip, running at 5V:

I don’t know whether the 168’s bandgap accuracy is lower, but as you can see these figures are about 10% off (the supply voltage was measured to be 5.12 V on my VC170 multimeter). IOW, the bandgap accuracy is not great – as stated in the datasheet, which specifies 1.0 .. 1.2V @ 25°C when VCC is 2.7V. Note also that the bandgap reference needs 70 µs to start up, so it may not immediately be usable when coming out of a power-down state.

Still, this could be an excellent way to predict low-battery conditions before an ATmega or ATtiny starts to run out of steam.

## Trying to measure capacitor leakage

In Hardware on Apr 7, 2012 at 00:01

Capacitors have a “leakage current”, i.e. when you charge them up fully, the leakage current will cause them to slowly lose that charge. I was wondering about this in the context of an ultra-low power JeeNode, which has a 10 µF buffer cap right after the voltage regulator. Does its leakage affect battery lifetimes?

Time to do a quick test – I used the 47 µF 25V cap included with JeeNode kits these days:

So how do you measure leakage currents, which are bound to be very small at 3.3V? Well, you could charge up the cap and then insert a multimeter in series in its most sensitive range. This multimeter goes down to 0.1 µA resolution, although its accuracy is specified as 1.6 % + 5 digits, so the really low values aren’t very precise.

A simpler way is to use the RC time constant as a basis. The idea is that a real-world cap can be treated like a perfect cap (which would keep its charge forever) plus a resistor in parallel. That resistor merely “happens” to be situated inside the cap.

What I did was charge the cap from a 3x AA battery pack which was just about 4.0V, then disconnect the battery and watch the discharge on the oscilloscope:

As you can see, it took 500 seconds for the charge in the capacitor to drop by some 2.5V – note the exponential decay, which matches the assumption that the leakage comes from a fixed resistance.

Can we derive the leakage from this? Sure we can!

The formula for RC discharge is:

``````    T = R x C
``````

Where T (in seconds) is the time for the cap to discharge by 63.2 percent, R is the discharge resistor (in ohms), and C is the capacitor size (in farads).

Above, it took 500 seconds to drop from 3.98 V to 1.48 V, which by pure accident is almost exactly 63.2 %, so T = 500 and C = 0.000,047 – giving us all the info needed to calculate R = 500 / 0.000,046 = 10638298 ≈ 10.6 MΩ.

Using ohm’s law (E = I x R), that means the leakage current at the start is 4 V / 10.6 MΩ = 0.376 µA.

The good news is that such a result would not be of any concern with ultra-low power JeeNodes – the regulator + ATmega + RFM12B use an order of magnitude more than that, even when powered down.

But the bad news is that this result is in fact completely bogus: to measure the charge, I placed the oscilloscope probe over the cap, and it happens to have 10 MΩ internal resistance itself. So basically the entire discharge behavior shown above was caused by the probe i.s.o. the capacitor’s own leakage!

So it looks like I’ll need a different setup to measure real leakage, which is probably in the nanoamp range…

## 75 days and counting

In AVR, Hardware on Mar 30, 2012 at 00:01

The JeeNode Micro based on the ATtiny84 is getting more and more use around here. One of the ways it can be powered is via a CR2032 coin cell on its back:

I’ve got one with the radioBlip sketch running here, to see how long it will last on a single coin cell.

Well… today it passed the 75-day mark – celebration time!

Onwards!

## Can’t be done

In Hardware on Jan 27, 2012 at 00:01

As you may know from posts a short while ago, I’ve been working on creating an ultra-low power supply, providing just enough energy to a JeeNode or JeeNode Micro to let it do a little work, report some data over wireless, and then go to sleep most of the time.

I even designed a PCB for this thing and had a bunch of them produced:

The good news is that it works as intended and that I’ll be using this circuit for some projects.

The bad news is that they won’t be available as kits in the shop. Ironically, this was the first time where I actually had a batch of kits all wrapped up and ready to go, ahead of time.

But the reality is that I can’t pull it off. For two different reasons:

• The circuit is connected to live AC mains @ 230 VAC and that means there is a serious risk if you build this stuff, try it out, and then hurt yourself because of some mistake. And even after that, there is the risk that the whole circuit is not properly protected, exposing these voltages (even just humidity and condensation).

• The other risk is that once everything works, it gets built-in for permanent use and becomes part of your house. What if it gets wet or malfunctions for some other reason, and your house burns down?

As supplier, I’d be liable (rightly so, BTW – there is no excuse for selling stuff which might be dangerous).

The hardest part of all is that even if an accident has nothing to do with this Low-power Supply, I still have to prove that this stuff is safe under any circumstance and that it complies with all regulations!

I’m not willing to go there. Life’s too short and I don’t have the pushing power to go through it all.

Having said this, I do intend to use this supply myself and create all sorts of nodes for use here at JeeLabs. Because I know the risks, I know which failsafe features have been built into the supply, and I’m ok with it:

The design is available in the Café, to document what I’ve done and for others to do whatever they like with it.

I’m not happy about this decision, in fact I hate it. I’m really proud of finding out that it is possible to create sensor nodes which run off just 12 mW of AC mains power. But the right thing to do is to stop here.

## Putting the JNµ to sleep

In AVR, Hardware, Software on Jan 18, 2012 at 00:01

The Sleepy::loseSomeTime() code in the Ports library was never tested on a JeeNode Micro. Turns out that only a minor library difference kept it from working (the arduino-tiny library has its own version of millis(), etc):

So now, the JNµ can be put to sleep as well. Here’s the jouleTest sketch I used, tweaked to run on the JNµ as well:

And sure enough, about once every 10 seconds it shows that familiar packet-transmit current consumption:

The blue line is the AC-coupled supply voltage, a 3x AA Eneloop battery pack in this case. It supplies about 3.8V, but when running off a 1000 µF cap, it looks like this continues to work down to 1.8V (well below the RFM12B’s minimum 2.2V specs) – although with only about half the transmit power by then.

This current use fingerprint is almost identical to the ATmega328 running this same code. Not surprising really, since it’s the RFM12B which determines most of the power consumption, not the ATmega vs ATtiny difference.

Onwards!

## Another AA booster

In Hardware on Jan 16, 2012 at 00:01

Out of curiosity, I’ve been doodling around with the AS1323 boost regulator chip, as suggested by someone in the comments. It’s not super efficient, but it does claim an extraordinarily low quiescent current of 1.6 µA.

Hooking up such a tiny chip is quite a challenge:

The trouble is that this stuff can’t be spread out too much – the specs say that both input and output caps have to be within 5 mm of the chip. So I tied it to a pcb – mostly for stability – and then wired everything up around it.

Without any load, this thing operates in quite an efficient mode:

The yellow trace is the voltage drop across a 10 Ω low-side resistor, the blue trace is the output, but AC coupled, i.e. showing only the ripple voltage.

The red line is the math function to integrate total power use in Coulombs – more on that later.

If you look at the top overview graphs, you can see the current blips which are over 160 ms apart, i.e. this thing is activating only 6 times a second. And each current pulse lasts only about 150 µs. The peak current on the input side, i.e. drawn from the battery, is about 12.5 mA.

Let’s put a 1 kΩ load on the 3.3V output line:

I’ve adjusted the scale a bit. The switcher is now operating at about 11 KHz. The peak current drawn is almost 18 mA, but note also that the current never drops to 0 anymore – the baseline of that yellow trace is 2 divisions down from the top, so that’s about 6 mA (as expected, since the load is always drawing current).

Now let’s push it and change the output load to 100 Ω, i.e. about 33 mA @ 3.3V. To make that work, I had to change the input sense resistor to 1 Ω:

The baseline for the yellow trace is now halfway, same as for the blue line.

I also added a third probe, the green line monitors output voltage, which is indeed steady at 3.3V (both red and green lines are based at the bottom of the screen). Note the huge peak current draw on the battery: over 290 mA!

Let’s try to understand what’s going on in this last case. First of all, with a 1 Ω sense resistor, a 190..290 mA current draw creates a voltage drop of around 0.25V – which means the battery voltage isn’t really reaching the switching regulator. The battery was measured to be at 1.37V, so the switcher is getting only about 1.1V on average. The datasheet says that it will only be 70..75% efficient on such an input voltage, when generating the 3.3V output.

The 100 Ω output load draws about 33 mA. That’s at 3.3V, so a perfect step-up regulator would need to draw 3x as much when running off 1.1V, i.e. 100 mA. A 70% efficient switcher would draw about 150 mA (0.70 x 150 ≈ 100). What I’m seeing here is more like a 40% efficient switching result (0.40 x 250 = 100) – hm, not sure why…

The other way to determine average current consumption, is to do some Coulomb counting…

In the first screenshot, each blip uses about 900 nanocoulombs (the red line rises 4.5 divisions over the entire width of of the screen). With 6 blips per second, we use 5.4 µC each second, i.e. 5.4 µA average current draw (not quite the 1.6 µA I expected, but still very impressive for an unloaded step-up regulator).

The second graph is trickier. We need to figure out the Coulombs increase per repetitive cycle. My guess would be around 820 nC. Multiply by the switching frequency of 11.25 KHz, and you get 9.2 mC per second, i.e. 9.2 mA average battery current to deliver about 3.3 mA @ 3.3V.

Gotta be a bit careful here. It turns out that the battery (which is a bit old), still delivers 1.44V at this lower power level. Also, since I’m using a 10 Ω current sense resistor in this case, there’s 92 mV wasted in that resistor. That leaves about 1.35V going in. A perfect switcher would draw 3.3V / 1.35V * 3.3mA = 8.07 mA. We’re pulling 9.2 mA, which is about 87% efficiency. That seems a bit optimistic, since the AS1323 doesn’t really go much further than 80%. Oh well, there are probably several measurement errors in my quick and dirty test setup.

For the third case with the 100 Ω load, I end up with a figure of 215 mC/s, i.e. an average current draw of 215 mA. Better than before but still under 50% efficiency.

One more datapoint: with a 100 kΩ load, the switching frequency goes to 120 Hz, while still using about 800 nC per cycle, i.e. ≈ 100 µC per second, or 100 µA. Again, pretty good for what is essentially a 33 µA load @ 3.3V – even if all these estimates are off by perhaps 25%.

So this chip might work quite well for bursty ultra-low power contexts such as a mostly-sleeping JeeNode!

In Hardware, Software on Jan 8, 2012 at 00:01

Here is a new snoozeBlink sketch which can run off the new experimental 12 mW Low-power Supply:

It does all the right things to start off in low-power mode and puts the ATmega to sleep, even as the LED blinks!

The LED is a normal red LED with a forward voltage of about 1.6V and with a 470 Ω series resistor. The result:

(lots of noise because I’m using the default 1:10 probe and the scope at its most sensitive 1 mV/div setting)

Voltage over the 100 µF reservoir cap in blue, current consumption in yellow. You can see the startup dip when the cap reaches about 6V, then the 2s wait, and then the LED blink at about 2 Hz with a 10% duty cycle. There’s not much energy to spare – the reservoir cap doesn’t even get a chance to fully re-charge between blinks.

After about 4 seconds, I turned off the power to find out what would happen. Yet there’s still enough energy left to get two more full blinks, and then an aborted blink as the reservoir cap voltage drops below 3V.

Note how the power consumption is just 3 mA while the LED is turned on. The ATmega itself is hardly ever running (the very brief 10 mA peaks got filtered out in this scope capture).

It can even be made to flash with a 26 mA LED current (omitting the resistor) for 16 ms @ 2 Hz. In this case the reservoir cap voltage varied from 9.4 to 4.4 V, again leaving very little energy to spare. Maybe one day this can be refined to drive a TRIAC, which needs very frequent but brief pulses (a BT137, BTA312, or L6004L3?).

But there’s actually something extra-ordinary going on with that power-up sequence – let’s investigate:

The BIG surprise? This is running on a standard JeeNode with standard bootstrap – no power-up troubles at all!

Let me try and interpret everything happening in that last image:

• the initial very high blip (over 25 mA) is the JeeNode’s on-board 10 µF capacitor charging up
• the 65 ms @ 3.2 mA is the clock startup delay, as defined by the default fuse setting
• up to this point, the reservoir cap has lost some 2V of its charge
• the next blip is the boot loader passing control immediately to the sketch (!)
• then there’s the 32 ms loseSomeTime() call in setup(), with the ATmega finally powered down
• the last blip at the right-end side of the screen puts the RFM12B into low-power sleep mode

So what’s going on, and above all why is the boot loader problem gone, after all that trouble it gave me before?

The only explanation I can think of lies in the one change I made since then: I’m now using OptiBoot v4.4 … and it probably does the right thing, in that it skips the boot loader on power-up and only goes through a boot-loader sequence on reset. This is the well known ladyada fix. I guess my previous boot loader setup wasn’t using that.

This is really good news. It means you just need a recently-flashed ATmega and you can continue to use the normal FTDI upload mechanism while fooling around with this ultra low-power stuff. Even the 10 µF cap and regulator on the JeeNode can be left in when powering it from the new Low-power supply.

## ISP Programmers – part 2

In AVR, Hardware on Jan 5, 2012 at 00:01

In yesterday’s post, I presented my latest ISP programmers, based on the isp_repair2 sketch.

I made a few small improvements to that sketch:

1. the RFM12B is powered down at the end, so that the unit only consumes a few µA’s once done
2. the programming rate has been improved by getting rid of those horribly slow digitalWrite() calls, etc.
3. updated RF12demo and OptiBoot to the latest version (v8 and v4.4, respectively)

Furthermore, I switched from the funky switches to plain jumpers, with the following layout:

Another change is that the default with no jumpers is now to burn RF12demo w/ OptiBoot for use with a 16 MHz resonator – this is a good default for JeeNodes, JeeNode USB’s, and JeeNode SMD’s. To select the other options, just hook this up to USB, change the jumpers, and watch the serial output report on reset.

This is the output with no jumpers and no target board attached:

This is the output after a normal programming cycle (again, the default case, no jumpers installed):

Programming takes only a few seconds. Note that this programmer is fully self-contained and includes its own LiPo battery, so all you need to do is press the 6 pins on the ISP header pads. The neat thing is that due to the normally-discharged cap on the target board, the brief power dip caused by touching the ISP pads will generate a hardware power-on reset in the programmer, which then immediately starts its programming cycle.

So the the whole workflow is now as follows:

• grab this thing – and let’s call it a “Portable ISP Programmer” (PIP!)
• press the pins against the ISP header of the unit to be re-flashed
• watch the initial LED blink on the programmer as it comes out of reset
• wait 2..3 seconds
• watch the second LED blink, indicating that it has successfully completed programming

There is no power switch, since the programmer enters total power down when done. To re-charge, plug the programmer into a USB port and wait for the “charge” LED to turn off. Note that pressing the reset button also works, but that it adds a small boot loader delay before the isp_repair2 sketch gets started.

This has become so convenient, that I can now take any old JeeNode lying around here, and reset it to a well-known state in just a few seconds, before re-using it for some project or experiment.

## ISP programmers

In AVR, Hardware on Jan 4, 2012 at 00:01

ISP (re-)programming is going to become more important in the future, so I’ve built a few more of these:

The problem was to come up with a robust way to connect to the target board, but I think I’ve found a solution:

Take a 4-pin header, slightly enlarge the holes in the plastic, and then gently-but-forcefully press a couple of Pogo pins in there. I’m using the type with a large head with sharp edges. Here’s the whole assembly:

After that, it’s a matter of attaching all the wires and tying / glueing things together:

These units are all refurbished ones with a defective radio, since that’s not needed here.

The ZIP straps hold the battery and wires in place. The hot glue does the rest:

These programmers are considerably more effective than you might think – tomorrow, I’ll explain why…

## Scheduler power optimization

In Software on Jan 2, 2012 at 00:01

Last year’s post showed how a packet transmission w/ ACK reception works out in terms of power consumption. It also uncovered a fairly large “power consumption bug”, with the scheduler idling only 0.1s at a time, causing the ATmega to exit power-down mode through its watchdog far more often than necessary.

Here’s the relevant code in the general-purpose Scheduler class in Ports.cpp:

And here’s what I ‘m going to change it to, to optimize and stay powered-down much longer:

This changes the wake-up period from 30 times per second, to roughly once every 8s, with blips like this:

My interpretation of this picture, is that the ATmega on this JeeNode needs a whopping 10 mA of power for 50 µs once every eight seconds to keep going. That 1 ms “lead-in” at < 1 mA is probably clock startup, or something.

This current draw is the same as before (this capture was with PIR installed). But instead of 1800 wake-ups per minute, there will now be 10 or so. This will reduce the power consumption from 2,000 µC to roughly 10 µC!

Does that mean the Room Node will now last 200 times longer on a single battery? Unfortunately, no. With these low-power games, the weakest link determines total battery life. In this case, there’s a PIR sensor which has to be constantly on, drawing about 50 µA. That’s 3,000 microcoulombs per minute.

But still, this little optimization should add quite a bit to the lifetime of a battery:

• old: 3000 (PIR) + 130 (radio) + 600 (estimated) ATmega/regulator + 2,000 (scheduler) = 5730 µC/min
• new situation, again per minute: 3,000 + 130 + 600 + 10 = 3740 µC/min

If you’re wondering what “microcoulombs/minute” means: that’s just current, so rescaling it to µC/s (i.e. µA’s), we get: old ≈ 96 µA, new = 63 µA. With a 2000 mAh 3x AA battery pack, that’s 2.5 vs 3.6 years of run time.

Note that these values are fairly optimistic. With motion in the room, there will be more than one packet transmission per minute. I have yet to see the real-life battery life of these room nodes, although right now it’s looking quite good: the nodes I have around here have been working for many months – 2012 will tell!

But either way, that change of just a few lines of C code should add about 50% to the battery life. Crazy, eh?

## Anatomy of a Room Node transmission

In Hardware on Dec 30, 2011 at 00:01

Now that my analysis capabilities have improved, it thought it’d be interesting to see the power consumption profile of a Room Node, running the roomNode.ino sketch. Here’s an annotated capture of a motion event:

The yellow line is the current consumption of the entire room node. I’ve added some annotations, although there are still a few things I’m not so sure about, such as the 2.5 ms delay between SHT readout and XMIT start.

The red line is the integral of the yellow line, i.e. the total amount of energy consumed as time progresses. It took about 3 ms between the end of the packet transmission and the first ACK packet header byte coming in – this thumb-twitching with the receiver enabled accounts for about 1/3rd of the power consumption!

There is almost always room for improvement with this sort of stuff. The closer you look, you more you find things to optimize. For example, I noticed that there were blips every 32 mS or so (it’s slightly irregular):

This is zoomed in on both axes. The noise level is a bit higher, perhaps due to the 2 mV/div setting of the scope.

That’s over 1 ms @ 0.8 mA, at about 30 times per second on average. I don’t know what it is – it’s not the PIR sensor, which was removed during this measurement. Not a lot of energy per blip, but it does add up: ≈ each uses 1.1 µC, i.e. some 2,000 µC per minute. Whereas the first screen shows that a transmission takes only 130 µC.

So there you go: vampire power at microwatt levels!

Update – Ah, wait – of course! – it’s the Scheduler class in the Ports library! When idling, it lets time pass in steps of 0.1s (or rather 96 ms), and there’s no other way to do this than with 32 and 64 ms watchdog timer steps. I told you – there are no show-stoppers in this game, it works on logic and insight, all the way down!

## Finished Low-power Supply

In Hardware on Dec 28, 2011 at 00:01

The Low-power Supply described previously on this weblog now has a PCB – and it’s about as small as a JNµ:

Here’s an assembled unit, ready for testing and hooked up to power a JeeNode (w/ disabled bootstrap):

And here’s the whole test setup I had to create to check this thing out:

Lots of stuff involved, including high-voltage probe and 230V isolation transformer (to the right, out of view).

Here’s a demonstration of how it works – summarized as one elaborate scope capture:

Green is the mains voltage (235 Vrms), purple is the charge building up on the 100 µF reservoir capacitor, yellow is the regulated output, and blue is the JeeNode’s current consumption (measured as voltage drop over 10 Ω). Note how some of the voltages measured here differ more by than four orders of magnitude!

Anyway, that zoomed-in image is the clear signature of the second 8-byte RFM12B packet transmission. Current consumption varies from 23 to 26 mA. It’s a relatively coarse image, since it has been zoomed in 4,000 times.

The 3.3V supply level is reached ≈ 2s after power-up, with another 2.5s needed to fully charge the reservoir cap. You can see from the purple dips that this supply could sustain at least one packet transmit per second.

No surprises here, but it’s good to see that the PCB design works as intended. Next step: implement deep sleep on the ATtiny84 – hopefully this’ll take just some minor adjustments to the Sleepy::loseSomeTime() code.

## Meet the Low-power Supply

In Hardware on Dec 18, 2011 at 00:01

Now that everything is working, I want to have a ready-to use printed circuit board for it. Came up with this:

It’s tiny – about 48 x 12 mm – even though it’s based entirely on through-hole parts. The idea is to build it up, add wires, and then encapsulate the whole thing in heat-shrink tubing to reduce the number of contact points.

It can not be repeated enough: when tied to AC mains, the ENTIRE circuit carries AC mains voltage levels!

I have a couple of configurations in mind (see yesterday’s post for the schematic):

• with C1 a 10 nF X2 cap and C4 replaced by a wire, this delivers an average of 0.3 mA on 230 VAC mains
• with C1 a 22 nF X2 cap and C4 replaced by a wire, this delivers an average of 0.3 mA on 115 VAC mains
• with both C1 and C4 22 nF caps, this supplies 0.3 mA on 230 VAC with no direct connection to AC mains
• with C1 and C4 replaced by a wire, this supply can be used with 10..24V DC in – which is great for testing
• with C1 and C4 each replaced by a 220 kΩ resistor, and R1 by a 1N4007 diode, this becomes a somewhat less efficient (but lower-profile) resistive version, again delivering up to 0.3 mA at 230 VAC

With C4 replaced by a wire, this circuit will have its “GND” output tied directly to the “N” input. This is important when powering the AC current monitor, which needs to have one side of its shunt at 0V relative to AC mains.

Note that no matter what, even with C1 and C4 both included, faults can develop in this circuit which cause the “low voltage” output of the circuit to end up directly tied to an AC mains “live” line. This is not, and will never be, a “safe” circuit. It can only be used safely while enclosed in a plastic box, with no contacts or parts sticking out.

In all cases, the on-board regulator will be activated once the input voltage rises to about 6V. This is the key to being able to power up a JeeNode or JeeNode Micro with their on-board RFM12B module.

## A power supply which draws 12 mW!

In Hardware on Dec 17, 2011 at 00:01

It’s been a challenge to get all the bits of the AC current monitor ready, but the last hurdle has now been taken.

In a nutshell: the AC current monitor is a small unit based on a JeeNode Micro, which periodically broadcasts information about the current consumption of an attached appliance. It’s hooked up to 230V, so it’d be a bit silly to run it off batteries. It would be equally silly if it were to draw lots of power, and since it has to be permanently on, I wanted to get its power consumption really, really low – under 0.1 Watt. That goal has now been reached.

According to this calculator, the following setup draws only 12 mW @ 230V and will supply 0.3 mA @ 3.3V:

Here is the schematic:

It’s a transformer-less capacitive power supply, combined with an LT1121 low-power 3.3V linear regulator. C4 can be omitted. This regulator has a shutdown pin, which is tied to the input voltage via a voltage divider. As a result, the output of this supply switches on only once the 100 µF reservoir capacitor has charged up to 6V (it’ll continue charging to 12V, at which point the zener diode kicks in). Here is the power-up behavior w/o D2, and no load:

The blue line is the voltage over the reservoir cap, and the yellow line is the regulated output. If you look very closely, you can even see the 50 Hz cycles “pumping up” the reservoir once every 20 milliseconds.

By itself, this isn’t good enough yet to drive my test JeeNode (no bootstrap, brief wakeup activity every 10s):

Very odd behavior, as the regulator and the RFM12B start pulling more current than is coming in, preventing the output from ever reaching more than 1.8 V (I used a 470 µF reservoir cap in this test).

The final trick was to add a diode from the regulator output to the shutdown pin. This positive feedback causes the regulator to very quickly snap out of shutdown mode. So once the reservoir cap reaches about 6V, the regulator switches on, at which point the shutdown pin is quickly pulled high to finish the job and keep it on:

This is running from 150 VAC using the new AC power box. At lower voltages, the trickle current becomes too weak to reliably turn on. At 230V, on the other hand, the whole startup process is even quicker and very robust.

I have not yet been able to measure the power draw of this supply. Due to its design it will always draw the same amount (predicted to be 12 mW), regardless of load. The feed capacitor (C1) is a 10 nF X2 type.

Here’s the final proof – a JeeNode, powering up in a few seconds and sending out a test packet every 10 seconds:

Many thanks to martynj – his weblog comments and great suggestions by email made this result possible.

Good – now I can sprinkle dozens of these around the house and still use no more than one Watt extra!

## Developing a low-power sketch

In AVR, Software on Dec 13, 2011 at 00:01

As you’ll know if you’ve been reading this weblog for more than a few nanoseconds, I put a lot of time and effort into making the ATmega-based JeeNode use as little power as possible – microwatts, usually.

In the world of ultra-low power, the weakest link in the chain will determine whether your sketch runs days, weeks, months, or years… low power can be a surprisingly elusive goal. The last microoulombs are the hardest!

But it’s actually quite easy to get some real savings with only a little effort. Here are some things to avoid:

• Don’t optimize in the wrong place – it’s tempting to start coding in a way which seems like a good idea in terms of power consumption, although more often than not the actual gains will be disappointing.

• Don’t leave the lights on – the ATmega is amazingly easy to power down, which instantly reduces its consumption by several orders of magnitude. Make sure you do the same for every major power consumer.

• Don’t just sit there, waiting – the worst thing you can do in terms of power consumption is wait. Unfortunately, that’s precisely what the Arduino runtime’s delay() and delayMicroseconds() calls do.

Ok, with this out of the way, I’ll describe a very simple way to get power consumption down – and hence battery lifetimes up (waaay up in fact, usually).

The trick is to use a convenience function from JeeLib (a.k.a. the Ports library). It’s in the “Sleepy” class, and it’s called loseSomeTime(). So if you have this in your code:

``````    delay(100);
``````

… then you should replace it with this:

``````    Sleepy::loseSomeTime(100);
``````

You also need to include the following code at the top of your sketch to avoid compilation and run-time errors:

``````    #include <JeeLib.h>

ISR(WDT_vect) { Sleepy::watchdogEvent(); }
``````

As the name indicates, the timing is not exact. That’s because the ATmega is put into a power down mode, and then later gets woken up by the watchdog timer (this is hardware, part of the ATmega). This timer can be several percent off, and although the milliseconds timer will automatically be adjusted by loseSomeTime(), it won’t be as accurate as when updated by the crystal or the ceramic resonator often used as system clock.

The second issue with the watchdog is that it can only delay in multiples of ≈ 16 ms. Any call to loseSomeTime() with an argument less than 16 will cause it to return immediately.

Furthermore, loseSomeTime() can only work with argument values up to 60,000 (60 seconds). If you need longer delays, you can simply create a loop, i.e. to wait 120 minutes in ultra-low power mode, use this:

``````    for (byte i = 0; i < 120; ++i)
Sleepy::loseSomeTime(60000);
``````

One last aspect of loseSomeTime() to be aware of, is that it will abort if an interrupt occurs. This doesn’t normally happen, since the ATmega is shut down, and with it most interrupt sources. But not all – so if loseSomeTime() returns prematurely, it will return 0. Normally, it returns 1.

The trade-off of loseSomeTime() is power consumption (system clock and timers are shut down) versus accuracy.

But the gains can be huge. Even this simple LED blink demo will use about 10 mA less (the ATmega’s power consumption while running at 16 MHz) than a version based on delay() calls:

``````    void loop () {
digitalWrite(4, 1);
Sleepy::loseSomeTime(250);
digitalWrite(4, 0);
Sleepy::loseSomeTime(250);
}
``````

To reduce this even further, you could shorten the blink ON time as follows:

``````    void loop () {
digitalWrite(4, 1);
Sleepy::loseSomeTime(50);
digitalWrite(4, 0);
Sleepy::loseSomeTime(450);
}
``````

The LED may be somewhat dimmer, but the battery will last 10x longer vs. the original delay() version.

Battery-powered operation isn’t hard, you just have to think a bit more about where the energy is going!

## RFM12B low-power startup

In AVR, Hardware on Dec 8, 2011 at 00:01

The startup saga continues. Too many inter-related issues, I need to simplify…

Before tackling the power-ramp startup scenario, i.e. starting up a JeeNode (or JeeNode Micro) on a slowly-charging capacitor, I wanted to make absolutely certain that the sketch is set up to get the best low power mode as quickly as possible after a hardware power-on reset.

Time to create a test setup:

This is a JeeNode running off 3.6 .. 3.9 V battery power, driving a MOSFET plug using this sketch:

In other words: power up for 2.5 seconds, power down for 0.5, then rinse and repeat. The JeeNode sitting upright at the bottom right is the Device Under Test (DUT). It’s a JeeNode without regulator, with a little test board to pass the ground connection through a 10 Ω resistor. This lets me measure current (or rather: voltage drop) as well as the voltage of the power supply.

Here is the behavior of a standard ATmega, with standard fuses and a sketch to init & power down the RFM12B:

There’s a 1.5s startup delay as the boot loader listens for incoming commands, before it passes control to the current sketch. The lower half of this screen shot shows that point, i.e. right when the sketch is given control. Within about 250 µs, the RFM12B is put to sleep. The vertical scale is 2 mA/div (Ohm’s law, 10 Ω resistor).

Note the time scale: the lower portion is zoomed in 1000x w.r.t. the top.

After lots of experimentation, with the boot loader disabled, I managed to get startup a lot quicker, using a lot less energy. The code used was as follows (with these fuse settings: EXT = 0x06, HIGH = 0xDB, LOW = 0xC2):

Here is a screenshot with all the traces properly labeled and with measurement units added:

Note again the horizontal time scale (top left). Here’s how to identify the different portions of these graphs:

• the first blip is when the ATnega comes out of power-on reset
• the second blip is for the rf12_initialize() and rf12_sleep() calls
• the third blip is the first time loop() is run, which then quickly goes to sleep again

The big surprise (and disappointment) here, is the time between blips 1 and 2, where the average current consumption is about 0.75 mA (between the white cursor lines). This is caused by the RFM12B starting up (a bit irregularly) with the crystal oscillator enabled, instead of in power down.

The problem is that the RFM12B can’t be accessed in the first 30 ms or so after power up (probably because it’s still busy getting out of its own hardware reset). That’s a shame, since the ATmega can go to sleep in ≈ 250 µs.

The point of this all, is to make a JeeNode (or JNµ) start up with a capacitor powered from AC mains, using as low a current trickle as possible. But unless I can find a way to shut that RFM12B down very early on, it looks like a 1 mA or so trickle will be needed to overcome this initial power “hogging” behavior.

I’m not (yet?) willing to throw more hardware at the problem, but that would be one way to work around it: use an I/O pin and a MOSFET to power the RFM12B, after the voltage is high enough to be able to overcome this dip.

In the previous post, I managed to get a JeeNode started with what I though was a 10 µA trickle, but it now looks like I was off by two orders of magnitude in those tests. It’s easy to lose track of details while making changes!

Conclusion: an AC mains power supply with 1 mA trickle is an option, but I’m not ready to give up … yet!

## RF12 power optimization

In AVR, Hardware, Software on Dec 1, 2011 at 00:01

Here’s a small evolutionary change to the RF12 driver, to squeeze one more drop of power consumption out of it.

This is the code for which I’m trying to optimize power consumption:

The Sleepy::loseSomeTime() call is the big power saver. It puts the ATmega into a total power down mode, except for the watchdog timer, which is used to get it back out of this comatose state. So we’re sleeping for 10 seconds.

Around it are the rf_sleep() calls needed to put the RFM12B into low-power mode as well.

And lastly, the rf12_sendWait(3) call does something pretty nifty: it puts the ATmega into full power down mode between each byte sent to the RFM12B while transmitting. This requires a non-standard fuse setting in the ATmega – it only works with a ceramic resonator or the internal clock oscillator, not with a crystal: wake up out of power down within a few clock cycles.

The most efficient mode turns out to be with the ATmega running at 8 MHz off the internal RC oscillator (which starts up really fast). With default Arduino’ish settings, you have to use mode 2, i.e. a less extreme power down mode so it can wake up fast enough.

Here’s one complete transmission of a 8-byte payload (scope details to follow tomorrow):

Each vertical division is 5 mA current draw (the voltage drop across a 10 Ω series resistor). You can see the ATmega turn on, drawing 5 .. 9 mA, and the RFM12B in transmit mode consuming about 23 mA.

The red line is pretty advanced stuff: it integrates the current over time – which is equivalent to the amount of charge consumed. At the end of the trace, this leads to a result of 7.22 microcoulombs per packet sent. One way to interpret this (thanks, Jörg – see comments), is that you could send one packet per second on an average current of less than 8 µA (hm, I think that should be 80 µA).

The “blips” are when the ATmega wakes up and feeds another byte to the RFM12B. In detail (edited image):

These blips take about 32 µS @ 5 mA, which is what it takes to communicate with the RFM12B on the SPI bus at 2 MHz. The reason is that the RFM12B supports a 2.5 MHz maximum SPI rate (it turns out that this limitation only applies for data read from the RFM12B module).

The blips repeat 18 times, every 162 µS. Why 18? Well, an RF12 data transmission looks as follows:

That’s 9 bytes of overhead, plus the 8 payload bytes, plus a trailing interrupt to shut down the RFM12B once the transmission is over.

For completeness – in case you think I can’t count blips: there’s one more activity peak at the start. That’s the call to rf12_canSend(), to check that the RFM12B is ready to start a transmission (which then takes 250 µs to start).

This is probably the limit of what you can push out of power savings with an ATmega (or ATtiny) and an RFM12B. Well, apart from: 1) sending less data, 2) increasing the transmit data rate, or 3) decreasing transmitter power.

When re-using the same code with “rf12_sendWait(2)” and running with normal fuse settings at 16 MHz using a ceramic resonator, it uses only slightly more charge – 7.70 µC, i.e. 7% more. So while this was a nice exercise, it’s not really a major improvement.

All in the name of nanowatt yak power s(h)aving…

## All power-up puzzles solved?

In AVR, Hardware on Nov 30, 2011 at 00:01

As reported in a recent post, there were startup problems when powered from a 0.4 mA trickle-fed capacitor.

In short: it didn’t work…

The problem with a trickle-feed supply is not that the voltage level will ramp up very slowly (the brown-out detector and power-on reset circuitry should be able to handle that). The problem is that the circuit needs to draw less current than the trickle at all times – because otherwise the capacitor won’t ever reach its full charge level.

One problem was the MCP1702 voltage regulator, which has a large current draw before the input voltage reaches 3.3V where it can start regulating. So I removed the regulator, and created a setup which limits the capacitor charge to around 3.8V – thinking that without the regulator, the ATmega would at some point start up and immediately put itself and the RFM12B into sleep mode, letting the supply voltage rise a bit further.

Strangely enough, it didn’t work at all. I kept seeing a start-up spike of several milliamps. Here’s the current consumption on power-up (the scope shows the voltage over a 10 Ω resistor in series with the power supply):

That’s over 10 milliamps, for well over a second – Huh?

And then it finally dawned on me: the boot loader! The ATmega is set to look for an upload right after power-up or reset, which is what the boot loader is all about. Guess what it does: look for incoming commands on the serial port for roughly one second, before passing control to the main sketch stored in the ATmega.

Clearly, the boot loader is running at full power. Whoops!

So the first conclusion is that in this context, we can’t use a boot loader. The solution is to change the high fuse from 0xDA to 0xDB with an ISP programmer. It’ll make it harder to upload code, but there’s no other way.

Great. I thought that would solve the problem. But that’s not all. The default fuse settings also cause the ATmega to wait for 65 milliseconds on power-up. This is for crystals to get up to a stable oscillation. Unfortunately, that means the ATmega is spending 65 ms in a higher-power mode on startup.

So I changed the fuses to use the 1K / 14 CK startup mode (power-up / reset). The way I read this, it means that the ATmega will power-up after 1024 + 14 clock cycles once it comes out of hardware reset, and after 1024 clock cycles when coming out of sleep mode.

Furthermore, the divide-by-8 prescaler fuse bit needs to be set, because the ATmega will power up with a 2.7 V supply voltage (the BOD level). At that level, running at 16 MHz is way out of spec, and no doubt very unreliable.

So all in all, the following fuse settings are required:

• BOD level = 2.7V, i.e. don’t power up before the supply has reached 2.7V
• enable ÷ 8 pre-scaler on startup (can be disabled in software later)
• make the clock start up in low-power 1K / 14 CK mode
• disable the boot loader, jump immediately to the main sketch

Here is the power consumption with these changes (note the 40x X scale and 5x Y scale differences):

There’s still a 0.65 mA current draw during start-up. Unfortunately, this one is nasty: it’s caused by the RFM12B module, which powers up in this mode. Best thing I can do is put the RFM12B to sleep as soon as possible, but that can’t happen before the ATmega has started up fully. So basically, there’s a 0.65 mA current draw which we can’t get rid of (other than adding extra circuitry to control the RFM12B’s power – but see also below).

What this means, is that I’ll have to settle for a 1 mA trickle feed supply for now. It’s enough to keep charging the buffer cap, and this way things ought to finally get past that power-up hurdle.

And guess what? It works!

The cap charges until the supply reaches 2.7V, then the ATmega snaps out of reset and puts the RFM12B to sleep.

The interesting thing now, is to check whether that MCP1702 current anomaly on startup really was a problem. So I switched back to a standard JeeNode, and tried it with the above fuse settings.

Hey, it still works! So we could go back to a 12V zener charging a 100 µF cap. This puzzle has come full circle!

More good news – it looks like there is a sneaky way to avoid the 0.65 mA power-up current draw of the RFM12B: make the ATmega start up at 1.8V instead of 2.7V – the RFM12B isn’t pulling much current at that level. So if we turn it off right away then the RFM12B will be put to sleep before it gets a chance to draw too much current.

Does this work? You bet. Here is by far the craziest low-power setup I’ve ever been able to get going:

That’s a 100 µF cap charged using a 10 µA trickle. You can see the 1.8V bump where the ATmega kicks in, inits the RFM12B, puts it to sleep, and later on sends 2 packets. This is a standard JeeNode, but with special fuse settings:

• internal 8 MHz RC oscillator, fastest startup
• don’t enter the boot loader
• brown-out level is set to 1.8V

The fuse settings are: extended = 0x06, high = 0xDB, low = 0xC2.

Fascinating how everything affects everything, eh?

UpdateI’m having some doubts about this last result. Will need to triple-check my calculations on this one. That last report is most definitely incorrect, there’s no way to get the RFM12B to start up with a 10 µA trickle – it starts up with the crystal oscillator active, which means that it’ll draw at least 0.6 mA until put to sleep.

## Ultra low power supply

In Hardware on Nov 27, 2011 at 00:01

This is another post about my quest for an ultra low power supply for the JeeNode and JeeNode Micro, directly connected to AC mains (and hence dangerous, I can’t stress that enough).

To reiterate: the goal is to create a supply using at most 0.4 mA for powering a device at roughly 2.5 .. 3.5 V. With a capacitive transformer-less circuit, this should lead to a 230V power drain of under 0.1 W.

The zener diode approach doesn’t work for voltages under 6V. Low voltage zeners are too leaky.

Neither does a low-power linear regulator – maybe – driven from say a 12V zener + cap. It probably draws too much current on power-up.

A possible solution was mentioned in a 2008 article by Bob Chao, titled “Voltage clamp circuits for ultra-low-voltage apps”. It’s based on a special type of MOSFET called an “EPAD”.

There’s a chip called the ALD111933 (scary name!) which includes two of these. Here are some specs:

So its gate threshold is very strictly specified as 3.3V, and it can only drain just a few milliamps. Still plenty for me, though. Another design limit is that the device only supports up to 10V between source and drain.

Here’s what I have in mind as my next attempt for the ultra low power supply:

The 9.1V zener will have no more than 10 µA of leakage, and the leakage of the MOSFET is negligible as long as the supply voltage remains under 3.3V. Which means all the surplus current can be used by the JeeNode – at last!

Note that there are no other voltage levels of this thing, so there’s not much leeway for charge on the capacitor to drop during high power use, i.e. packet transmission. I can think of two ways to improve on that: go back to a 470 µF cap, which will hold more charge, or add an extra diode in the MOSFET’s gate to increase the voltage level at which it triggers. Either way, I think this circuit ought to finally give me that constant trickle to keep going!

I’ve ordered the necessary parts. To be continued…

## The beat goes on

In Hardware on Sep 4, 2011 at 00:01

Today, a milestone was reached:

``````    \$ jeemon examples/driver-demo/
15:45:01.975 RF12demo config usb-A700fdxv RF12-868.5
^C
``````

That’s nearly half a million packets, one every 64 seconds, all on a single LiPo battery charge:

The setup is very simple. A 1300 mAh LiPo battery (I just picked one up in a camera shop with a convenient size), attached to a JeeNode USB:

At 3.94 V the battery is still far from dead, so it’ll probably stay alive for quite a bit longer…

The sketch running on this node is:

(looks like I had lost the low-power stuff in the “radioBlip” code, now fixed on GitHub)

Lots of low-power nodes are holding out nicely here at JeeLabs, by the way. There are about half a dozen permanent room nodes, and with the latest roomNode sketch they just keep going. Some are running on 3x AA rechargeable EneLoop batteries, others use 3x AAA with even less juice, and all of them have been running with just a single charge since the beginning of this year.

## JeeNode with a 32 KHz crystal

In AVR, Hardware on Jun 28, 2011 at 00:01

Another experiment: running a JeeNode on its internal 8 MHz RC clock while using the crystal input to run timer 2 as an RTC. This would allow going into a very low-power mode while still maintaining a much more accurate sense of time.

To this end, I modified a JeeNode SMD, by replacing the 16 MHz resonator with a 32 KHz crystal:

I didn’t even bother adding capacitors, these are probably not needed with this crystal (same as on the RTC Plug) since there is probably enough parasitic capacitance already.

The tricky part is the code, since the ATmega is now running in a not-so-Arduino-like mode. Could almost have used OptiBoot with this setup, but the only internal RC clock build for it is the LilyPad, which has an ATmega168.

I ended up using the ISP programmer. IOW, I now compile for “LilyPad w/ 328” and then bypass the bootstrap and serial-upload. Less convenient, but it works.

Here’s a quick test sketch which writes a dot on the serial line exactly once a second:

So this setup is working. It draws 4.10 ma, consistent with the recent current measurements: slightly less than with the 16 MHz resonator pre-scaled by two.

In idle mode, current use drops to 1.71 mA, not bad!

Now let’s power down with just the timer running as real time clock. There’s a special “power save” mode which does just that. The difference is that timer 0 will now be off, so there won’t be interrupts waking up the ATmega every 1024 µs (as side-effect, the millis() function will start to lose track of time):

A small adjustment is needed to make sure the serial port is finished before we go into low-power mode, hence the call to delay(3).

Hm, power consumption is still 0.67 mA – quite a bit, given that we’re really powering down most of the time.

Ah, wait. I forgot to turn off the radio. Doing that brings the reading down to 0.15 mA – and I forgot to turn off the ADC and other sub-systems. Now we’re down to … 0.05 mA, while still printing dots:

Note that these 1 second interrupts are very accurately timed, more so even than with the standard 16 MHz resonator. This could be used to perform time-domain tricks on the wireless side, i.e. waking up just in time whenever a “scheduled” packet is expected to come in – as described in yesterday’s post.

There’s probably more left to try. The delay is running on full power, waiting for the serial output to clear the USART. It could be done while in idle mode, for example. Anyway… that entire delay becomes superfluous when we stop sending out debugging output over the serial port.

So there you have it – a JeeNode running at ≈ 8 MHz, with a precise 32,768 Hz pulse feeding timer 2, in a way which supports low-power sketches while maintaining an accurate sense of time.

Wanna make a clock?

## Current measurements

In AVR, Hardware on Jun 26, 2011 at 00:01

Wanted to check a few things w.r.t. current consumption of a JeeNode. The old way of doing this was a bit inconvenient, so I made a new test setup:

(old one on the left, new one on the right)

Sturdier, no need to disconnect the multimeter to short it out, and most importantly: high-side current sensing! That’s quite important, because multimeters can add a small voltage drop when used in current measurement mode, and that voltage drop will affect the serial I/O on the FTDI pins when placed in the GND line. Silly me, should have been on the PWR line all along!

The back side of the new connector is trivial:

The multimeter attaches to the top pins, bent apart for easy connection. The jumper shorts it out so this contraption can still be used when the multimeter is turned off.

Ok, time for some simple measurements:

• ATmega full speed, doing nothing: 6.84 mA
• ATmega full speed, with the RFM12B receiver on: 18.42 mA
• ATmega powered down, only the RFM12B receiver on: 11.53 mA
• ATmega full speed, with the RFM12B tranmitter on: 29.92 mA

Idle mode is a simple way to reduce power consumption without changing the logic of the code. It turns the MPU off until an interrupt occurs. Basically, you’re telling it “I’ve got nothing to do until something new happens”. It’s a pretty safe change, and well worth doing in any idle loop which isn’t directly polling I/O pins. The ATmega’s current consumption is slashed by more than half:

• ATmega in idle mode, doing nothing: 2.80 mA

Another way to reduce power consumption, is to slow down the clock at which everything takes place, by setting the “clock pre-scaler”:

• ATmega @ 16 MHz, doing nothing: 6.84 mA (as before)
• ATmega @ 8 MHz, doing nothing: 4.35 mA
• ATmega @ 4 MHz, doing nothing: 2.96 mA
• ATmega @ 2 MHz, doing nothing: 2.02 mA
• ATmega @ 1 MHz, doing nothing: 1.55 mA
• ATmega @ 500 KHz, doing nothing: 1.28 mA
• ATmega @ 250 KHz, doing nothing: 1.16 mA
• ATmega @ 125 KHz, doing nothing: 1.09 mA
• ATmega @ 62.5 KHz, doing nothing: 1.06 mA

Diminishing returns, clearly. Note that lowering the system clock in this way is not necessarily the best choice – getting something done N times faster and then powering down completely might be more efficient (see below).

One thing to watch out for: don’t go below 4 Mhz if you want to be able to use the RFM12B, or the processor will be too slow to process each byte.

When combining this, we get:

• ATmega @ 4 MHz in idle mode, doing nothing: 1.48 mA
• ATmega @ 62.5 KHz in idle mode, doing nothing: 1.03 mA

The advantage of this approach is that the clock is still running on the 16 MHz resonator (which probably draws most of that remaining current), so you’re still able to keep track of time – just more slowly.

A different approach is to go into real low power mode, and use the watchdog to get back out of this comatose state. The watch dog timer is less accurate, but depending on your application that may not be an issue.

Here’s the current consumption with the ATmega alternately in full speed and in power down mode:

• ATmega 16 ms @ 16 MHz / 16 ms powered down, doing nothing: 3.49 mA
• ATmega 8 ms @ 16 MHz / 16 ms powered down, doing nothing: 2.31 mA
• ATmega 4 ms @ 16 MHz / 16 ms powered down, doing nothing: 1.39 mA
• ATmega 2 ms @ 16 MHz / 16 ms powered down, doing nothing: 0.80 mA
• ATmega 1 ms @ 16 MHz / 16 ms powered down, doing nothing: 0.46 mA

That last one does about the same amount of work as when running constantly @ 1 MHz, but with a third of the power consumption. Here is the corresponding sketch:

And it will continues to scale downward:

• ATmega 100 µs @ 16 MHz / 16 ms powered down, doing nothing: 90.4 µA

Which still represents 100,000 active processor cycles per second…

And lastly, let’s take it into power down and run for just 1 ms per second, i.e. 0.1% of the time. I can’t measure this with the multimeter, because the power use jumps up every second, but the comatose period draws a mere 6.8 µA, which is consistent with what has been reported several times before (the watchdog is still active, and so is the brown-out detector).

## Still running on LiPo

In Hardware on May 21, 2011 at 00:01

A while back, a post on this weblog described a simple setup I had running to see how long the radioBlip.pde sketch would keep running on a single LiPo battery.

Here’s the setup again:

That’s a 1300 mAh battery, and the test sketch on it sends out an incrementing counter approximately once a minute (I extended the counter to 4 bytes, instead of the 2 bytes used in the original sketch).

It’s still going strong, i.e. this sketch has been running for 9 months on a single battery charge so far.

The counter is now at about 350,000 and I’ve determined that packets actually go out every 64 seconds, so that puts the counter at about 260 days. There’s a gap there, because the node was once reset some two weeks after being started for the first time.

So with some 275 days of running time, we can deduce that the average power consumption of this node has to be under (1300 * 1000) µAh / (275 * 24) h = 197 µA. This assumes that the battery would be empty, which it isn’t yet – so we know the average current must be lower (a lot lower, probably). Unfortunately, I didn’t include logic to measure and send out the LiPo voltage, which would be a good indicator of how far the LiPo battery actually is. The good news: a check with my multimeter shows the battery to still supply a whopping 3.985 V!

Anyway – I wouldn’t be surprised to get at least 4 times as much runtime, i.e. 3 years, out of this setup (which would translate to 50 µA average current draw).

Sooo… just hang around for another few years, and I’ll let you know!

## GLCD on battery power

In Hardware on Nov 27, 2010 at 00:01

I’m going to switch to a different type of graphic LCD once the next batch of Graphic Boards arrives. Instead of a white-on-black type, the new GLCD will be a blue-on-sort-of-blueish color:

The reason for this is that it is still quite readable without the backlight:

There is a solder jumper on the Graphics Board, to choose between powering the backlight continuously via PWR, or having it powered under software control, via the not-often-used IRQ pin. This not only lets you turn the backlight on and off, but even dim it under software control, because the IRQ pin supports PWM, i.e. analogWrite().

The above display draws about 280 µA without backlight right now, which means it will keep running for over a month on a single AA cell, using the AA Power Board. There are probably ways to reduce that current consumption further, as I’m not doing anything yet with the ST7565’s standby and other low-power modes.

And although it may not be practical for a permament display, this definitely is useful for something I’d like to have around and use on a regular basis. By sending it stuff to display over wireless, this setup can support what is quickly becoming my favorite mode of operation here at Jee Labs: no wires cluttering my desk!!!

## Sending data TO remote nodes

In Software on Oct 31, 2010 at 00:01

Yesterday’s post described an easy way to get some data from remote battery-powered nodes to a central node. This is the most common scenario for a WSN, i.e. when reading sensors scattered around the house, for example.

Sometimes, you need more reliability, in which case the remote node can request an “ACK” and wait (briefly) until that is received. If something went wrong, the remote node can then retry a little later. The key of ACKs is that you know for sure that your data packet has been picked up.

But what if you want to send data from the central node TO a remote node?

There are a couple of hurdles to take. First of all, remote nodes running on batteries cannot continuously listen for incoming requests – the RFM12B receiver draws more than the ATmega at full power, it would drain the battery within a few days. There is simply no way a remote node can be responsive 100% of the time.

One solution is to agree on specific times, so that both sides know when communication is possible. Even just listening 5 ms every 500 ms would create a fairly responsive setup, and still take only 1% of the battery as compared to the always-on approach.

But this TDMA-like approach requires all parties to be (and remain!) in sync, i.e. they all need to have pretty accurate clocks. And you have to solve the initial sync when powered up as well as when reception fails for a prolonged period of time.

A much simpler mechanism is to let the remote take the initiative at all times: let it send out a “poll” packet every so often, so we can send an ACK packet with some payload data if the remote node needs to be signaled. There is a price: sending a packet takes even more power than listening for a packet, so battery consumption will be higher than with the previous option.

The next issue is how to generate those acks-with-payload. Until now, most uses of the RF12 driver required only packet reception or simple no-payload acks. This is built into RF12demo and works as follows:

That’s not quite good enough for sending out data to remote nodes, because the central JeeLink wouldn’t know what payload to include in the ACK.

The solution is the RF12demo’s “collect mode”, which is enabled by sending the “1c” command to RF12demo (you can disable it again with “0c”). What collect mode does, is to prevent automatic ACKs from being sent out to remote nodes requesting it. Instead, the task is delegated to the attached computer:

IOW, in collect mode, it becomes the PC/Mac’s task to send out an ACK (using the “s” command). This gives you complete control to send out whatever you want in the ACK. So with this setup, remote nodes can simply broadcast an empty “poll” packet using:

``````    rf12_sendStart(0, 0, 0);
``````

… and then process the incoming ACK payload as input.

It’s a good first step, since it solves the problem of how to get data from a central node to a remote node. But it too has a price: the way ACKs are generated, you need to take the round-trip time from JeeLink to PC/Mac and back into account. At 57600 baud, that takes at least a few milliseconds. This means the remote node will have to wait longer for the reply ACK – with the RFM12B still in receive mode, i.e. drawing quite a bit of current!

You can’t win ’em all. This simple setup will probably work fine with remotes set to wait for the ACK using `Sleepy::loseSometime(16)`. A more advanced setup will need more smarts in the JeeLink, so that it can send out the ACK right away – without the extra PC round-trip delay.

I’ll explore this approach further when I get to controlling remote nodes. But that will need more work – such as secure transmissions: once we start controlling stuff by wireless, we’ll need to look into authorization (who may control this node?), authentication (is this packet really from who it says it is?), and being replay-proof (can’t snoop the packet and re-send it later). These are all big topics!

More on this some other time…

## Simple RF12 driver sends

In AVR, Software on Oct 30, 2010 at 00:01

(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.

## Reporting motion

In AVR, Software on Oct 21, 2010 at 00:01

Yesterday’s post presented a new sketch which did everything the old sketch did, except report motion. The reason was that the requirements for reporting motion are quite different from the rest: it has to be reported right away – using ACKs, time-outs, and retries to make sure this message is properly received.

The latest version of roomNode.pde now adds the missing logic. And it does indeed get a lot messier – doubling the total number of lines in the source code.

Here is the new loop() code:

The key change is that there is now a check for “pir.triggered()” which will be called outside all normal scheduling actions. Note that this code is still using scheduler.pollWaiting(), so the code is still spending most of its time in power-down mode.

Except that now, we’re also setting up a pin-change interrupt for the PIR sensor:

The new code to handle these PIR triggers is as follows:

So instead of folding this complicated case into the rest of the code, when a PIR trigger goes off, we now simply send that packet out and wait for the ACK, repeating it a few times if necessary. The normal measurement and reporting tasks are not affected by any of this, other than that the measurement scheduling is postponed a bit to avoid triggering another report right away.

The new PIR motion sensor turns out to be quite convenient, because it has an on-board trimpot to set the re-trigger timeout. As long as motion is detected more often than this threshold, the PIR output will remain 1, so there is no need to play tricks in software to avoid constant triggers. We’ll get one pin change for the start of motion, and another one when no motion has been detected for a preset amount of time.

Having said that, I’ve implemented a similar re-triggerable one-shot mechanism in software anyway, because my older nodes use the ELV PIR sensor, which send out a pulse for each motion trigger. So all ON pulses within 30 seconds of each other get coalesced into one.

To illustrate that the system is still doing almost nothing most of the time, I added a debug mode which prints a “.” on each iteration of loop(). In normal Arduino sketches, this would cause an incessant stream of characters to be printed out, but in this sketch there are just a few:

Motion detection now works more or less independently of the normal measure / report tasks.

There are still some rough edges, but I expect this new code to perform considerably better in terms of battery lifetime already. The dreaded battery rundown problem when the central node is not reachable should be gone. All that remains are a few attempts (I’ve set it to 5) whenever the PIR sensor turns on or off. In both cases the ACK has to be received within 10 milliseconds – after that the sketch enters power-down mode again.

The new code should also make it much easier to add sensor types (switches, hall-effect, 1-wire, barometer).

FWIW, this code needs 8238 bytes (without serial I/O), so it’ll still easily fit in an ATmega168. Without SHT11 (which uses floating point) that drops to 5682 bytes, including the RF12 driver. How’s that for a WSN node!

## New roomNode code

In AVR, Software on Oct 20, 2010 at 00:01

It’s time to start putting the pieces together now: sensor readout, scheduling of measurements and packet sends, and low-power mode. Looks like the code in the Ports and RF12 libraries is now making this easier than ever.

There’s a new roomNode.pde sketch which illustrates the whole shebang. At 145 lines, it’s a bit too long to include here in full, but I’ll show some of the interesting pieces.

Note that this version implements everything except motion reporting, which is a bit more complex.

Following the good ol’ top-down tradition, first the setup() and loop() code:

It starts the measurement loop, which then keeps itself running periodically. The report activity is started every once in a while. Note also the “now” variable, which will make it easier to use 2-byte ints in the logic which will decide later about when to report motion, etc.

The measurement code depends completely on what sensors are supported, and is pretty straightforward:

No surprises, we just have to be careful to do things in an energy-efficient manner. All the readings end up in the “payload” struct.

And here’s the reporting code:

Here’s some sample output on the serial port:

I still need to add the logic for motion detection, but with the new scheduling capabiltities, I expect that extra complexity to stay within a small portion of the code – unlike the current rooms.pde sketch, where everything seems to affect everything else.

The best part? My multimeter stays mostly under 60 µa, i.e. the low-power logic is automatically kicking in!

## Room Node – next steps

In AVR, Software on Oct 19, 2010 at 00:01

First of all: thanks to everyone who commented on the recent posts, both online and by direct email. Fantastic feedback, lots of ideas, and several valuable corrections.

In yesterday’s post, I agonized about how hard it is to track time in some sort of reasonably continuous way when most of it is spent in comatose state. Fortunately, a Room Node won’t need that awareness very much. I just wanted to show how things get complex in terms of watchdogs running-but-not-yet-expired, and multiple interrupt sources.

For the next version of the rooms.pde sketch, my plan of attack is to simply ignore the issue. The watchdog will be used for guaranteed wake-up, while PIR motion detection and radio reception interrupts will simply cause the millis() clock to lose time, occasionally.

For ACKs, I’m going to start simple and wait for up to 2 milliseconds in idle mode, before resuming lower-power options again. One interesting suggestion was to slow down the clock while doing so (through the system clock pre-scaler), but that has to be done with care because a slower-running ATmega will also respond more slowly to RF12 driver interrupts – and there is not that much slack there.

Here’s the updated Scheduler class, now included in the Ports library:

Only a minor extension on the API side: by using pollWaiting() instead of poll(), you can tell the system to enter low-power mode until the next scheduled task. If another interrupt pre-empts this wait cycle, then it’ll break out of power-down mode and go through the loop and re-enter the low-power state the next time around.

The other change I’m currently testing is that a few Scheduler functions can be called from interrupt code, so this provides a way for interrupt code to safely schedule, resume, or cancel a task “via the main thread”.

This is the tiny change needed to make the schedule.pde demo energy efficient:

However, because it now uses the watchdog, you also need to add the following boilerplate to the sketch:

``````ISR(WDT_vect) { Sleepy::watchdogEvent(); }
``````

The demo now draws 25 µA when I remove the LEDs.

So here’s the deal: if you can manage to write all your code is such a way that it never calls delay() – or delayMicroseconds() with large values – and instead uses this Scheduler-with-tasks approach, then you’ll get a fairly low power usage almost for free… i.e. without having to do anything else! (just don’t forget to turn the radio on and off as needed)

The code has been checked into subversion, and is also available as ZIP archive – see the Ports info.

Update – more changes checked in to better handle watchdog vs other interrupts.

## Tracking time in your sleep

In AVR, Software on Oct 18, 2010 at 00:01

No, this isn’t a story about bio-rhythms :)

One of the challenges I’ll be up against with Room Nodes is how to keep track of time. The fact is that an ATmega is extraordinarily power efficient when turned off, and with it a JeeNode – under a few microamps if you get all the little details right. That leads to battery lifetimes which are essentially only determined by self-discharge!

But there are two problems with power off: 1) you need to be 100% sure that some external event will pull the ATmega out of this comatose state again, and 2) you can completely lose track of time.

Wireless packets are of no use for power-down mode: the RFM12B consumes many milliamps when turned on to receive packets. So you can’t leave the radio on and expect some external packets to tell you what time it is.

Meet the watchdog…

Fortunately, the ATmega has a watchdog, which runs on an internal oscillator. It isn’t quite as accurate, but it’ll let you wake up after 16 ms, 32ms, … up to 8 seconds. Accuracy isn’t such a big deal for Room Nodes: I don’t really need to know the temperature on that strict a schedule. Once every 4 .. 6 minutes is fine, who cares…

There’s a Sleepy class in the Ports library, which manages the watchdog. It can be used to “lose time” in a decently accurate way, and will use the slowest watchdog settings it can to get it out of power-down mode at just about the right time. To not disrupt too many activities, the “millis()” timer is then adjusted as if the clock had been running constantly. Great, works pretty well.

It’s not enough, though.

As planned for the next implementation, a Room Node needs to sleep one minute between wakeups to readout some sensors, but it also needs to wake up right away if the motion sensor triggers.

One solution would be to wake up every 100 ms or so, and check the PIR motion sensor to see whether it changes. Not perfect, but a 0.1s delay is not the end of the world. What’s worse though is that this node will now wake up 14,400 times per day, just to check a pin which occasionally might change. This sort of polling is bound to waste some power.

Meet the pin-change interrupt…

This is where pin-change interrupts come in, They allow going into full power-down, and then getting woken up by a change on any of a specified set of pins. Which is perfect, right?

Eh… not so fast:

Q: What time is it when the pin-change occurred?

A: No idea. Somewhere between the last watchdog and the one which will come next?

IOW, the trouble with the watchdog is that you still don’t really track time. You just know (approximately) what time it is when the watchdog fires again.

If the watchdog fires say every 8 seconds, then all we know at the time of a pin-change interrupt, is that we’re somewhere inside that 8s cycle.

We can only get back on track by waiting for that next watchdog again (and what if the pin change fires a second time?). In the mean time, our best bet is to assume the pin change happened at the very start of the watchdog cycle. That way we only need to move the clock forward a little once the watchdog lets us deduce the correct moment. FYI: everything is better than adjusting a clock backwards (timers firing again, too fast, etc).

Now as I said before, I don’t really mind losing track of time to a certain extent. But if we’re using 8-second intervals to get from one important measurement time to the next, i.e. to implement a 1-minute readout interval, then we basically get an 8-second inaccuracy whenever the PIR motion detector triggers.

That’s tricky. Motion detection should be reported right away, with an ACK since it’s such an important event.

So we’re somehere inside that 8-second watchdog cycle, and now we want to efficiently go through a wireless packet send and an ACK cycle? How do you do that? You could set the watchdog to 16 ms and then start the receiver and power down. The reception of an ACK or the watchdog will get us back, right? This way we don’t spend too much time waiting for an ack with the receiver turned on, guzzling electrons.

The trouble is that the watchdog is not available at this point: we still want to let that original 8-second cycle complete to get our knowledge of time back. Remember that the watchdog was started to get us back out in 8 seconds, but that it got pre-empted by a pin-change.

Let me try an analogy: the watchdog is like throwing a ball straight up into the air and going to sleep, in the knowledge that the ball will hit us and wake us up a known amount of time from now. In itself a pretty neat trick to keep track of the passage of time, when you don’t have a clock. Well, maybe not for humans…

The scenario that messes this up is that something else woke us up before the ball came down. If we re-use that ball for something else, then we have lost our way to track time. If we let that ball bring us back into sync, fine, but then it’ll be unavailable for other timing tasks.

I can think of a couple solutions:

• Dribble – never use the watchdog for very long periods of time. Keep waking up very frequently, then an occasional pin-change won’t throw us off by much.

• Delegate – get back on track by asking for an ack which tells us what time it is. This relies on a central receiving node (which is always on anyway), to tell us how to adjust our clock again.

• Fudge it – don’t use the watchdog timer, but go into idle mode to wait for the ack, and make that idle period as short as possible – perhaps 2 ms. IOW, the ACK has to reach us within 2 milliseconds, and we’re not dropping into complete powerdown during that time. We might even get really smart about this and require that the reply come back exactly 1 .. 2 ms after the send, and then turn off the radio for 1 ms, before turning it on for 1 ms. Sounds crazy, until you realize that 1 ms of radio time uses as much energy as 5 seconds of power down time – which adds up over a year! This is a bit like what TDMA does, BTW.

All three options look practical enough to consider. Dribbling uses slightly more power, but probably not that much. Delegation requires a central node which plays along and replies with an informative ack (but longer packets take longer to receive, oops!). Fudging it means the ATmega will be in idle mode a millisec or two, which is perhaps not that wasteful (I haven’t done the math on that yet).

So there you go. Low power stuff isn’t always trivial, once you start pushing for the real gains…

## Room Node battery life

In AVR, Hardware on Oct 6, 2010 at 00:01

The current Room Node sketch only gets 1..2 months of life out of a 3x alkaline AA battery pack. Not enough – by far – for practical use around the house.

The good news is that it’s almost entirely a software issue. There have been JeeNodes running for many months now, some up to 10 months, so there is no hardware limitation to achieve such lifetimes.

In fact, I’d like to push it a bit further and see how long one could run a Room Node off a single rechargable AA battery using the AA Power board. If it’s not that long, I could still opt for the 3x AA pack.

Let’s estimate the idle current draw of a JeeNode first.

The big consumer is the PIR sensor. I recently switched to a new one, because it only needs 3.3V and because of its low current draw. Note that the PIR motion sensor is the only component in the Room Node which should not be disabled during sleep: the whole point is to be able to detect motion at all times, after all. Also, a PIR sensor needs time to stabilize, in the order of a minute, so turning it on briefly is no option.

Here’s the good news:

That’s 41 µA idle current.

The JeeNode draws ≈ 3.3 µa, let’s round it up to 4 µA.

The SHT11 draws 2..5 µW, let’s round it up to 2 µA.

So total idle draw is 47 µA.

As it turns out, transmissions consume a neglegible amount of current – if the frequency of transmission is 5 minutes, for example (i.e. 288x per day). The motion detection is different, this needs to go out as soon as there is motion, but this probably won’t happen more than a dozen times a day, on average).

For a transmission, the RFM12B needs to be on for about 2 ms, at which point it draws around 25 mA. With 2 ms once every 300 seconds, that’s a duty cycle of 1:150000, i.e. under 2 µA when averaged out.

So let’s round up and assume that the average current draw of a Room Node is 50 µA @ 3.3V.

A 3x AA battery pack of 2500 mAh would last 50,000 hours, i.e. over 5 years if we ignore the self-discharge rate … assuming that the low-power code is perfect, that is!

Now for the AA Power Board lifetime estimate. At very low current levels, the efficiency of the LTC3525 regulator is 75..80%, according to the datasheet. But first, we need to estimate the current draw. Keep in mind that the power source will be 1.2 .. 1.3V, so we basically need a 3-fold step up. Let’s calculate the input current draw, assuming 1.2V in, 3.3 V out @ 50 µA, and 75% efficiency:

input current = 50 x 3.3 / 1.2 / 0.75 = 183 µA

With an Eneloop battery, I’ll assume it has 1900 mAh capacity, and loses 15% of its charge in two years. Let’s assume that it’ll be used no more than 2 years, and that it lost that 15% charge right at the beginning. Then this is effectively nothing more than a 1600 mAh battery.

Ok, how long can it power a JeeNode plus Room Board?

lifetime = 1600 / 0.183 = 8743 hours = 364 days

So all in all this setup should be able to run just about one year off a single rechargable AA battery. Note that there was some rounding in several places in these calculations, so these estimates are probably a bit conservative.

One year battery life… that’s in fact exactly what I was hoping for!

Now the “only” remaining challenge is to optimize the “rooms.pde” sketch enough to make this happen.

## Poor Henry

In Hardware on Oct 2, 2010 at 00:01

The new AA Power Board is working very nicely, but it turns out that the ferrite-core inductor is a little fragile.

This is the 10 micro-Henry inductor core, as it should be:

… and this is what happened to one of the shipments “all the way” to the UK:

(photo courtesy Steve Evans – great close-up!)

Whoops, not good!

This happened to two of the five boards shipped as part of a “5-pack”, where I placed all the boards together in a single plastic bag, along with the metal AA clips. The fact that the inductor is placed near the outside edge also probably doesn’t help…

I’ll package the boards differently from now on. But if you got these boards, please check them and let me know if they got damaged (they may still work, depends a bit on the breakage) – I’ll send out replacements for any bad boards out there, of course.

Live and learn!

## Room Node mount?

In Hardware on Sep 21, 2010 at 00:01

I’m still searching for ideas to mount a JeeNode with a Room Board, a.k.a. as a “Room Node”. Now that the AA Power Pack lets me get rid of two of the 3 AA’s, I’m sort of hoping to bump into some new and practical options.

The PIR motion sensor is placed above an empty spot between the JeeNode and the AA Power board. It’ll need to be wired up in that position, of course.

The shapes are still agonizingly unsuited for placement into a corner, but then again… it’s a lot better than with the 3x AA battery pack! Here’s the whole setup again, in close-up:

The trick will be to cover it up properly, here’s a first trial using my favorite foam-board as prototyping tool:

That’s 6.5 cm wide, btw. Any less, and the battery holder will poke into it and make it wobble.

Does it look good? I don’t know. I think I could live with a slanted 6.5 x 20 cm white strip along the ceiling, with a little PIR peeking out in the middle (and a small hole for the LDR + temperature/humidity sensor).

Next challenge is to come up with a mounting bracket for this darn thing. Perhaps 3D-printed? Two triangles on the end or something? If they slant slightly inwards, they would cast a shadow and not draw much attention…

It all needs to be properly detachable, since this thing runs on battery power. I could stick two little solar panels on the surface to get a warm fuzzy environmental feeling… but I doubt they’ll capture enough energy in that position.

Anyway – I’m happy to have a fresh option to think about. We’ll see…

## Lots of AA’s

In Hardware on Sep 20, 2010 at 00:01

With all the JeeNodes and room nodes I’ve been trying out around here – and the modest results with the rooms.pde sketch w.r.t. battery life so far, I’ve gone through all these much faster than I would have liked to:

Went through over 60 here at Jee Labs, in the past year or so. So much for the environment!

Enough is enough. I’m switching to the Apple charger with the Eneloop NiMh’s. And with the new AA Power board, it looks like a single AA cell per node might be enough.

But wait! Are all those AA cells really empty? Time to find out!

Since the AA Power board is so efficient, I though it’d be interesting to see how many of those “dead” AA cells are truly empty. Note that the AA Power board can pull juice out of a battery and generate 3.3V even when it’s supplying less than half its original voltage:

So let the battle begin: which cells really can no longer drive a JeeNode as wireless test node?

The result surprised me quite a bit. These 10 were completely dead:

But the rest – which is ALL the batteries shown in the first picture – still worked!

This doesn’t mean that any of these batteries will last very long. But still – they drive the JeeNode and its on-board RFM12B transmitter well enough to send out a fresh packet once a second. Which means that even with an output voltage less than 1.1V, they are still able to a briefly deliver a 80 mA peak current once a second (i.e. 3x the current required @ 3.3V) !

Hmm, now what … charge an Eneloop with all that residual energy, perhaps? :)

## AA power options

In Hardware on Sep 19, 2010 at 00:01

The new AA Power board is a pretty darn flexible little board, if I may say so myself. Its switch regulator draws very little current itself, 7..30 µA depending on the input voltage. The input voltage range is approx 1.0 .. 5.5V, to be able to start up, but it will drain the power source all the way down to 0.4V if it can, pulling every last bit of juice out of regular AA batteries.

But the AA Power board is also capable of providing a pretty decent amount of current when needed. This is essential for the on-board wireless radio of the JeeNode, but it even works with heavier loads than that:

That’s an Arduino-compatible JeeNode with an LCD Plug and a 2×16 character LCD with backlight – all running off a single 1.2V AA NiMH battery!

The maximum current depends on the input voltage. It is guaranteed to be at least 60 mA from a 1V supply, going up to 140 mA from a 1.8V supply. Note that the input current can be much more than that – drawing 60 mA at 3.3V means the battery may have to deliver about 200 mA at 1V to make it happen. A clever little power regulator it is – a producer of energy it is not!

There a several ways to connect the AA Power board with a JeeNode:

• inline, feeding the PWR pin with 3.3V (this will be dropped some 30..50 mV by the on-board regulator of the JeeNode itself, with no ill effects)
• in piggy-back mode, with an AA cell inserted in the battery clips (alkaline or NiMh)
• as a shield on top of the JeeNode, again with an AA cell inserted

There’s also a fourth way to use this board: leave off the battery clips, and connect a battery between any PWR and GND pins on the JeeNode itself (or use the battery holes) – this requires a solder jumper on the AA Power board.

The flexibility of the regulator means that you can connect any power source between 1.0 and 5.5V to PWR and GND, just as you would with a stand-alone JeeNode. Whatever it is, the +3V pin will carry the essential 3.3V level.

There is one issue to beware of: when PWR is connected to BAT+ via the solder jumper, then do not hook up a second power source at the same time. The most common case is probably: when a battery is connected to PWR, do not connect an FTDI adapter such as the BUB, because it’ll put 5V on the PWR pin … and the battery (or the BUB!) probably won’t like it.

The PWR pin can in fact be used in four different modes:

• normal – it’s higher than 3.3V and the on-board regulator brings it down to 3.3V for the +3V pin – this would be the case with 3 to 8 AA’s, for example (no need for an AA Power board)
• boosted – it’s lower than 3.3V and it’s used to feed the AA Power board – in this case the on-board regulator does nothing (and could be omitted)
• parallel – the PWR pin is connected directly to the +3V pin – this can be used with the AA Power board to make sure the PWR pin also carries power (always 3.3V), in case some plugs expect a supply voltage on the PWR pin
• floating – the PWR carries no power – this is the case when the AA Power board is used without solder jumper (default case)

The important point here is that the PWR pins do not necessarily carry a higher voltage than the +3V pins. It might be more (normal), less (boosted), the same (parallel), or none (floating). Not every JeePlug can be used with each mode of operation, so be careful to check.

Tomorrow, I’m going to fool around with a bunch of batteries :)

## AA mounting options

In Hardware on Sep 18, 2010 at 00:01

As promised yesterday, here is some more info on how to use the new AA Power board.

You’ve already seen the “inline” mode, using an Alkaline cell this time:

The second main mounting option is in piggy-back mode, flipped over and mounted on the back of a JeeNode:

This can be done either with regular male header pins (1×6 and 2×4, or 3×4), or with extra long pins which will stick out the front of the JeeNode as normal header pins:

Doing so requires some care, because once these two boards are soldered back-to-back, you can’t reach everything anymore. Disassembling such a sandwich later is tricky.

Note that you can stand the whole assembly on empty AA battery clips, but once a battery is inserted, this becomes unstable because the round battery sticks out:

With AAA clips and the much thinner (and weaker) AAA battery, it turns out that the whole construction does stand upright, but the size and position of the clips gives it limited stability when adding plugs on top.

There is a third option – use the AA Power board on top of a JeeNode with stacking headers, i.e. like a “shield”:

There is not that much room, but the 4 port headers can still be used. Note that the AA Power board needs to be mounted upside down in this case, i.e. with the SMD components and the silk screen facing down towards the JeeNode. Here’s another view of this shield-style option:

Coming up… a description of the full range of power connections supported by this little magician.

## Long live the AA battery!

In Hardware on Sep 17, 2010 at 00:01

The AA Power board announced yesterday just arrived:

And it looks like it does indeed perform exactly as expected. Here’s the ripple:

That’s with the 1.6 mA LED load, i.e. a 75 µs cycle / roughly 13 KHz – this was as predicted: at light loads, the recharge frequency can reach down into the audible range. But it’s highly unlikely to be noticable due to the tiny size of the inductor, which after all is not built to act as a loudspeaker :)

Here’s the “AAv1” fully mounted for powering a JeeNode via the FTDI connector:

(there’s no charge circuit here, I’m just using an externaly-recharged battery as power source)

And here’s the whole setup in actual use:

Works like a charm. Runs just fine with the “rooms” and “radioBlip” sketches, and wireless just works – as before.

Quiescent current draw is about 20 µA when powered this way. That goes down to 10 µA when used with two cells @ 2.4V, and down to an amazing 7 µA when powered from a 3V source (a CR2032 ought to work nicely!). Above 3.3V, the circuit becomes just a tad less efficient when it switches into step-down mode, drawing about 30 µA all the way up to 5.5V.

Great, now we’re starting to get into some serious low-power options.

Tomorrow, I’ll describe other ways to use this new AA Power board…

## Meet the AA Power board

In Hardware on Sep 16, 2010 at 00:01

Remember the recent post about running a JeeNode off a single battery?

That was 9 days ago, and that LED shown above is still lit. It’s not a huge accomplishment, because the LED draws only about 1.6 mA and is very dimly lit, but still. Over two hundred hours of operation time, and the rechargeable battery I used (this one) is still going. It started off at 1.35V and is now at a decent 1.22V level.

Assuming a 70% efficiency (at such low voltages, it probably won’t be much higher than that), and an average of 1.3V getting boosted to 3.3V, the power consumption over this period is … scribble, scribble … 1.6 * 3.3 / 1.3 / 0.7 * 216 = 1253 mAh, i.e. about two thirds of the total capacity of this one-cell AA battery.

Not too shabby. Even without power-down tricks, just by entering idle mode in all the busy loops, an ATmega328P will draw less than 1.6 mA when running at 16 MHz on 3.3V (which is slightly overclocked, but it works just fine). Idle mode is very nice, because you don’t have to play any serious low-power tricks, you just have to tell the ATmega: I have nothing to do right now, take it easy until the next interrupt occurs.

In other words: using only the simplest of all the low power tricks, a JeeNode can run about two weeks off a single AA battery (less, if you have power-hungry peripheral chips connected, of course).

Try running an Arduino Duemilanove off a 9V battery, or even a 4x AA battery pack. Fine board, but it sure ain’t low power…

Anyway, I’ve decided to design an AA Power board for this little power magician:

It’s not specific to the JeeNode, but it was of course designed to be a particularly good match for it:

• the width of the board is exactly the same as JeeNodes and all the JeePlugs
• it can be attached in-line, i.e. like an FTDI board/cable
• it can be used in piggy-back mode, i.e. attached to the back of a JeeNode
• or use it in shield mode, i.e. on top of a JeeNode with stacking headers
• it has mounting holes (since there is plenty of room on this thing)
• the board can be fitted with either AA battery clips, or AAA battery clips
• or attach external batteries to it: one, two, three (even four, if NiMh) … you decide!

Whatever the power source is, this board will either boost or step-down the voltage as needed. The efficiency will be up to 95%, depending on load and supply voltage. But in any case, it’ll be way more efficient than any linear voltage regulator, including the one on the JeeNode.

One AA is smaller than 3 or 4, obviously, so a JeeNode with this AA Power board will also fit into smaller places.

In case you insist on using 3x or 4x AA’s, then you’lll still benefit from a much higher conversion efficiency, and the ability to run the batteries down until they are completely empty. In other words: they will last longer!

Now it’s just a matter of waiting to find out whether I did all my homework properly, and got the connections, traces, and physical dimensions right.

## Running off a single AA battery

In Hardware on Sep 6, 2010 at 00:01

The other day, I found the LTC3525 – an interesting little (yes, tiny!) boost regulator chip, which might be a pretty good power source for low-power JeeNodes.

Couldn’t resist – had to try it…

Here’s a test setup using my favorite foam-board as base, with one AA battery driving a test LED:

(hard to see, but that LED is indeed on)

Did I mention that the whole thing uses tiny parts? It did take some patience…

Tests show that it will regulate any input voltage from 0.8V .. 5.5V to 3.3V @ 60..200 mA depending on the input voltage. And with 70..90% efficiency, even in the 10’s of µA current consumption range. I’ve verified that it will indeed down-regulate when fed > 3.3V, which makes it very flexible.

The quiescent current draw of this circuit appears to be around 20 µA on a 1.3V input.

So it looks like this could work out nicely:

My hunch is that this thing could last 6 months for a room node. Maybe more, but with a 6-pack of AA batteries plus charger, who cares?

Hmm, might be worth designing a little board for…

## Sleepy class

In AVR, Software on Sep 4, 2010 at 00:01

To make it simpler to experiment with the very low-power states of the ATmega on the JeeNode, I’ve moved some code to the Ports library.

It’s all wrapped up into a new “Sleepy” class:

See the powerdown_demo.pde and radioBlip.pde sketches for examples of use.

This class is documented in the Café:

FWIW, I’m also evaluating the Redmine system as a way to bring the code repository, Café docs, issue tracker, and Talk forums all into one context:

That site is still experimental, so I’m not making it public yet. The one missing feature holding me back is that Redmine does not have a good spam prevention mechanism, such as Akismet. At least last time I looked. But all in all, this would be a great way to provide a place to describe projects, fill in the documentation, and track all code changes and bugs collaboratively. If you’d like to have a sneak preview, or want to have a place to describe your project, or perhaps would like to help with the fairly gigantic task of getting a good documentation section going, please email me.

I’ve started copying over some content, but it’s going to take a while before everything has been brought over and adjusted. Both the old and the new system use Markdown, but there are always them pesky little details…

Anyway, back to the topic at hand – enjoy the low-power options, and please consider sharing your explorations, findings, and inventions in the Talk discussion forums.

## JeeNode goes solar

In Hardware on Sep 3, 2010 at 00:01

Now that ultra low-power options are coming into reach for JeeNodes, lots of new scenarios can be explored.

The most obvious one is probably a solar-powered JeeNode … so meet the latest new node #5 at Jee Labs:

It also uses a 0.47 F supercap, same as yesterday, but now hooked up to a small 4.5 V solar cell (which can only deliver a few mA in bright sunlight), and a Schottky diode between the solar cell and the capacitor.

Here’s the “power supply” in more detail:

As you can see, the solar cell is tiny. A few square cm’s only. In fact, it takes quite some time for it to charge the supercap to acceptable levels. I had to place the cell in moderately bright sunlight for about half an hour to get to a 4 Volt charge. It was inching along, taking several seconds per 0.01 V increase.

To avoid losing all that charge right away in the power-up cycle, I modified the ATmega’s fuses to start in 258 clock cycles after power down, and to start up within 4.1 msec after reset. That way it will start up as quickly as possible at all times. The 258 CK setting is particularly nice, because it means the ATmega can get out of total power down within about 16 µs, fast enough to respond to a byte RX/TX interrupt from the RFM12B!

Does it work? Check it out: after connecting the JeeNode with the “radioBlip.pde” sketch pre-loaded… away it went – sending one packet every 60 seconds as node 5:

``````    OK 5 1 0
OK 5 2 0
OK 5 3 0
OK 5 4 0
``````

While exposed to the current partly-sunny / partly-cloudy light levels, the voltage on the supercap is still increasing. This is good – it means there’s a surplus of solar energy, even with these transmissions going on. That extra energy will be crucial if this thing is to last through the night…

If everything works out, this little Arduino-compatible bugger could well be the first JeeNode to become completely autonomous and transmit wirelessly… forever!

Time will tell :)

## Sending packets without battery

In AVR, Hardware, Software on Sep 2, 2010 at 00:01

Here’s a fun experiment…

After yesterday’s improved power-down current results, I wanted to find out how much power it really takes to send out a bunch of small packets. No acks, just periodically sending out a packet and sleeping.

Trouble is, I didn’t want to wait for a battery to run down, since that would take months or even years. Bit long to get results for this weblog, eh?

So instead, I used this little chap:

It’s a super-capacitor which can handle up to 5.5V and has a capacity of 0.47 Farad! That’s like putting a thousand 470 µF caps in parallel. Amazing stuff, in an even more amazingly small package.

Here’s a JeeNode, fitted with this new power source, to give you an idea of just how small this thing is:

The next step was to design a small sketch to test this. Here’s what I came up with:

Some of the code left out for brevity. Full source code can be found here.

What this demo does is send out a packet with a 2-byte payload, then sleep for approximately 1 second, then send again, etc. Until power runs out.

Sure enough, packets started coming in every second:

``````    OK 4 0 0
OK 4 1 0
OK 4 2 0
OK 4 3 0
[...]
``````

I expected it to send out say 100 packets or so, before the charge in the 0.47 F supercap would run out.

Guess how far it went…

``````    [...]
OK 4 178 28
OK 4 179 28
OK 4 180 28
OK 4 181 28
``````

That’s packet number … clickety, clickety … 28 * 256 + 181 = 7349 !!!

In other words, the JeeNode was able to send out well over 7000 packets, i.e. two hours of packets sent once a second.

This is fantastic. I think the secret – apart from the 3 µA powerdown mode – is that the RFM12B + RF12 driver require very little time to start up, send off a packet, and go back to sleep again. There is no ACK involved, the RFM12B is hardly ever in reception mode.

With real-world use, I expect power requirements to be considerably higher. First of all, a Room Board will draw around 50 µA, due to the on-board PIR sensor. And second, I’m going to want to use ACKs for at least the motion detector reports, so that the system has a robust mechanism for reporting motion whenever it is detected. This means putting the RFM12B in receive mode for a few milliseconds, waiting for the ACK. And repeating this process a few times if that ACK isn’t immediately received.

But still … over 7000 packets without a battery!

Update – with one packet per 5 seconds, the charge lasted 4523 packets, i.e. just over 6:15.

Update #2 – with one packet per 60 seconds, 771 packets got sent out, that’s 12:51 hours … looks like the self-discharge of the supercap is eating up the remaining energy.

## Sleep!

In AVR, Software on Sep 1, 2010 at 00:01

The “powerdown_demo.pde” sketch in this recent post draws 20 µA, which surprised me a bit…

A while back, I got it down to a fraction of that, by turning off the brown-out detector (BOD) through a fuse bit on the ATmega. That’s a little circuit which prevents the ATmega from coming out of reset and doing anything if the voltage is too low.

As it turns out, you can turn off the BOD in software, but only for sleep mode. The reasoning being that there’s no point in protecting the processor from going berserk while it’s not doing anything in the first place…

Well, my code to turn off the BOD was wrong. You have to do this right before going to sleep. Here’s the updated powerdown_demo.pde sketch:

(correction – I mixed up my bits: change “PINB |= …” to “PINB = …” or “PORTD ^= …”)

The result?

Now we’re cookin’ again!

## Another LiPo option

In Hardware on Aug 21, 2010 at 00:01

The other day, I found a Lithium battery in a local shop, which has just about the right size and properties for use with a JeeNode USB:

Found it here, for €9 … so it won’t break the bank.

The nice bit, apart from its size, is that it is fully enclosed and isolated, with two contacts which are easy to solder:

Do read that warning, and then proceed anyway :)

What you see above, is the battery with a bit of solder applied to each terminal. Next, I attached some wires:

I used two-sided tape to permanently fasten the battery to the JeeNode USB’s back side. Note that the headers were already soldered on, with all the extruding pins clipped to get a slightly flatter surface:

The ground wire didn’t need insulation after all, since it connects right next to where the battery is. The positive wire was connected to PWR on port 3, to leave the PSI header free if it ever needs to be hooked up later.

And that’s all there is to it:

There is no switch to disconnect the LiPo, so the JeeNode USB can run down the battery if it’s not running a good power-saving sketch. But who needs a switch anyway, when you can do it in software, right? Just upload this:

When run, the JeeNode will power off completely. This code has been added as “powerdown_demo.pde” sketch in the Ports library.

For proper use, sketches running on a LiPo-powered JeeNode USB should periodically measure the current LiPo voltage via the ADC6 pin, which is tied to a voltage divider. For this to work, the voltage should not have dropped below about 3.4V, so that the ATmega still gets a properly regulated 3.3V as AREF to compare with. The voltage on ADC6 is always half the voltage on the PWR pin. So what every sketch needs to do, is to occasionally measure the voltage, and once it reaches 3.4V, shut down completely using something like the above code.

So there it is – another JeeNode, ready to go … to recharge it, I just plug it into USB!

## New AA battery option

In Hardware on Aug 19, 2010 at 00:01

Today might be a good day to set aside your dislike of Apple for a moment…

There is a new battery pack + charger option on the market:

In Europe, this combination costs €29.95, and it gets you 6 rechargable batteries plus a charger.

The specs are what make this thing particularly interesting for low-power battery-powered devices:

• each NiMH AA cell holds 1900 mAh charge (rumored to be rebranded Sanyo Eneloops)
• the batteries are reported to retain at least 70% of their charge for 2 years
• battery lifetime is reported as being at least 10 years (with recharges, of course)
• the charger drops to 30 mW “vampire” power draw once the batteries are charged

To start with the latter: I’ve verified it. When charging, there’s a small yellow LED and it draws less than 4 watts. When done, the LED turns green, and power consumption drops to 0.18W. Then, after 6 hours, the LED goes off and the power consuption drops to… zero! At least on the very sensitive SBC-500 I used.

This is a very big deal!

It means you can permanently leave these chargers plugged in, with a few spare AA’s. No cost, no waste – simply a way to keep a couple of cells fully charged and ready to go.

It’s also perfect for JeeNodes, using the standard 3x AA battery holder:

That’s 4.1V when fully charged. And JeeNodes will work with them all the way down to 3.3V, i.e. 1.1V per cell. Also, unlike LiPo batteries, running NiMH batteries down won’t do them any harm.

At last, I can stop wasting alkaline batteries… I’m probably going to replace all of them in the months ahead!

## Going for gold with the BMP085

In Software on Jun 30, 2010 at 00:01

The recent post about adding some battery savings logic got a lot of mileage out of a very simple change – more than 10x lower average power consumption.

Warning: getting power consumption down can be an addictive puzzle!

Jörg Binkele was very helpful, and sent me a scope image, measuring the voltage drop over a 10 Ω resistor in the power line (before the regulator). Here are the first 5 seconds after powering up:

As expected, the node settles into a very low power mode most of the time, with an occasional blip once a second. FYI: one vertical division is 10 mA. The little horizontal bar at both ends is probably the trigger level.

One small surprise was the startup behavior. Well, that first 18 mA bump is really a very simple bug: in the first second when the timer is running and being polled, the node is not in low-power mode. Aha, of course – my power-down logic is at the end of loop(). Ok, trivial to change – just move the end of loop() to the beginning:

Yup, that seems to get rid of the 1 second hump @ 18 mA. Great. I don’t have an explanation yet for the initial 1.5 seconds, but I suspect that the RF12 driver is waiting in rf12_initialize() – there is still some oddness with RFM12B initialization after power-up. Oh well – that’ll be for another day.

But now it gets interesting – I told you it’s addictive! – the image above shows that each blip is ≈ 75 msec @ 18 mA. That’s when both the ATmega and the RFM12B are turned on.

Wait a minute. Why so long? Sure, the BMP085 needs to measure temperature and pressure, and that takes several tens of milliseconds. But why keep everything else running full throttle? There’s no need.

So I rearranged the core loop a bit, in a way where all major delays would be done with as much of the node’s hardware turned off as possible (bmp085demo.pde):

Here is the result, again courtesy of Jörg – and then annotated:

There’s lots of info here. Please note that the time scale is 25 times more detailed than the first scope image. The fun part is that you can essentially tie each power level to a line of code.

For example, the first hump is when the timer hasn’t yet reached 1000 milliseconds (since the watchdog can only take steps of at least 16 ms), so the node waits. But since it uses idle mode i.s.o. normal mode, power levels are about half of what an ATmega usually consumes. With almost no effect on the code. All we’re doing is switch off to wait for the next timer interrupt – that’s 50% of easily obtained savings.

Then there are two medium peaks when the ATmega starts the BMP085 measurements, and in between it drops back to power-down levels. Then we waste some power sending results out on the serial port (this could be removed). Lastly, when it’s time to transmit the readings, we switch on the radio, make sure it gets its job done, and then loop, again in power-down mode with the watchdog to keep us going.

If you look very closely, you can even see how long the BMP085 is busy with measuring temperature (about 4ms) and pressure (roughly 20 ms). Exactly according to specs.

The blip on the first screen is about 4 divisions on the second screen, and as you can see, the node is now asleep most of that time. That’s probably another 10-fold improvement. I wouldn’t be surprised if this node will now run a year or so on one set of AA batteries. And it’s still reporting once a second.

The moral is: match your reasoning to measured facts, and you can get a lot of power savings. Each case will be different, but it’s not rocket science.

Thanks Jörg, but please don’t send any more scope shots … I need to kick this addiction again! ;)

(Reminder: last day of the June special in the shop!)

## A small improvement to rf12_sendStart()

In Software on Jun 21, 2010 at 00:01

The RF12 driver has a function called rf12_sendStart() which – you guessed it – is used to start sending out a new wireless packet.

Yesterday’s post was about battery savings, which I implemented by going into a power-down state right after sending out a new data packet.

That code included this little detail:

The reason for this is that the RF12 driver works mostly on an interrupt basis – i.e. in the background. Without the delay, the node would power down before the packet had actually been sent out. Then, when waking up, the transmission would fail due to the transmitter underrun caused by this logic.

By simply waiting a bit, the interrupts can continue to take place, and all the bytes will get sent to the RFM12B and from there into the airwaves.

Totally by chance, an EtherCard software problem was reported on the Jee Labs discussion forum, which turns out to be related to this very same issue. Sure enough, adding the “delay(5);” fixed that problem as well.

This felt a bit unsatisfactory as solution, so I’ve extended the rf12_sendStart() function to support a “synchronous mode”. The change is backwards compatible, i.e. the default behavior of rf12_sendStart() hasn’t changed.

Now, if you pass 1 as fourth argument, rf12_sendStart() will wait for the packet transmission to actually complete before returning to its caller. In general, calling rf12_sendStart() in sync mode is probably a good idea. Sync mode can be used for sending data packets as well as acknowledgement packets.

So the above code can be replaced by this single line:

This simplifies the bmp085demo.pde sketch slightly, and it also solves the problem that the EtherCard library may occasionally lock out interrupts on the SPI bus a bit too long to keep the RF12 driver running.

The code and documentation have been updated.

Onwards!

## Battery savings for the Pressure Plug

In AVR, Hardware, Software on Jun 20, 2010 at 00:01

Reducing power consumption is fairly tricky, as you can see in the many previous posts about this topic. And to be honest, I haven’t quite gotten to the point where I want to be with the Room Board. My first “major” (ahem) setup with about a dozen nodes around the house didn’t quite go as I had hoped. Most batteries were empty within a month. A few nodes are still going, but those are hooked up to power adapters…

I’d like to revisit this issue and try to improve things a bit. To make the rooms sketch perform better, and also to make the code structure a bit clearer. The current rooms code is quite complex and hard to follow.

But before messing with the rooms.pde sketch, let’s tackle something simpler: the wireless sensor node based on the Pressure Plug, as described here, and then simplified here. I’ll use that last version as starting point.

The first point to note is that to get a substantial first power reduction, you have to focus on the portion of the code where it’s spending most of the time. Which, in the case of “bmp085demo”, is here:

That’s right: it’s waiting for the next second to “happen”. And even with a slow’ish sensor such as the BMP085 at maximum resolution, it’s spending more than 90% of its time there… waiting!

I’ll use an approach which might be a bit surprising: let’s not change any of the current logic. The idea is that once we’ve done our thing for the current second, we can go into low power mode, as long as we make sure to get back to normal operating conditions in time for the next second.

So what we’re going to do is add some code to the end of the loop() function. It’s functionally equivalent to adding it at the start, since loop(), eh, loops – but I think it makes a better point.

The end of loop() used to look as follows:

I’m changing it to this:

IOW, at this stage all the hard work has been done. We wait a bit for all interrupt-driven I/O to complete (serial and RF12). And then we need to figure out how much time remains until the next second. The power saving happens by spending that time in power off mode.

But this requires some preparation. When inducing a comatose state like this, you have to make absolutely sure that something is still able to get you out of coma and back up and running again. This is what the ATmega’s “watchdog” is for: we set it up to wake us up in 16 milliseconds, just before entering sleep mode. And then we keep doing that until it’s almost time to take another reading. The actual watchdog interrupt handler does nothing, btw – all we want is to get back out of power down.

Note that the radio also needs to be turned off and back on again. It’s the biggest power consumer when enabled. Turning it off and going into power down mode is what lets us go from a tens-of-milliamps current drain to a tens-of-microamps current drain.

All the logic for this is located in the loseSomeTime() function, which was adapted from a slightly different version in the rooms.pde sketch:

And that’s about it. The average power consumption of this sensor node will go down by an order of magnitude. It’ll still be 1..2 mA, but it’s a major improvement: this node should now run 2..3 months on AA batteries. The source code for bmp085demo.pde has been updated.

I’d like to stress that such gains require very little effort for many types of sketches. All you have to do is figure out where the sketch is spending most of its time, and deal with just that part of the code. Getting into yet lower power consumption levels would require more work.

## Using LiPo batteries

In Hardware on May 29, 2010 at 00:01

The latest revision of the JeeNode USB includes a LiPo battery charge circuit:

The “+5V” pin is the incoming pwoer from the USB bus, it goes directly to the MAX1555 LiPo charger. From there, the PWR line is fed, so this will normally be at 4.2V when no battery is attached. That PWR voltage in turn is fed to the on-board 3.3V regulator for the ATmega and RFM12B.

This design was chosen because it lets you very easily add a LiPo battery: simply attach it between PWR and GND. There are no switches or switch-over issues: plug-in to charge, then use unplugged as needed.

I’m going to use the Carrier Board as example, and I’m going to use a LiPo battery from SparkFun, which comes with a polarized JST plug already attached. Here is the matching socket:

What we need is a spot where this socket can be soldered on. Ah, here it is, on the PWR/SER/I2C connector:

The trouble is that the pins are not 0.1″ apart as needed here, and that the socket won’t be usable if mounted sideways. So I cut off the plastic tabs and bent the wires a bit differently (taking care not to bend too much, because they break very easily):

The result fits perfectly on the Carrier Board, with the whole setup in turn fitting very nicely in the ABS box:

I’m using an 850 mAh LiPo cell.

One point to note is that the charge current from the MAX1555 is fixed at 280 mA. The rule for LiPo battery is to charge them at no more than 1C, i.e. a 850 mAh cell shouldn’t be charged with more than 850 mA. So in this case, we’re fine, with an estimated charge time of 3..4 hours for a fully discharged battery.

IOW, don’t use this setup with LiPo batteries smaller than 300 mAh or so.

Another thing to avoid with LiPo batteries is to discharge them below about 3V. You can check rf12_lowBat() from the RF12 library once in a while. It reports when the voltage at the RFM12B drops below 3.1V, i.e. around 3.2 .. 3.3V on the LiPo. Once this happens, power down the ATmega + radio to avoid draining the battery any further.

Why all the fuss? Because LiPo batteries can burn and explode, when improperly handled. There’s a lot of energy in there, and at some point things can exceed the design limits. Search for “lipo explode” on YouTube…

There are really only two issues: 1) the short-circuit discharge current can be extremely high (20C, i.e. 17 Amps with the above unit!), so short circuits and polarity reversals must be avoided at all times. And 2), charging should be done with the proper circuitry, such as the one in the JeeNode USB.

Why use LiPo’s? Well, they are very compact for the amount of energy they store, they can be recharged over and over again, and they have a very low self-discharge rate (i.e. long shelf life when not used).

When used properly, LiPo batteries are a great way to power JeeNodes, etc.

## Lithium node

In Hardware on Jan 23, 2010 at 00:01

The 3.6 long-life / low-current OmniCel lithium batteries just came in.

Say hello to the latest room node at Jee Labs:

Colorful, eh? ;)

The battery is connected directly to +3V and GND, i.e. after the voltage regulator, since its operating voltage is an excellent match for the ATmega and RFM12B.

No motion sensor was needed for where this node is going (and I didn’t have any left anyway), so that reduces the current draw by some 40 µA. Average should be somewhere around 200 µA – as mentioned before, this can no doubt be optimized further.

Since there are no motion triggers, this node will only send one or two packets per minute – the battery should last well into 2011, according to the specs.

Unless the receiver is turned off and this thing starts re-transmitting all the time. I really need to fix that flaw…

For a fun enclosure, check out the Airwick post by Szymon Kobalczyk on the Jee Labs discussion forum.

## Sleep mode fix

In AVR, Software on Jan 20, 2010 at 00:01

The Rooms sketch (latest code here) had problems with the sleep mode added about a month ago:

The first value is the current consumption in µA.

For some reason or other, the node would stop working and enter a permanent-on mode, drawing over 7 mA and draining the battery in a matter of days. Not good.

It seems to be related to the way the power down mode was implemented. To get absolutely rock bottom power draw, I was using the RF12’s watchdog timer. The ATmega watchdog time draws slightly more current and isn’t quite as configurable.

I’ve now reverted to using the ATmega watchdog anyway. Here is the modified logic:

The watchdog is set to interrupt every 16 milliseconds, constantly. When the node is powered down, this will wake it up again. What the new loseSomeTime() code does, is simply to power down a couple of times, until the target delay time has been reached. There is some inaccuracy in these timings since the watchdog timer is free-running, but this should not matter too much when waiting for a second or so.

The new code has been running fine for over a day on six nodes. Here’s a sample from my power tracker:

That’s 110 µA right now, 265 µA in the last minute, and 230 µA in the last hour.

At around 250 µA average, the power consumption is a bit higher than before, but my main concern is first to get the nodes running reliably. Even @ 250 µA, the AA batteries should last several months.

The average power down current draw is 110 µA/sec, 40 µA of which is due to the PIR sensor. The total current draw while transmitting is around 29 mA – during reception it’s about half, i.e. 14 mA. Still, due to the very brief on-times, this current consumption averages to only about 400 µA during 1 second for a normal send + ack sequence. Under optimal RF conditions, the long-term average consumption of a node will be under 150 µA. I’m confident that further optimizations could reduce this to well under 100 µA.

But there is one known flaw, which can be observed to happen once in a while: the nodes always wait for an ack in full-power mode, i.e. with the receiver on. This will normally be within milliseconds, but if the connection is flakey or if the central node is unresponsive, then nodes can spend a great deal of time in full-power mode. This needs to be fixed one day.

I’ve started re-flashing all the room nodes and replacing their dead batteries, here at Jee Labs – let’s see how it goes this time around.

## Power tracker – software

In AVR, Software on Dec 22, 2009 at 00:01

Yesterday’s post described a small circuit to track power consumption of JeeNodes to help optimize sketches for minimal power consumption.

Let’s put that circuit to use, with a bit of software to measure actual power consumption. The basic idea is to continuously measure current and then integrate these measurements to determine the sum of all power consumption intervals, regardless of levels.

The reason for this is that we’re not really interested in current draw but in the amount of charge consumed by the JeeNode. As far as the battery is concerned, drawing 1 mA for 1 hour is the same as drawing 100 µA for 10 hours (in the ideal case, anyway). The fancy way to say this is that we need to measure Coulombs, not Amps. Or rather micro-Coulombs, i.e. µC. That’s really easy once you realize that 1 µA is the same as 1 µC per second. Or to put it differently again: 1 mAh = 3600 mC. So a 1000 mAh battery is really nothing but a 3600 C charge.

Ok, back to the problem at hand: measuring average current draw per second.

Here is a simple sketch which does all the auto-ranging and integration:

It reports averaged power drain in µA/sec (the second value is the number of samples per second). The 10% correction which I had to apply in my setup could be due to a number of factors – most likely it’s due to resistor tolerances (they are all 5%).

Here’s an interesting case with the latest rooms node:

As you can see, the baseline power drain is a fantastically low 56 µA/sec in this case, but once or twice a minute it goes up to 14 mA/sec for several seconds. Not sure what’s going in here – need to investigate (now that I can!).

It would be nice to automatically detect the baseline, i.e. the average low-level sleep consumption, and things like the peak current and the percentage of the total consumption caused by such peaks. Extending the software to handle this is more work.

With slightly more elaborate software, it will be possible to place the power measurement plug between the measuring JeeNode and the JeeNode under test, and then leave it alone. A 1-day or 1-week average should give an excellent estimate of battery lifetimes.

## Power consumption tracker

In Hardware on Dec 21, 2009 at 00:01

After the recent battery life estimation and refinement posts, I wanted to create a more permanent and more automated setup for monitoring the total power consumption of JeeNodes. I expect to be repeating these power usage optimizations regularly, with new sketches.

Here’s the idea. A little interface to let one JeeNode (or Arduino, whatever) monitor the power consumption of another. This ought to provide a fairly accurate measurement within a day or so.

First the schematic:

This is a “low-side” current meter. In fact there are two of them in series, one with a 60 mA range, the other with a maximum range of about 1 mA. So this setup can measure up to 60 mA with approximately 1 µA resolution at the lower end. These ranges could easily be changed by adjusting the 5 Ω (2x 10 Ω) and 270 Ω resistors.

The low range resistor has a forward-biased diode, which limits the total voltage drop over it to under about 0.6V. This means that the total voltage drop over the measurement circuit will stay under 1V for currents up to 60 mA. With a 5V supply, that leaves about 4V to be supplied to the JeeNode being tested – more than enough headroom for the 3.3v regulator to do its thing.

Note that there is a drawback to low-side current sensing: the “ground” level supplied to the test circuit isn’t really ground. It’s floating “somewhere” above zero, and what’s worse is that the actual level will depend on the amount of current drawn. But in this case it doesn’t really matter, since the test circuit isn’t connected to anything else anyway (we’re doing all this to measure a battery-power wireless system, after all).

Two op-amps are used to amplify the 0 .. 0.3V signals 10 times. A neat trick: the low range op-amp (on the right) nicely compensates for the floating reference level from the high-range resistor by using that as reference for its negative input. So basically, these two op-amps generate two analog voltages in the total range of 0 .. 3.3V. I picked the OPA2340 CMOS op-amps because they can operate at 3.3V and can output rail-to-rail voltages. They also happen to draw very little current.

Here’s a custom-made JeePlug with all the above components:

Note: I don’t know what got into me while building this plug, but the pins on the port connector are all reversed. So I’m forced to plug this thing in the other way around. Doh!

This is only half the story. Tomorrow: the software side of power tracking.

## Battery life – refinement

In AVR, Hardware, Software on Dec 19, 2009 at 00:01

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:

1. The biggest drain determines battery lifetimes.
2. Measuring actual current profiles always beats guessing.
3. 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.

## Battery life estimation

In AVR, Hardware, Software on Dec 18, 2009 at 00:01

To get an indication of battery power drain, I measured the voltage drop over a 47 Ω resistor in series with the 5V supply, using a JeeNode with Rooms Board and the latest version of the “rooms” sketch.

Here’s the blip I see, once a second (100 mV/div and 20 msec/div):

That’s a 40 msec pulse of about 5 mA, in other words: 5 mA during 4 % of the time, which averages out to around 200 µA current draw continuously. Not bad, but not stellar either: it’s 4 times the sleep mode current.

Every once in a while, a much longer and bigger spike shows up:

Which looks like roughly 350 msec @ 12 mA.

Let’s assume the big one is a real transmission. It sort of fits: the spike at the end is a brief transmission at ≈ 35 mA total, followed by a 20-ish mA period of reception (waiting for the ack to come in).

Very roughly speaking, the area of that extra spike at the end is about the same as the 5-to-10 mA step at the start of this period. So as an estimate, we’re consuming about 12 mA during 350 msec – let’s round down to 300 msec.

Let’s also assume these bigger current patterns happen every 30 seconds, when the node is reporting changed values (everything other than motion gets reported at that rate in the latest “rooms” sketch).

So 1% of the time (300 ms every 30s), power consumption is 12 mA. This averages out to 120 µA continuous current consumption.

In other words: a JeeNode running this latest rooms sketch with the SHT11 and ELV-PIR sensors, is consuming roughly 200 (blip) + 120 (spike) + 50 (sleep) = 370 µA.

Using a 2000 mAH 3-cell AA battery, this should lead to a 225-day lifetime – over 7 months.

Can we do better? Sure.

It’s basically a matter of figuring out what’s going on during those 40 and 350 msecs, respectively. Interestingly, more can be gained by improving non-transmitting “blips” than twice-a-minute high-power RF packet exchanges.

Do those 40 ms @ 5 mA every second look a bit suspicious? Yep – that’s the “idling” power level. What happens is that I was a bit too pessimistic in the time spent in sleep mode. This was the code:

Looks like this is about 40 ms off, and so the code ends up waiting for the 1 sec timer to expire… in idle mode!

Let’s change this to end up closer to the desired time:

Here’s the new blip (different scales):

We’re down from 40 to 10 msec blips – tada!

That translates to an average 50 µA current draw from the blips, bringing the total down to 220 µA. Which translates to a 375-day battery life: over a year!

Now we’re cookin’ … but could we do even better? Sure.

Note that only the 2 ms spike at the end of the 5 mA blip is the actual active period. The time up to then we’re just waiting in idle mode – and wasting power.

We could shorten the sleep timer to 994 ms, since we don’t care whether readings are taken exactly 1 second apart. Now the RFM12B-based watchdog timer will wake us up just 2 ms short of the target time. And sure enough, the 5 mA blip is down to around 3 ms – shown here with an even further expanded time scale:

But that’s silly. We’re tweaking a millisecond timer, and we’re not even interested in an “exact” 1000 ms cycle in the first place! It makes much more sense to just use the RFM12B wakeup timer to get us close to that 1 second cycle, and then immediately take a measurement. Here’s the corresponding code change in periodicSleep():

Does this make a difference? Definitely:

One final remark: the above battery lifetime estimates do not take into account the increased power consumption when motion is detected and more packets are sent (up to once every 5 seconds). On the plus side, when no light / temperature / humidity changes happen, the packet frequency will drop further, to once-a-minute.

The above changes have been checked into the source code repository.

Update – I just found out that the DSO-2090 scope has a high-pass low-pass filter option:

Sure wish I’d found out about that feature sooner… it’s so much more informative: the initial ramp is probably the clock starting up, and the little peak could well be the LDR pull-up during ADC conversion!

In AVR, Hardware, Software on Dec 16, 2009 at 00:01

With the new easy transmission mechanism and the low power logic implemented, it’s time to revisit the “rooms” sketch, which I use for all my house monitoring nodes based on the Room Board.

I’ve wrapped the code used in POF 71 a bit further, with these two extra functions:

With this, the main loop becomes very simple – even though it will now power down the RFM12B and the ATmega328 whenever there’s nothing to do for a while:

The lowPower() and loseSomeTime() code is still the same as in POF 71 – this is where all the hardware low-power trickery really takes place:

Note that these need an “#include <avr/sleep.h>” at the top of the sketch to compile properly.

I’ve also disabled the pull-up resistor on the LDR while not measuring its value. This drops power consumption by over 100 µA, depending on actual light levels.

A quick measurement indicates that power consumption went down from 20 mA to some 50 µA (much of that is probably the PIR sensor). These are only approximate figures, because my simplistic multi-meter setup isn’t really measuring the charge (i.e. integrated current draw), just the current draw while in sleep mode.

These changes have been checked into the repository as “rooms.pde”.

This code isn’t perfect, but since “perfection is the enemy of done” I’ll go with it anyway, for now. One difference with the original rooms sketch is that the motion sensor is not read out as often so brief motion events might be missed. Another issue with this code is that if the central node is off, a lot of re-transmissions will take place – without the node going into sleep mode in between! IOW, a missing or broken central node will cause all remote nodes to drain their batteries much faster than when things are properly ack’ed all the time. Oh well, let’s assume this is a perfect world for now.

With these levels of power consumption, it’s finally possible to run room nodes on battery power. I’ll use some 3x AAA packs, to see what sort of lifetime this leads to – hopefully at least a couple of months.

Will report on this weblog when the batteries run out … don’t hold your breath for it ;)

Update – I just fixed a power-down race condition, so this code really goes back to sleep at all times.

## Low power mode again

In AVR, Software on Dec 9, 2009 at 00:01

After yesterday’s Wireless Light Sensor was announced, I wanted to push a bit more on the low-power front.

The POF described two simple tricks to get the power consumption from 19 to 3 mA, roughly. It turns out that a single extra step will get the idle consumption down to some 20 µA. That doesn’t mean we’re getting a 15-fold battery lifetime increase, because I’m measuring the current at idle time but not accounting for the brief periods of high-current activity which also occur. But it’s a major reduction in power consumption.

Here’s how … but this requires going a bit deeper into some low-level AVR/ATmega chip features.

First, here are some utility functions we’re going to need:

The lowPower() routine disables the ADC subsystem and then enters the specified low-power mode in the ATmega. Once it resumes, the ADC subsystem setup will be restored to its previous state.

The loseSomeTime() does just what is says on the box: go into comatose mode for a more-or-less controlled amount of time. The trick is to activate the RFM12B watchdog just before passing out. This leads to larger power savings than we would have with the ATmega’s watchdog, btw – and it’s easier to implement.

The complication is that we risk losing all track of time. It’s a bit hard for an ATmega to count heartbeats when its heart has stopped beating – not only are there no beats, it’s also stripped of its counting abilities while in coma…

So instead, we estimate just how long we’ve been away from the watchdog time chosen for the RFM12B, and correct the milliseconds timer built into the Arduino. That’s what the “timer0_millis” stuff above is about. It will not be quite as accurate as before, but that’s probably acceptable for a sensor node like this one.

The last issue is that we need an indication about how long we can go comatose. I’ve added a “remaining()” member to the MilliTimer class to obtain this information.

Now, all the pieces are in place to change the code in the Wireless Light Sensor from this:

.. to this:

So there you have it. Most of the time between each measurement once a second, the node will now go into a very low-power mode of around 20 µA. My current measurement tools are inadequate to measure exactly what amount of charge is being consumed, which is what this is really about. So accurate battery lifetime calculations are not yet possible – but I expect it to be in the order of months now.

I’ve updated the Wireless Light sensor POF to point to this post and include this trick.

## Ligthy power save

In AVR, Software on Jul 5, 2009 at 00:01

Getting the power consumption down of yesterday’s “Lighty” example turns out to be quite a challenge.

One thing to do is to separate out the logic for enabling the different sensors, and extending it to also support disabling all of them:

Powering down completely works best when all internal peripherals are also turned off, as implemented in the following code:

Now the trick is to enable some interrupt source to take us out of this deep sleep phase again. This could be the ATmega watchdog, but the radio watchdog uses even less power, so here’s how to stay off for about 4 seconds:

So far so good. This disables all power consuming sensors and internal circuits, preps the radio to wake us up in 4 seconds, powers off, and then reverses the whole process.

Bug there is a bug in all this – somewhere… From some earlier experiments, I would have expected to see a power draw of a few microAmps with this code. But for some reason, it never drops below 2.7 mA, i.e. still “burning” 1/10th of full power!

I haven’t been able to figure out yet where these milliamps are going :(

For the sake of argument, let’s assume this works properly. Then the next problem will come up, which is that measuring and sending packets every 4 seconds drains more power than I’d like to. It takes several milliseconds to measure all readings and send out a packet. But who needs readings every 4 seconds?

So the solution to this is to just sleep a bit longer, using the 4-sec wakeups to quickly read-out some sensors, and calculate their averages. Here’s is the final loop of the power-saving “LightySave” sketch:

This will integrate readings for 75x 4 seconds, i.e. 5 minutes, and then send out a single packet. Note how the power-hungry radio module is only enabled at the very last moment. All we have to do is make sure it’s ready to send, then send one packet, then wait again until the send is complete.

Then the loop restarts, sleeping in low-power mode, etc.

Only issue is to find out where the 2.6 mA are going! I’ll try to figure this out, and will post here once fixed …

## New RF12 sleep support

In AVR, Software on May 23, 2009 at 00:01

The RF12 driver has been extended to support power down as well as wake-up.

This example uses the RFM12B wake-up timer to generate an interrupt in about 1 second, then powers down, then leaves the radio off once power is back up:

That last call is important, because otherwise if the system happens to power up due to some other trigger, then the wake-up interrupt may happen later and cause problems. This way, regardless of why the system came back up, we make sure that the RFM12B wake-up interrupt stays off. The radio is still off at this point.

The argument to rf12_sleep() is a time value, in units of 32 ms. The maximum value is 127, i.e. 4 about seconds between wake-ups. If you need longer sleep times, change the logic to go back to sleep right away until the proper amount of time has elapsed.

To turn the radio back on, use “rf12_sleep(-1)” to start listening to packets again after the next rf12_recvDone() poll. Since the RFM12B consumes a fair amount of power, it’s best to wait with this right until you’re ready to send out a packet.

Here is the new code, which is now included in the updated RF12 driver:

The RF12 driver software is available over here or as ZIP, this is an Arduino-compatible library.

## Power consumption – more savings

In AVR, Hardware, Software on May 16, 2009 at 00:01

Let’s get that JeeNode power consumption down

The no-savings baseline from two days back was 10 mA, with a few simple measures getting it down to 1.31 mA, i.e. waiting in idle mode with the pre-scaler set to 64 and turning the RFM12B clock off.

It turns out that the ATmega328 is quite a bit more power efficient in that mode, the same sketch consumes 0.67 mA, i.e. half that of an ATmega168. Great – that’s an easy gain. Unfortunately it doesn’t carry over as much to power down mode: 125 µA versus 137 µA. There is still some unexplained power use there – maybe some of the circuits need to be turned off explicitly, or some more output pins floated.

Anyway, the next idea to go beyond 1.31 mA is to use the watchdog timer for idling away in power down mode. The basic code structure will be as follows:

Ooh, wait – turns out that there is a simpler way, which doesn’t require changing the main application logic after all. We can let the watchdog generate an interrupt without resetting the system. Here’s the code I ended up with after some experimentation:

Note the added dummy watchdog interrupt routine. Without it, the code apparently enters a nasty infinite loop when the watchdog fires, which is hard to get out of – even after a hardware reset.

Usage: 139 µA while waiting – 99% of the time. Great.

The code can actually be streamlined a bit – simply leave the watchdog running to pull the processor out of power down mode once a second:

But there’s more. The ADC can be disabled to reduce the power drain even further:

Now usage drops to 24 µA while waiting. Cool.

One last change is to disable the brown-out detection, which in turn disables the internal voltage reference. Changing the high fuse from 0xDD to 0xDF drops total power usage to a diminutive 6.8 µA. Perfect.

So there you have it – 1500 times less power usage!

Update – see the discussion in this post for a change which gets this down to 3.7 µA …

Update 2 – changed the low fuse from 0xFF to 0xEE, i.e. 64 µs start-up i.s.o. 1+64 ms (ok for resonator, not ok for a crystal). This will help get the power up duration down once I start looking into it.

## Power consumption – subtle bugs

In AVR, Software on May 15, 2009 at 00:01

Yesterday’s code has several bugs:

As already mentioned, a delay is needed to let the serial data leave the USART before the pre-scaler change messes up the clock and baudrate. But there are also two other serious problems:

• the “limit = millis() + …” expression will overflow and fail (after about 49 days)
• the “millis() == limit” condition can “miss a beat”, leading to an almost-infinite loop

Both bugs can be fixed by carefully rewriting the code:

The differences are subtle, but essential. Without it, the loop will get stuck within just a few seconds of starting the sketch. With the above fixes it’ll run properly forever… I think.

## Power consumption – baseline

In AVR, Software on May 14, 2009 at 00:01

Ok, first step in lowering JeeNode power consumption is to establish a baseline.

Here is the original code, the first few lines of the loop that is – the rest is the actual sensor readout and calculations, which take about 10 milliseconds:

Usage: 9.80 mA (slightly different from yesterday’s post, hooked up to USB from now on).

First change is to make the delay loop explicit:

Usage: 10.05 mA – no idea why it’s slightly higher. Anyway 10 mA will be used as baseline – this is the current drawn before any power-saving measures are introduced.

First step: lower power use by putting the processor in idle mode while it’s waiting for the next readout time. Included “avr/sleep.h” and changed the loop to be as follows:

Usage: 5.58 mA – it works, cool!

Next idea is to lower the system frequency, but only while waiting – so that readout, processing, and serial I/O remain unaffected:

Usage: 1.99 mA – whee! But there is a small gotcha – the system now goes into slow mode before the serial port has finished transmitting. A “delay(3)” at the end (or start!) of the loop is needed to fix this.

For comparison: with just the pre-scaler and no idle mode, usage is 2.15 mA – so the bulk of the savings comes from slowing down the system clock. Idle mode saves roughly 10% at lower frequencies.

One more important saving is possible due to the onboard RFM12B radio module, which powers up with its 10 MHz crystal clock running. Adding a bit more code to access the radio and disable its clock lowers power usage from 1.99 mA to 1.31 mA.

So these three simple measures combined already lead to a 7.5-fold power reduction: “waiting” a bit more carefully and turning off the RFM12B. All without affecting the main application code in any way.

As for the bottom line: putting the processor in power down (from which this code won’t ever wake up) uses 137 µA – and removing the MPU chip brings it to 17 µA. Note that with 140 µA average usage, a JeeNode can run for two years on 3 standard AA batteries.

It ‘s possible to reduce the power consumption from 1.31 mA to the µA range by powering down the processor and using the watchdog timer to wake it up – but that requires another set of changes to code and fuses – stay tuned…

Update – see this more recent post for additional details.

## Power consumption

In AVR, Hardware on May 13, 2009 at 00:01

This contraption:

… when connected as follows:

… makes it easy to measure the supply current, with a BMP085 pressure sensor hooked up in this case:

Just under 10 milliamps, as you can see. That’s just the JeeNode running the BMP085 demo at 16 MHz, sending a new reading over the serial port every second. The RF12 module has not been turned on.

If the JeeNode is to be used for a WSN, then it will have to get its power consumption down. Way down, in fact…