Computing stuff tied to the physical world

Watchdog tweaking

In AVR, Software on Apr 1, 2012 at 00:01

The other day, I mentioned a way to keep approximate track of time via the watchdog timer, by running it as often as possible, i.e. in a 16 ms cycle.

This brought out some loose ends which I’d like to clean up here.

First of all, the loseSomeTime() code now runs 60 times per second, so optimizing it might be useful. I ended up moving some logic out of the loop, to keep the time between power-down states as short as possible:

Screen Shot 2012 03 27 at 11 00 51

The result is this power consumption profile, every ≈ 16 ms:


That’s still about 22 µs @ 6.5 mA. But is it, really?

The above current measurement was done between the battery and the power supply of a JeeNode SMD. Let’s redo this without regulator, i.e. using a “modded” JeeNode with the regulator replaced by a jumper:


Couple of observations:

  • different ATmega, different watchdog accuracy: 17.2 vs 16.3 ms
  • the rise and fall times of the pulse is sharper, i.e. not dampened by a 10 µF buffer cap
  • new behavior: there’s now a 0.4 mA current during 80 µs (probably the clock starting up?)
  • that startup phase adds another 75 nC to the total charge consumed
  • note that there is a negative current flow, causing the charge integral to decrease

The worrying bit is that these two ways of measuring the current pulses differ so much – I can’t quite explain it. One thing is clear though: an adjusted fuse setting with faster clock startup should also make a substantial difference, since this now needs to happen 60 times per second.

A second improvement is to assume that when a watchdog cycle gets interrupts, half the time has passed – on average that’ll be as best as we can guess, assuming the interrupt source is independent:

Screen Shot 2012 03 27 at 13 17 55

The last issue I wanted to bring up here, is that small code optimizations can sometimes make a noticeable difference. When running the test sketch (same as in this post) with a 8192 millisecond argument to loseSomeTime(), the above code produces the following profile:


The reason the pulse is twice as wide is that the “while” in there now loops a few times, making the run time almost 50 µs between power-down phases. As Jörg Becker pointed out in a comment, the ATmega has no “barrel shifter” hardware, meaning that “shift-by-N” is not a hardware instruction which can run in one machine cycle. Instead, the C runtime library needs to emulate this with repeated shift-by-1 steps.

By changing the while loop from this:

Screen Shot 2012 03 27 at 12 18 20

… to this:

Screen Shot 2012 03 27 at 13 06 49

… we get this new power consumption profile (the horizontal scale is now 20 µs/div):


IOW, this takes 20 µs less time. Does it matter? Well, that might depend on who you ask:

  • Marketing guy: “50 µs is 67% more than 30 µs – wow, that means your sketch might last 5 years i.s.o. 3 years on the same battery!”

  • Realist: “50 µs i.s.o. 30 µs every 8 seconds – nah, those extra 120 nC or so will merely add 15 nA to the average current consumption.”

The moral of this story: 1) careful how you measure things, and 2) optimize where it matters.

Anyway, I’ve added all three changes to JeeLib. It won’t hurt, and besides: it leads to smaller code.

  1. That 0.4mA 80uS bump is curious. I’ve noted it as well in my power experiments. What I find most unusual about it is that it is so short. The default fuse bits are for 16K clock cycles when waking from powerdown, which would be 1ms @16MHz. Is your fuse set to 1K CK, which would be 62.5uS @16MHz? I’m just curious if your data correlates with mine.

    Also you can save a few clock cycles by removing the prrOff parameter to powerDown() as it currently has no effect. PRR is only used to disable units in active and idle mode.

    Datasheet: “Module shutdown can be used in Idle mode and Active mode to significantly reduce the overall power consumption. In all other sleep modes, the clock is already stopped”

    • Thx for the comment on prrOff, I’ve removed it. Not sure what my settings were on that node, sorry.

Comments are closed.