Power optimizing your application

Whenever new features are developed, chances are that some power ends up being “wasted” or used unoptimally. Generally the process for power optimizing application starts with power profiling to identify which features of the code actually use most power.

We take RuuviTag firmware version 2.1.0-alpha as an example, and work our way to 2.1.0-beta which is power optimized. Since the RuuviTag FW v1 we have added NFC, GATT profile, RTC, and accelerometer interrupts. Additionally there has been a lot of work “under the hood” in preparation for new features on roadmap. Let’s see how the power consumption looks!

RuuviTag power consumption
Power consumption of RuuviTag FW V2.1.0-alpha

On a quick glance we can see that a few things are “off”. Average consumption is almost 80 μA, which is a 166% increase since FW v1. This would translate to maybe one year of battery life, which is uncomfortably low.

First thing to catch our eye is the transmission interval. The FW v2 boots in raw mode and should transmit at 1 Hz, however transmissions are obviously at 2 Hz. This is leftover from URL mode, let’s fix it.

TX interval
TX interval is now fixed, reducing current consumption by 20 μA. There’s something else, though

We shaved 20 μA off by fixing bug with transmission interval, not bad. However, there’s something strange going on at 1 Hz interval. For some reason there is a relatively long lasting spike in current consumption. Is it the sensor reads? Or maybe something in updating the transmitted data takes long?

One micro-optimization I did was to run BME280 in “normal mode”, which has the sensor starting samples autonomously approximately once per second. This avoids us spending precious microseconds used to manually start samples. Something comes up:

Current spikes
Current spikes are no longer synchronized to data transmissions

We have found out the culprit for the long-lasting power consumption: BME280 is doing something silly. It turns out that the code had the 16x oversampling still enabled after the previous experimentation with BME280. After removing the oversampling and leaving infite impulse response-filtering we get a lot improved consumption values:

Chart indicating power consumption
We’re down to 28 μA which meets FW v1 consumption

We can still see the BME280 reads, but they’re a lot faster which means that the power consumption is reduced by 30 μA. Now we’re at 28 μA,which meets the RuuviTag FW v1 performance.

After power profiling our application again we get a pie chart of current consumption:

RuuviTag FW 2.1.0 beta current consumption

Getting current consumption under 10 μA would be “the holy grail”, as then the tag life could reach the shelf-life of 1000 mAh battery itself. However we’d have to make some compromises, such as sample BME280 and LIS2DH12 less frequently as well as advertise at rarer rate. The baseline consumption would also need to be optimized.

For now, we can consider base mode of the RuuviTag FW to be a good compromise between features, speed and battery lifetime.