Debugging power usage
In a previous blog post I mentioned how a small timer I made kept eating batteries unexpectedly. With no way to analyzer the power consumption, the problem is almost impossile to debug. That is why I started working on a self-made power analyzer. The self-made power analyzer is now fully functional.
![Power analyzer](/_astro/case.CCyQZm1L_cFaGa.webp)
Using PulseView its now trivial to inspect the power usage of any low-power device. Just hook it up and press the Start
button! So I attached the timer which mysteriously ate batteries.
![The timer attached](/_astro/timer_debug.B64SGHoi_2a3EuI.webp)
The provided 3.3 Voltage supply makes it extremely easy to analyze most microcontrollers. I just connected it to the battery terminal of the timer and opened PulseView. I selected the Nori power analyzer
, now there was only one thing left to do, press start and use the device for a bit. What I saw completely explained why my batteries kept running out in a few weeks.
![Power usage before](/_astro/before.zoK8nUjb_ZmOY0f.webp)
Its using a whopping 1.3 mA while idle! A typical 9V battery only contains 500mAh. Lets calculate the battery life.
idle_consumption = 1.3mA
battery_capacity = 500mAh
idle_hours = battery_capacity / idle_consumption = 384.6 hours
idle_days = idle_hours / 24 = 16 days
Only 16 days!? Thats is extremely disappointing. The idle power consumption is way too high.
Lets check out the code (simplified example) that the microcontroller is running:
clock.SetMode(Nori::TimerMode::CTC)
->SetClockSource(Nori::ClockSource::Div256)
->SetLimit((uint16_t)31250)
->AttachInterrupt([]() { timer.Tick(); });
set_sleep_mode(SLEEP_MODE_IDLE);
while (true) {
sleep_mode();
set_sleep_mode(SLEEP_MODE_IDLE);
}
Wait a minute! maybe SLEEP_MODE_IDLE
is not as efficient as expected. However SLEEP_MODE_IDLE
is needed to wake the atmega using the timer. What happens if we only use the SLEEP_MODE_IDLE
while the timer is running, and SLEEP_MODE_PWR_DOWN
otherwise.
while (true) {
if (timer.CanShutdown()) {
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
} else {
set_sleep_mode(SLEEP_MODE_IDLE);
}
sleep_mode();
}
Lets check the new power usage using the power analyzer.
![Power usage after update](/_astro/after.CNLDkEdC_2rYkMV.webp)
Wow! only 0.011mA is used while the timer is idle now! Lets calculate the battery life using the new power consumption.
idle_consumption = 0.011mA
battery_capacity = 500mAh
idle_hours = battery_capacity / idle_consumption = 45454.5 hours
idle_days = idle_hours / 24 = 1893.94 days
idle_years = idle_days / 365 = 5.18 years
That is an improvement of nearly 120 times the original battery life! (If the timer is idle at all times). To improve the battery life even further, I also disabled the backlight from the display.
![Circuit boards](/_astro/pcb.BoUsycdB_Z1fpI6M.webp)
Ofcourse everything is free and published online. The source files of the power analyzer can be found here.