Sorry to bother everyone again. The following are some power consumption results that might be handy for some folks. I was looking at various discussions on Pico power consumption, plus the work of ghubcoder, and read discussions about sleep and dormant mode whatnot. But I didn't see anyone exploring beyond the usual modes discussed in the datasheet and SDKs. So I tested a few things and it turned out that I can actively run a Pico at XOSC 12Mhz at around 2-3mA. I haven't seen anyone talking about this. So, this is my report.
I wanted to build an environmental data logger for garden use. Picked BH1750 and HDC1080 for good quality data. They both worked with my Pico and are very low power, so my primary concern is Pico power consumption. I plan to use one 18650 LiFePO4 battery about 900mAh capacity. For now, I use a cheap USB gizmo (with units of 1mA) to measure ballpark power use.
In the following, there are also snippets of code. Since there is more or less one way of setting a configuration, such code is not copyrightable. Take it as public domain code.
I have a test program that does a few things, I will list two here: (A) Try to sleep, use sleep_ms() a lot. It's probably busy waiting in most of the modes. (B) Do active work, in this case some addition, R/W a 32KB table in SRAM. Measuring in 1mA units with a USB gizmo is not terribly accurate, but it's easy to set up the tests. Baseline power consumption of Pico board under test is:
Ballpark power consumption (mA): baseline, Pico running a default configuration
(A) sleep_ms() (probably busy waiting) = 19
(B) actively working on a 32KB table = 23
FIrst attempt: run everything at 48MHz like the example in the hardware SDK API documentation
Ballpark power consumption (mA): everything at 48MHz, USB PLL running
(A) sleep_ms() (probably busy waiting) = 8
(B) actively working on a 32KB table = 9
So a turned down Pico can get me at least 3 days of logged data with margin. The obvious takeaway is shutting down one PLL saves juice.
Second attempt: run at 24MHz. As mentioned in some discussions, the call below did not work with 12MHz for me, probably because this call is a PLL-enabled run mode. So let's try 24MHz.
Ballpark power consumption (mA): one-call setup 24MHz mode
(A) sleep_ms() (probably busy waiting) = 9
(B) actively working on a 32KB table = 10
Well, any savings from slowing down the system clock is offset by having two PLLs running. So if I need a low power USB mode, I would use the 48MHz configuration with one PLL. Initially I was quite happy with using 48MHz, but the XOSC 12MHz would be better. But I couldn't find any discussion on running a Pico at XOSC 12MHz. Apparently it's something that is not commonly done. All I found was the setting being used just before sleeping. Well, with 900mAh I'm not real concerned about deep sleeping. This brought me to ghubcoder's writings and sleep_run_from_dormant_source() in sleep.c.
Third attempt: doze run mode, running 12MHz XOSC
Ballpark power consumption (mA): 12MHz XOSC doze mode
(A) sleep_ms() (probably busy waiting) = 2-3
(B) actively working on a 32KB table = 2-3
That meets my needs very well, at least 7 days of data with margin, even when running all the time. So everything is run from the 12MHz XOSC and both PLLs are disabled. ADC and peripherals are running, but I've definitely only tested sleep_ms() and using a timer callback. USB is disabled of course. Seems stable to me, I have it running for about an hour now and I am leaving it plugged in. It's like doing most of sleep_run_from_dormant_source() but not the sleep part.
For include files, you will need all or most of the following:
For stuff that do not use a lot of processor power, 12MHz is plenty enough, especially for a dinosaur like me. For a lot of sequencing stuff, one does not really need max clock speed. From the datasheet, it seems to be a configuration that is allowed, but it's a little strange to me that it is not already implemented as a run mode in the SDK. That's about all I have to say. If there are mistakes in the above, please correct me. Thanks.
I wanted to build an environmental data logger for garden use. Picked BH1750 and HDC1080 for good quality data. They both worked with my Pico and are very low power, so my primary concern is Pico power consumption. I plan to use one 18650 LiFePO4 battery about 900mAh capacity. For now, I use a cheap USB gizmo (with units of 1mA) to measure ballpark power use.
In the following, there are also snippets of code. Since there is more or less one way of setting a configuration, such code is not copyrightable. Take it as public domain code.
I have a test program that does a few things, I will list two here: (A) Try to sleep, use sleep_ms() a lot. It's probably busy waiting in most of the modes. (B) Do active work, in this case some addition, R/W a 32KB table in SRAM. Measuring in 1mA units with a USB gizmo is not terribly accurate, but it's easy to set up the tests. Baseline power consumption of Pico board under test is:
Ballpark power consumption (mA): baseline, Pico running a default configuration
(A) sleep_ms() (probably busy waiting) = 19
(B) actively working on a 32KB table = 23
FIrst attempt: run everything at 48MHz like the example in the hardware SDK API documentation
Code:
// change clk_sys to be 48MHz, taking the 48MHz clock from PLL_USB clock_configure(clk_sys, CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX, CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB, 48 * MHZ, 48 * MHZ); // turn off PLL sys pll_deinit(pll_sys); // change clk_peri too clock_configure(clk_peri, 0, CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS, 48 * MHZ, 48 * MHZ);
(A) sleep_ms() (probably busy waiting) = 8
(B) actively working on a 32KB table = 9
So a turned down Pico can get me at least 3 days of logged data with margin. The obvious takeaway is shutting down one PLL saves juice.
Second attempt: run at 24MHz. As mentioned in some discussions, the call below did not work with 12MHz for me, probably because this call is a PLL-enabled run mode. So let's try 24MHz.
Code:
/* * turn down system clock to 24MHz, an allowed minimum frequency * by default, peripherals are then switched to the USB 48MHz clock */ set_sys_clock_khz(24 * 1000, false);
(A) sleep_ms() (probably busy waiting) = 9
(B) actively working on a 32KB table = 10
Well, any savings from slowing down the system clock is offset by having two PLLs running. So if I need a low power USB mode, I would use the 48MHz configuration with one PLL. Initially I was quite happy with using 48MHz, but the XOSC 12MHz would be better. But I couldn't find any discussion on running a Pico at XOSC 12MHz. Apparently it's something that is not commonly done. All I found was the setting being used just before sleeping. Well, with 900mAh I'm not real concerned about deep sleeping. This brought me to ghubcoder's writings and sleep_run_from_dormant_source() in sleep.c.
Third attempt: doze run mode, running 12MHz XOSC
Code:
// CLK_REF = XOSC clock_configure(clk_ref, CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC, 0, XOSC_MHZ * MHZ, XOSC_MHZ * MHZ); // CLK SYS = CLK_REF clock_configure(clk_sys, CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF, 0, XOSC_MHZ * MHZ, XOSC_MHZ * MHZ); // CLK USB = 0MHz clock_stop(clk_usb); // CLK RTC = XOSC (12MHz) / 256 = 46875Hz clock_configure(clk_rtc, 0, CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_XOSC_CLKSRC, XOSC_MHZ * MHZ, 46875); // CLK PERI = clk_sys clock_configure(clk_peri, 0, CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS, XOSC_MHZ * MHZ, XOSC_MHZ * MHZ); // turn off both PLLs pll_deinit(pll_sys); pll_deinit(pll_usb);
(A) sleep_ms() (probably busy waiting) = 2-3
(B) actively working on a 32KB table = 2-3
That meets my needs very well, at least 7 days of data with margin, even when running all the time. So everything is run from the 12MHz XOSC and both PLLs are disabled. ADC and peripherals are running, but I've definitely only tested sleep_ms() and using a timer callback. USB is disabled of course. Seems stable to me, I have it running for about an hour now and I am leaving it plugged in. It's like doing most of sleep_run_from_dormant_source() but not the sleep part.
For include files, you will need all or most of the following:
Code:
#include "hardware/pll.h"#include "hardware/clocks.h"#include "hardware/structs/pll.h"#include "hardware/structs/clocks.h"#include "hardware/xosc.h"
Statistics: Posted by katak255 — Thu Apr 25, 2024 8:37 am