Getting low power consumption, with external sensors

Hi,

Our application is based on the asset tracker, and has a similar overall process of waking up, taking sensor readings and going back to sleep. This application is used in a number of our products, some of which need to run on small batteries. Over the last week I've been working on getting power consumption down - and I'm currently at 20 uA including the other devices on our board (like high-side switches and external flash memory). 20 uA is awesome!

However, I now need to introduce back the functionality - like measuring external sensors using I2C. I see some sensor drivers, for example the INA219 that I'm using to start with, supports Zephyr's CONFIG_PM_DEVICE option and handles power down. When asked, the INA219 driver will set the device into a power down mode - and I have tested this and found that the INA219 itself uses very little current when in this mode.

How do we go about making this work with the nRF9160? For that option to work, we need the Zephyr Power Manager to be running with a power policy - and I note the CAF Power Manager actually disables that by requiring CONFIG_PM_POLICY_CUSTOM and returning NULL back to the Zephyr Power Manager. Instead, I'm using the residency-based policy (see here: System Power Management — Zephyr Project Documentation) and I've added a couple of power states to my device tree:

/ {
    power-states {
        active: active {
            compatible = "zephyr,power-state";
            power-state-name = "active";
            min-residency-us = < 1000 >;
        };
        idle: idle {
            compatible = "zephyr,power-state";
            power-state-name = "suspend-to-idle";
            min-residency-us = <2000000>;
            exit-latency-us = < 1000 >;
        };
    };

    cpus {
        cpu@0 {
            cpu-power-states = <&active &idle>;
        };
    };
};
When I run the debugger, I can see Zephyr actually runs the function with an initial tick value of 7FFFFFFF (-1, or K_TICKS_FOREVER). Strangely, that doesn't seem to select my first policy (active) and decides to shut down the INA219 on boot - potentially before the initialisation even runs.
Before I spend too much time going down this route, I wanted to ask and see what the Nordic-recommended approach was. How should I be preparing by devices for power down? Is there an event I can capture (like the power down event from CAF), and then somehow ask the external sensors to power down using their PM integration? Does Nordic have any example code where they use a high-current sensor (600 uA is considered high in my application!) and shut it down before sleeping?
I notice there's no nRF91-series example code (in my NCS 2.2.0) showing how those CPU power states are used in the device tree - but I also don't see any using that CAF Power Manager (machine_learning targets the nRF53, and nrf_desktop targets the nRF52).

Searching for power savings, I find a number of references to this article: Measuring PSM idle current on the nRF91 DK - Blog Archives - Blog - Nordic DevZone (nordicsemi.com). This article was really useful in achieving my 20 uA figure (I was able to get even less by removing all the other components on my PCB) - but that relies on disabling a lot of things at compile-time and doesn't explain the power management of external devices.
I'm planning on continuing to investigate these cpu-power-states in Zephyr but I would appreciate any advice you can provide!
Kind regards,
Dan
Parents Reply Children
No Data
Related