-
-
Notifications
You must be signed in to change notification settings - Fork 938
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
Power analysis #53
Comments
I have a ppk here but no real experience. Can hook it up and see what we see Im using it in the external DUT but with nrf52 attached configuration and this open source python sdk instead of their js stuff upstream is be05997 this waits through startup, but screen still on
waits long enough to be measuring when screen is off
Not sure if these are the range of what you're expecting or if I need to dial this in
im sure youd like to try some special firmwares with only certain devices or bluetooth stuff enabled Sadly im not sure how to automate the damn thing for CI but I can run a few tests occasionally for you, its a pretty clean setup and not too much bother |
Yeah ppk doesn't look great for automated purposes I don't think. You have to manually flip a switch to be able to program target and the switch back |
That could be replaced with a relay/transistor. |
@jacobrosenthal Thanks for these measurements! So, if I understand correctly, the firmware uses 1.2mA in sleep mode and 180mA when the display is ON? @maidenone your setup is amazing, I wish I could build something similar to auto-test new versions of the firmware! In fact, I didn't even think about the automatisation of power measurements, but now, I really want to do that! By curiosity, how much does the PPK cost and where can I find it? |
When I measured Hypnos' power consumption this spring, I got the results below. This is with the HR sensor physically disconnected and BLE advertising disabled.
|
This was manly a "integration test framework" the automatic power profiling was just a bonus. Each node (RPI + DUT) connects to a common "manager" (the web interface) through http/json requests. so if i hook up my pinetime, you can deploy and test on it. i also had command line tools so i could flash and get real time RTT output from devices in UK, USA, China or Spain while sitting in my comfy basement. ^_^ I had two git repositories, one for the test-project and one specific for the tests, before a test executed the nodes run git pull on the test repo, so you could add/modify test cases and the nodes was always up to date. example of a test script:
@JF002 But i would go with a custom solution (Pineboard or rpi and a ina219 module) ^_^ |
will set up two testnodes one with pinetime and one with p8, i will document this on the forum, i would like to make it open to the public, but must find a way to parse the binaries for "bad bits" before flashing to avoid locking/ bricking of the units. i think i got all the hardware i need. automated power measurements between builds will be easy to fix ;) |
@maidenone This is awesome! Keep us up to date with your progress! |
I detected that my pile of RPIs have been decimated to a broken RPI3, but i have two Orange Pi Zero 256MB H2+ that i can use. Hardware:
I have ported to py3 / cleaned up the testing framework, its now operational, but still a bit too "hard coded" in some aspects. Software
|
created a forum thread: |
This is awesome! I posted a reply on the forum post. |
@JF002 I posted some news on the forum, do not know if you get any notifications from there? |
I do not receive notifications from Pine64 forums, but I'll try to enable them! |
@JF002 check the forum again ;) |
Hi all, SetupBootloader 1.0 RC4 Current is measured with a multimeter (Metrix MX 554) in series with battery terminal +. Theoretical consumptionAccording to the schematics, there is a base consumption, and we can't expect less than that.
U14: ME6206datasheet: https://datasheetspdf.com/pdf-file/825717/Microne/ME6206/1 There are several part for the same reference. I hope we don't have ME6206K, which consumes a lot. U12: SGM2036-3.3datasheet: https://files.pine64.org/doc/datasheet/pinetime/SGMICRO-SGM2036.pdf nRF52832@JF002 can you tell me which low power mode you are using when watch is in standy? I mean no screen, no ble connection nor advertising. totalbase consumption on vbat is 28µA Measurementfirst measurementsI made quick measurements :
We can see that consumption is really to high! Without display & touchTo see if this high consumption come from display and touchscreen, there are physically disconnected.
High consumption is still there and seems not to be related to display. Without HR sensorSame think, but without HR sensor
conclusionthere is still about 1mA of consumption that should not be there. I think we can battery charger, as it only consumes on 5V input, not on battery. We can also forget BMA421 accelerometer. It is not used in infinitime 0.13.0, en even if it was activated, it only consumes 14.5µA in normal mode I could from flash memory, which consumes few mA in read or write circle. |
@vbelloir Thank you very much for this detailed analysis! Regarding the low-power mode in sleep mode : devices are stopped when possible (ex : the LCD is shut down) and all peripherals (I²C, SPI,...) are disabled. Also, all task are waiting for an event on a queue, which allows the scheduler to enable the "tickless sleep mode" (from FreeRTOS), which, in the end, calls WFI()/WFE(). The instructions puts the CPU in SYSTEM ON low-power mode. All RAM regions are maintained, and it can wake up on any event (timer, ble,...). From the table, I think this is ON_RAMON_EVENT. Previously, InfiniTime sent the SLEEP command to the external SPI flash memory, but it triggered a bug in the bootloader so I disabled that. The SPI bus is still disabled, though. In the code, you can have a look at
Regarding the high power consumption you measured : did you ensure that the debug circuitry was not enabled while measuring? The debug circuitry is enabled when the SWD connects to the MCU and is not disabled when the debugger is physically disconnected or by a soft reset. The only way* to disable it is to issue a hardware reset or unplug/plug the power. If it is disabled and you still measure these high numbers, then, we are a lot of room for improvements :p |
Thanks for you response. After posting, I have checked the code, and systemTask.cpp. And I was surprised that there is no action on CPU, here:
I'm not a real firmware guy, so, I will probably say a mistake, but I would have expect something a call to sd_power_system_off, found in SDK. This last sentence make me answer your question : I don't think that debug circuitry of dev kit is on, because I have never connected a swd probe to it. I updated it with DFU. |
Ok, the debug circuitry is probably disabled, then ! It's not easy to check that the CPU is actually sleeping without waking it up to log that it's sleeping, so it's possible that it's not sleeping as much as I think it should! You won't find any call to Here is the procedure to go to sleep:
When this is over, all the tasks are waiting on a queue with a longer timeout. When all the tasks are waiting, FreeRTOS calls WFE to to into sleep mode. |
Is it hard to get a simpler project, that just put nrf52 in low power mode? The same you are using in infinitime ?
Also, I got a pca10056 board based on a nrf52840 chip.
I will try ti build this project to see which cinsumption i can reach:
https://github.com/apache/mynewt-nimble/tree/master/apps/advertiser
Le Jeudi 18 février 2021, JF002 a écrit :
… Ok, the debug circuitry is probably disabled, then !
It's not easy to check that the CPU is actually sleeping without waking it up to log that it's sleeping, so it's possible that it's not sleeping as much as I think it should!
You won't find any call to `sd_power_system_off` because this is a function from the NRF SoftDevice (NRF BLE stack). InfiniTime is based on NimBLE, an open source ble stack from MyNewt.
You'll find the call to WFE(), where the system is put to sleep, here : https://github.com/JF002/Pinetime/blob/develop/src/FreeRTOS/port_cmsis_systick.c#L266
Here is the procedure to go to sleep:
- The idle timer is triggered, or the user pushes the button
- The message `Messages::GoToSleep` is sent to SystemTask
- SystemTask sends `Messages::GoToSleep` to the other tasks (Display and Heartrate)
- These task do whatever they need to go to sleep (ex : DisplayTask powers the LCD and the backlight off). Display task sends the message `Messages::OnDisplayTaskSleeping`
- When SystemTask receives this message, it disables the lcd, touchpanel, and then the SPI and TWI busses.
When this is over, all the tasks are waiting on a queue with a longer timeout. When all the tasks are waiting, FreeRTOS calls WFE to to into sleep mode.
--
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#53 (comment)
--
|
Just as a test, I flashed waspos (bootloader.hex, and micropython.zip). When Watch is in standby , screen is off, advertising is still there, and consumption is about 2.7mA.... EDIT : in parallel, I let my sealed device discharging itself, without any connection. |
Just for example, I just flash on my dev kit, a Nordic beacon example, I get 800µA, without display, touchscreen, and HR sensor. |
Today, I made measurement with a really reduced app. In Mynewt 1.8, a bsp for pinetime was added by Casper Meiin: A tutorial is available to build the mynewt blinky app for PineTime: I also noticed that there is a issue opened by Daniel Kucera concerning low power on nRF52: I use part of is github work on thie blinky app project. while loop in main.c becomes:
In that condition, I was able to reach 66µA. But keep in mind that very few peripheral are used in that setup. |
I started some measurement on infinitime code (tag 0.13.0). I would like to remove all task, and re-activate them on by one, to see where so ressources need to be deinit, but I don't reaally know how to do that. @JF002 do you have some time to ping me on Telegram, to see how I can help? |
I suspect that there is one first work that can be done in pinetime bootloader.
Booting 0.14.0 Infinitime release without bootloader, I got those consumptions:
Same Infinitime release, but with bootloader 1.0-RC4:
It seems that there are some ressources, used in mynewt or mcuboot, that are not correctly de initialized. |
There are some posts on the NordicSemi forums about power consumption increasing after the first use of SAADC. I'm hoping someone with the means to measure the power consumption could measure the difference with the low power mode enabled, and some other workarounds if necessary Replacing
https://devzone.nordicsemi.com/f/nordic-q-a/34702/regarding-nrf-52832-power-consumption-saadc-ppi-timer |
I tried quickly to reproduce the setup, without any success. It is quiet old in my head.... I don't remember if I was using bootloader in Feb 2021 |
@vbelloir thank you for testing! As far as I know, it's not possible to use Mynewt without bootloader. |
I managed to put the SPI flash in deep power down mode, which (according to my multimeter) reduces power from 178µA down to 164µA (a reduction of 14µA). This matches the datasheet, which gives 12µA for standby current and 0.1µA for deep power down current (the 2µA difference between spec and measurement is probably well within tolerance of both the flash chip and my multimeter). As usual, I've put my findings on the wiki. |
Do you want me to test your bin file, and measure current also? |
That would be very useful! It would rule out differences in measurement tools. My project is here: https://github.com/aykevl/things/tree/master/watch |
Are you sure of the url? I don't know anything about go. I will use it with pinetime dev kit with jlink probe. No need of OTA. |
True, I had mixed up impedance with voltage. Sorry about that. |
@vbelloir yes it is written in Go (it does not use Mynewt). I haven't provided any documentation yet how to use it, I will try to do so at a later time. |
ok, can you at least share me a bin/hex/elf file. It could be able to make some measurement. |
Here is a zip of the ELF file: watch.zip |
I managed to reproduce the ~66µA power consumption! The final missing bit was the heart rate sensor that is apparently enabled by default and consumes 0.1mA. @vbelloir here is the updated firmware, in case you'd like to test: watch.zip. It consumes a bit more in my measurement (62-63µA) because it's also polling the button, I get the lowest power consumption when I really disable everything. As usual, I have updated the wiki. |
Since I mostly need the clock function, I am really looking forward to having my PineTime using this little power most of the time. |
Hi @aykevl I just test it right now. Next week, I would be able to lake also some measurements with a better tool. This tool is used by a colleague. |
Thanks a lot for testing!
When I take the average of multiple minutes of measurement, I get around 80uA (although it fluctuates a bit). I don't know what is causing these current spikes, but I imagine some of the chips (the touch controller perhaps) is recalibrating during that time. If I remember correctly, the touch controller consumes around 3mA when active, so that would make sense. |
I left it running for a bit longer and found some more patterns. It appears to go through periods of higher and lower current consumption. The lower current consumption is around 72uA (averaged out over a minute to include the 200ms spikes). Higher current consumption (up to around 200uA) seems to get triggered by movement, or by me resting my arms on my desk (??), although that could perhaps also be bad cables or something else. In any case, the typical resting current consumption seems to be more like 72uA, which is still pretty low (~100 days battery life). |
It's very interesting. Will you try to do the same with infinitime? Or will you able to support a FW dev of infinitime? |
I have no plans to work on InfiniTime, sorry. But I'd be happy to answer any questions that people might have to get such low current consumption on their firmware. |
I did a few experiments. With a few minor changes to the code, I manage to reduce the current consumption down to ~130µA. It's waaaaay better than current consumption of the current release (~1.1mA), but still ~40µA more than @aykevl (I measure 97µA using watch.elf). Not sure where those 40µA come from though... @aykevl How can I ensure that the low-frequency oscillator is enabled and used? EDIT : I think I found what's using those 40µA : the motion sensor! It looks like it uses a bit of current when it's initialized and configure to count steps! |
That's great!
Yeah, that's certainly possible. I haven't really investigated low power modes for the motion sensor, but I did find that after reset it enters a low power mode of negligible current consumption (less than 1µA IIRC).
Pretty sure it is, if you manage to get such low current consumption. But if you want to be sure, you can read the |
Actually now I think about it, my firmware doesn't touch the motion sensor at all. So if it was enabled in the previous firmware and wasn't reset or power-cycled, it might still be enabled. That might explain why you measure a higher current consumption than I do. |
Since my devkit is connected to the debugger, I always power cycle it before measuring the current to ensure that the debug peripheral does not draw any additional current. I think my setup is not optimal for power measurement right now because of all the long wires and the breadboard. That's maybe why I measure a value slightly higher than yours?
I'll create a few PRs with the changes so we can review them and integrate them in InfiniTime :) Note that those changes are pretty rough and disable most of the functionalities of the watch (button, ble, heart rate sensor, motion sensor,...).
I'll check, but I think I remember the SRC was effectively set to Xtal! |
I've just created 4 PRs:
Together, those PRs decrease the power usage by a lot:
This reduces the power usage by a ratio of 2.7 to 4.7, which is quite awesome! The power usage in sleep mode could be further reduced by
It was also a nice opportunity to check that the feature that disables BLE in InfiniTime actually works : the power consumption is the same when I disable BLE in the code (at compile time) and when I disable it in the settings (at run time)! The theoretical battery life is increased from ~7 days to ~35days in sleep mode while slow advertising ! Thanks again to @aykevl for sharing their results! |
That's really amazing! I looked at the PRs and they look reasonable - but I don't know much about InfiniTime or FreeRTOS so can't say much about it.
Did you try polling the button instead of relying on interrupts? Also, I found that using the pin sense mechanism instead of using level triggered interrupts for the touch controller avoids the current consumption increase that is caused by edge triggered interrupts. You can find more details here: EDIT: one thing I haven't looked into yet is the various options in the touch controller. It might be possible to save some current consumption by changing some of the registers (calibration interval, for example). |
Thanks for the review, a second view is always interesting!
No, not yet, but it's probably something worth looking into! Thanks for the links!
The touch panel is veeery sensitive, and tends to wake InfiniTime up way too often, which causes unwanted actions in the UI and higher power usage. I'm very interested if you can find some way to tune it and improve the sensitivity and power usage! |
Oh, I see. |
Very happy to read theses messages! |
I'd say it is already very capable of being used as a daily watch. And whenever someone comments on mine and I tell them that it typically lasts 4 pr sp days on a single charge, they've been shocked (oftentimes coming from Apple Watch users, but idk the battery life on those since I haven't owned one). 10 days is incredible! |
I suspect the accelerometer is not set to low power mode by default in InfiniTime. I have my TinyGo version of the BMA421/BMA425 driver almost working and once I get it to work fully, I'll post the results here. The accelerometer should be able to go down to 14uA when set to sleep mode, without sleep mode it's much more. I did in fact manage to reach that low level (actually 11uA or so but that's probably a measuring error), but had trouble getting the step counter to work (I'm pretty sure it's possible, I just didn't figure it out yet). |
Ok, managed to get the step counter to work. It consumes 14µA when fully optimized, exactly as the datasheet states. I also tested my driver with something similar to the configuration for InfiniTime (https://github.com/InfiniTimeOrg/InfiniTime/blob/main/src/drivers/Bma421.cpp) and found it uses far more power:
So this is probably something to investigate for InfiniTime. My driver is here: https://github.com/tinygo-org/drivers/pull/587/files. Especially important are the ACC_CONF and PWR_CONF registers. Specifically, the datasheet says the following (page 31 of the PDF): So that's what I did, I set the ODR to 50Hz and acc_bwp to osr4_avg1 (no averaging). That may result in worse readings, but it still detects steps. My multimeter now claims the watch uses 79µA most of the time with step counting enabled and BLE disabled. The actual current consumption will be slightly higher because of the spikes the touchscreen (?) produces sometimes. |
In commit f7e40b1, I re-implemented sleep/wakeup for all devices (touchpanel, display, NOR Flash, SPI and TWI).
I checked (using the logs) that all Sleep() and Wakeup() method are called in the correct order.
I also checked that the MCU is put in deep sleep with a logic analyzer (the MCU is in deepsleep during the call to __WFE() in port_cmsis_systick.c).
Now, I think it would be very interesting to actually measure the power consumption of InfiniTime while running different use-cases:
But... I do not have the necessary instruments and knowledge to do the measurement by myself.
If anyone has the setup and instruments necessary to measure the power consumed by InfiniTime, just write a comment to this issue !
Also, if you can, just leave your Pinetime running this commit (f7e40b1) or a next one just to see how long it runs on battery!
Thanks
The text was updated successfully, but these errors were encountered: