-
Notifications
You must be signed in to change notification settings - Fork 518
More on Power consumption #165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thanks @pbecchi for raising this issue and share your experience with the power consumption. You are right with your observation, I will throw a bit more detail where I could.
I have also wanted to test more with power consumption and write an tutorial for it. But we are too busy for now with the upcoming nrf52840, which we will need do low power, so we wait until it comes out to test with. This will serve as notes to ourself to improve it later. |
Another way to reduce power is to go full event response aka callback and abandon the use of loop() with suspendLoop() call. ( I will take note myself for the tutorial, before I start to forget things) Also you may want to tweak the ble radio timing/parameter such adv, connection interval etc ... the full list and its affect (current save) will come later when I tested them with the bench ( we may go as far as low power profile with pre-configured parameter for user). There may be more trick, but I kind of forget, will get back to this when we are done with the nrf52840 :D |
@hathach Thanks for your replay! To be more precise on my previous message:
|
Yes, suspendLoop() will put loop() task in suspend and prevent it to execute. If you need it, so just use it if you need it. For the serial issue with power, currently I don't have any ideas why it behaves as such. I am quite sure to not print anything when debug=0. Although, I am too busy by now for upcoming nrf52840 to pull out nrf52dk to test this out. I am afraid you have to do it by yourself a little bit more until we release the nrf52840 board. Sorry since I only have 2 hands and 10 fingers :)) |
Thanks, I understand your problems..... So I will try to solve this power drain problem by myself and ...I will let you know!! |
thanks, please update here if you could find out anything. Low power is mostly software thing ( hw is often too obvious and spotted out soon enough). It needs a guideline and discipline to follow. Unfortunately, we haven't got the guideline yet ( just some above tips ) |
related to #51 |
I'd have one more data point on unexpected power consumption - FPU. |
superb !!! That is brilliant finding, we will note this and make sure including this in our soon-coming testing and tutorial. |
Interestingly enough, there seems to be (ifdef-outed) stub of the workaround in the waitForEvent implementation, as I have just found (looking into why my waitForEvent doesn't really sleep either, while delay() does pretty well) |
use delay for the sleep(), it is mentioned in my above comment. waitForEvent will probably be removed
For details: https://www.freertos.org/low-power-tickless-rtos.html |
I am moving towards tickless, though I wonder about threading model of the platform. Thanks. |
@Nenik it is rather simple, ble and soc run on their on thread, most of callback run on a worker thread ( some needs signature changes to be called in worker). Give me a couple of days, I will answer it more details in the forum topic. |
Looking forward to that. |
Except that the timer stack is only 100B deep :-( I know how to modify the FreeRTOS config underneath, which gets me back into the game, but a reasonable extension of the timer thread stack sounds cheaper (memory-wise) than rolling out another handler thread to forward timed things into. nRF52 has plenty of memory anyways, by Arduino standards... |
try our ada_callback() and ada_callback_fromISR() it is meant to use internally for deferred callbacks. But can be served as generic worker thread, I may rename it to make that clearer and easier to use for Arduino sketch later. |
Though you need to be aware of which thread your code is running, shouldn't wait for an semaphore or event that triggered within callback thread, while you are there. Some callback (not all, we do that later) has an option to be invoked in callback thread or in the main ble thread. You can make use of that for adv threading. PS: for continue with threading, please post on the forum, or if you found any bugs/improvement, post it in separated issue. This one is for low power, Although they are somewhat related. |
HAve a look to this post :https://devzone.nordicsemi.com/f/nordic-q-a/36649/custom-board-using-bt832-and-bt832x-power-drain-issue/146816#146816 Nordik PPK is a very useful tool to understand power drains! |
@pbecchi that is interesting, indeed Nordic PPK is very handy for analyzing the current. I have one here as well :D |
@hathach
But when I got between waitForEvent vs. a delay, I'm seeing my current go from about 70ua to over 400ua... my scope trace shows waitForEvent is waking up every ~1ms where as with delay it's about every 20us. Perhaps I misunderstood this. Any thoughts welcome. My code sample is below, with relevant stuff at the very bottom Thanks for any feedback
|
Hello! With the latest firmware, it seems that power consumption increases as softdevice is turned on. https://devzone.nordicsemi.com/f/nordic-q-a/35073/high-power-consumption-of-softdevice/136048#136048 In my environment power consumption has been reduced by rewriting |
I looked at that and it wasn't entirely clear how it would impact the delay function. Is that what you observed? @hathach could you follow up on my earlier question directed to you? |
some Measurements with my NRF52832 module: void loop() i get arround 7µA current consumption (BLE advertising). This is the same value when i used RedBear Lib. with delay(1000) in loop() i get arround 2000µA! |
Thank you. Can you post how you are setting RTOS tick rate? I know from scope measurement with waitForevent() it is 1khz so I think this is real key here. Or better yet post your example please. I was able to reduce delay current in loop some by adding the idle task but as you say it is still quite high. I think your method may be the best. Hope you can reply. Thanks
|
Hello wb8wka you need to modify the RTOS Config Header ... adafruit\hardware\nrf52\0.9.3\cores\nRF5\freertos\config\FreeRTOSConfig.h #define configTICK_RATE_HZ 4 // default = 1024 A Rate between 4 Hz and 10Hz uses arround 7µA on my Hardware (just the NRF52Module and some pull resistors @ 3,7V) please post a reply with your current consumption with Lower RTOS TickRate |
average is now 36ua with your mods and the beacon rate at 2000ms. However, I only have the serial port off and still have I2C on. I need to read I2C sensor about every 30 seconds (not doing that yet) BLE beacon working correctly. On my scope trace I am still seeing wakups ~1ms but they are not as "dense" as when tick was at 1024. Thank you this is very good find, it is late so I will exam more later in the day. |
With less sleepy eyes, I'm seeing ~9ua average now. That's as before. Also the scope is less active, much closer to a current spike every 250ms which is what I would expect. I'm thinking perhaps I didn't allow all the caps to fully drain and something was in a higher current mode. I did see you were on 0.9.3 (I was on 0.9.2) but I did verify before updating. Didn't make any difference. Now to make it do something useful. I hope to read a sensor and update the BLE advertisement. |
It's the 832. When i first tried updating, it was to 0.17, which is when I realized the current jump, but since my local was working, I just left it alone. More recently, I've also tried 0.20 and 0.21. I tried just copying my old version of the repo and then giving it to others to use so that I can work around this, but they get the following error that I couldn't figure out, since the file does seem to exist in the bin folder. I can't find anything about that file anywhere online. |
Hi @hathach , Is this aforementioned "coding guideline for low power" tutorial published and already available? If it is not available can you please suggest a list of things we can try to reduce the power consumption? |
Hi @ericlangel , I have the same board from Taiyo Yuden and it seems like it is using more current (0.5ma) than nrf52DK. I understand that some optimizations you list here don't help reducing consumption anymore because of the updates on the library. Can you please advise me on what current optimizations/tweaks I can work on so I can reduce the power consumption on this board? |
@selman-nus i think i cant advise you, because i stay on Version 0.9.3. |
@ericlangel I can test on the current version and update here with my findings. But I don't know what should I test, I am new to this library. |
@selman-nus It has no LF 32khz Osc. So you need to Enable the RC Osc //#define USE_LFXO // Board uses 32khz crystal for LF its defined in variant.h of your Arduino selected Board C:\Users\Username\AppData\Local\Arduino15\packages\adafruit\hardware\nrf52\0.9.3\variants\feather_nrf52832 |
its a long time ago that i worked with.... but using rc when 32khz osc is connected was a bad idea (dont know why actual) sorry, i think i cant help you at the moment |
Update The nice power reduction I'm seeing may be attributable to this change in v0.23 of the core library rather than to the difference between suspendloop() and a scheduled task vs. the traditional loop(). Apologies for that - I've left the post in case the summary is useful to others but removed the part attributing the 6 mA reduction in supply current to the scheduled task approach. Since I've consulted this tread, and things it points to, repeatedly, I thought I'd weigh in with what worked for me. In short, replacing
with
Elsewhere (typically a callback), you can pause with |
@ajs123 You might want to note that some things cannot be called from timers. Take for example file system access. I did try to save data to a file from a timer (update settings for future reloading in setup) and never managed to make it work. As soon as I put it in the main loop, it worked. A constant 6mA is an indication that the CPU never sleeps. If you use BLE, actual current consumption will be very "spiky" as you can see in #600 |
Yes re the 6mA - see my update to the post. I was looking and looking for the FPU interrupt issue perhaps still lingering and most likely I was falling victim to the crypto interrupt issue that's fixed with v0.23 of the core. Re things that cannot be called from timers, the issue I'm aware of is with things that take longer than the recurring timer interval (or, in the case of deferred callbacks from interrupts, things that take longer than the possible time between interrupts). See here for use of direct-to-task notification as a solution. The "mainline" task runs at lowest priority and blocks unless it has a notification waiting. There can be multiple notifications and it will only unblock once. With that said - and I hope it's useful - if performance is no different with delay() then in many cases it will be simpler, and still effective, to use the regular Arduino loop(). In my application, I want to be able to go into a very low power mode. I was unable (at least with the 0.21 and 0.22 cores) to get resumeloop() to work but I was successful (with the 0.23 core) with stopping and restarting a timer. Power usage with the timer stopped is barely different from what I get using systemOff(). |
In the last Days i tried the V1.2 release. And i could get very good results for Current consumption. suspendLoo() after Setup and in Loop itself. So i got around 4-6µA current consumption (with Advertising Interval Peaks). So for me the V1.2 is a great improvement against V0.9.3 |
Thanks @ericlangel for your nice report!
|
oh sorry its NRF52832 on a custom Board (without LDO, supplied by 3,6V Li-Battery) |
Hello! Currently, I am having trouble with the high power consumption of Adafruit Feather nRF52840 Board.
Following are the results of my experiment.
|
The NeoPixel on the Feather board consumes about 500uA when not lit. It’s not too hard to carefully pop it off (all at once or kind of layer by layer) with a pair of small side cutters. That should get you down to 200 uA. Recalling past forum discussion, the interface chip for the USB may be a significant contributor as well. |
@ajs123 P.S. |
@Siroyan Have you tried running the "Blink_sleep" example? During that sleep time, you should be able to measure a truely low current consumption from the chip and anything above a couple of uA should be from any additional hardware on your board (neopixel being one hungry thing...) That being said, are you quoting average currents? This will likely be very spiky in fact and highly dependent on the code you have. For my BlueMicro_BLE keyboard firmware, I was able to bring the current consumption to a low level in between radio transmissions, however, you have to keep in mind that when the CPU is running, it can consume about 6mA and when the radio is running, it can generate spikes upwards of 20mA. As such, having a device that measures current consumption very rapidly is very useful to tweak and verify that your code is indeed minimizing power consumption. Have a look at my video here that's done with the PPK2 to get a hint about what that looks like. Getting the CPU to low power mode when doing nothing is very important; otherwise, you will get that 6 mA I was mentioning above. I haven't checked whether my code is still "low power" with the latest (1.2.0) but I use these 2 methods: |
@jpconstantineau When I tried the sample program, the current consumption after the LED blinks was about 500uA. I am using Keysight's b2900 series Source mesurement unit. It should have enough resolution and I don't think it is "average current". |
@Siroyan But as the Neopixel show....dealing with µA is not just code. Every 10k Resistor matters -> 3V3/10k = 330µA |
@ericlangel |
i dont know when QSPI is used. But you said you suppling the Board with the 3V Pin? Did you checked (measured) reverse Current of the LDO? |
@ericlangel
Yes, and I measured current with LDO removed now, so It still consumed about 500uA. With the nRF52840 running |
I have never used NRF52840 (never tested current consumption). I just used NRF52832. And yes, with the example above you get around 2-5µA. (without BLE advertise!) |
i have a strange Bug
causing a Current of around 410µA without this line i have 5-6µA |
I seem to have a similar issue that @ericlangel described above when testing with the nrf52832. When using BOTH the Wire Library (I2C) and I ran 4 tests and measured the idle current during the
The code snippit below seems to be the simplest way to express the issue: #include <bluefruit.h>
#include <Wire.h> //I2C library
#define INT_PIN 15
volatile unsigned long ms = 25;
void irqHandler()
{
#if CFG_SYSVIEW
SEGGER_SYSVIEW_RecordEnterISR();
#endif
ms = 2000;
#if CFG_SYSVIEW
SEGGER_SYSVIEW_RecordExitISR();
#endif
}
void setup() {
Bluefruit.begin();
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, !LED_STATE_ON);
Wire.begin();
delay(100);
Wire.beginTransmission(0x0E);
Wire.write(0x0F);
Wire.endTransmission();
Wire.end();
delay(100);
pinMode(INT_PIN, INPUT_PULLUP);
attachInterrupt(INT_PIN, irqHandler, FALLING);
}
void loop()
{
digitalWrite(LED_BUILTIN, LED_STATE_ON);
delay(ms);
digitalWrite(LED_BUILTIN, !LED_STATE_ON);
delay(10000);
} Test 1 - (2.525uA): // Wire.beginTransmission(0x0E);
// Wire.write(0x0F);
// Wire.endTransmission();
...
// attachInterrupt(INT_PIN, irqHandler, FALLING); Test 2 - (10.25uA): // Wire.beginTransmission(0x0E);
// Wire.write(0x0F);
// Wire.endTransmission();
...
attachInterrupt(INT_PIN, irqHandler, FALLING); Test 3 - (2.525uA): Wire.beginTransmission(0x0E);
Wire.write(0x0F);
Wire.endTransmission();
...
// attachInterrupt(INT_PIN, irqHandler, FALLING); Test 4 - (472uA): Wire.beginTransmission(0x0E);
Wire.write(0x0F);
Wire.endTransmission();
...
attachInterrupt(INT_PIN, irqHandler, FALLING); Should I open this as a separate issue, or should we just use this thread to discuss it? |
Hi everyone, Thanks! |
Since long time I am fighting to lower power consumption using this library to the levels reachable with Sdk examples!
I have run several examples, testing the uA level in different type of code.
If we don't use BLE libraries uA are very near to the one expected , normally few uA when we are in low power mode.
But if we use BLE consumption get well above 1mA so about 100 times more that expected!
I have used the dual role BLE uart example and these are my findings:
-to enter low power mode you have to add delay() in the main loop , the longest the milliseconds the lowest the power drain.
-all Ble central related functions are taking quite a bit of mA
-keeping only BLE peripheral functions, with delay(100) will give about 600uA that is about what is expected (100 uA+500uA for Serial uart)
-taking out all Serial.begin and Serial.print from the example INCREASE the power drain to about 2mA while should be reduced by 500uA
I think this strange behaviour may only be due to some Serial debug statement present on the BLE libraries.
In theory Serial debug should be fully controlled by the Tools menu setting and with debug=0 slould not be executed!
The text was updated successfully, but these errors were encountered: