Comments (71)
I've just created 4 PRs:
Together, those PRs decrease the power usage by a lot:
Use-case | Fast Advertising | Slow Advertising | BLE disabled |
---|---|---|---|
InfiniTime 1.12 | 1.48mA | 890µA | 860µA |
With those changes | 580µA | 200µA | 180µA |
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
- Disabling the motion sensor (which disables the step counter) : -40µA
- Disabling all the IRQ on the I/O (which disables the button, touch panel and charger detection) : -20µA
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!
from infinitime.
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.
My multimeter claims it consumes only 60µA, but this 60µA vs 66µA difference could easily be explained by one or both multimeters being slightly wrong (I have a cheap one that I've noticed changes a bit over time).
I think this is the lowest we can possibly get with the PineTime. I've also investigated the BMA421 accelerometer and it appears to be set in power down mode by default.
@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.
from infinitime.
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!
from infinitime.
created a forum thread:
https://forum.pine64.org/showthread.php?tid=11711&pid=79840#pid79840
from infinitime.
I could try after my summer holidays.
I have few time available since few weeks, but I am interested in that subject.
from infinitime.
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.
My two P8 have entered the country, :D, sadly local customs is usually the big delay.. : (
Hardware:
- 2x NRF Devkits
- 2x ina boards (power measurement)
- 2x servos
- 2x orange pi
- 2x relay modules
- 1x pinetime
- 1x p8
- time
I have ported to py3 / cleaned up the testing framework, its now operational, but still a bit too "hard coded" in some aspects.
Will have to put some more time on it before i share the gitlab link ;) maybe even add bootstrap to beautify the UI :p
Software
- Fully operational
- break out hardcoded hwspecifics
- beatuify
- share gitlab link
from infinitime.
Today, I made measurement with a really reduced app.
In Mynewt 1.8, a bsp for pinetime was added by Casper Meiin:
https://github.com/apache/mynewt-core/tree/master/hw/bsp/pinetime
A tutorial is available to build the mynewt blinky app for PineTime:
https://github.com/apache/mynewt-core/tree/master/hw/bsp/pinetime
I also noticed that there is a issue opened by Daniel Kucera concerning low power on nRF52:
apache/mynewt-core#2393
I use part of is github work on thie blinky app project.
while loop in main.c becomes:
main(int argc, char **argv)
{
int rc;
#ifdef ARCH_sim
mcu_sim_parse_args(argc, argv);
#endif
sysinit();
g_led_pin = LED_BLINK_PIN;
hal_gpio_init_out(g_led_pin, 1);
hal_timer_deinit(0);
while (1) {
os_eventq_run(os_eventq_dflt_get());
// ++g_task1_loops;
//
// /* Wait one second */
// os_time_delay(OS_TICKS_PER_SEC);
//
// /* Toggle the LED */
// hal_gpio_toggle(g_led_pin);
}
assert(0);
return rc;
}
In that condition, I was able to reach 66µA.
But keep in mind that very few peripheral are used in that setup.
from infinitime.
I suspect that there is one first work that can be done in pinetime bootloader.
I measured consumption at three moments:
- t1: at startup, when screen and advertising are ON
- t2: when screen is switched off, be adv is still ON
- t3: when adv stopped.
Booting 0.14.0 Infinitime release without bootloader, I got those consumptions:
- t1: 27.3mA
- t2: 1.16mA
- t3: 0.9mA
Same Infinitime release, but with bootloader 1.0-RC4:
- t1: 27.3mA
- t2: 1.54mA
- t3: 1.43mA
It seems that there are some ressources, used in mynewt or mcuboot, that are not correctly de initialized.
from infinitime.
I did some measurements using my cheap multimeter (that can somehow measure down to 1µA) and posted my findings on the wiki: https://wiki.pine64.org/wiki/PineTime#Reducing_power_consumption
In summary, I was able to get my custom firmware to use only about 0.18mA in standby, while still listening for button events. It doesn't enable BLE, the step counter, or the accelerometer yet which will likely increase this somewhat but I think this means InfiniTime can improve current consumption quite significantly.
from infinitime.
Hi @aykevl I just test it right now.
I found 43µA standby with your fw, It's very nice!
Next week, I would be able to lake also some measurements with a better tool. This tool is used by a colleague.
from infinitime.
I have set up simular integration testing nodes before.
i have used:
rpi (flashing + read spi data from ina219 + uart)
ina219 current sense module
you can then set up a git hook that automatically triggers a build and execution, then upload the results.
for extra points you can add a few servos to tilt / simulate touch event.
even more extra points if you connect a controllable PSU to emulate a battery, then you can also test low/full power detection
Here is what i did: (you can also skip using the NRF dev kit and use openocd to flash through RPI GPIO, but you cant use RTT then.
I then had a webbased interface to allocate / execute and view test nodes. you could also compare between executions.
top left is power consumption, lower left is test framework output (ignore flash failed, its a bug :p ), to the right is the RTT output.
the blue is one execution and the grey is another. I have omitted hardware names as it contained customer information.
from infinitime.
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.
Sleep | Screen on |
---|---|
1.07 mA | between 12 and 15 mA |
from infinitime.
Hi all,
I started today some power measurement on Devkit.
Setup
Bootloader 1.0 RC4
Infinitime 0.13.0
Current is measured with a multimeter (Metrix MX 554) in series with battery terminal +.
Letter, I will make more accurate measurement if needed.
Theoretical consumption
According to the schematics, there is a base consumption, and we can't expect less than that.
This consumption depends on:
- U14: 3.3V LDO for nRF, and memory,
- U12: 3.3VLDO for sensors,
- standby consumption of components, power by LDOs or battery.
U14: ME6206
datasheet: 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.3
datasheet: 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.
total
base consumption on vbat is 28µA
Measurement
first measurements
I made quick measurements :
display | Connection ? | ADV | Consumption (mA) | |
---|---|---|---|---|
Mode 1 | OFF | OFF | OFF | 1,43 |
Mode 2 | OFF | OFF | ON | 1,58 |
Mode 3 | ON | OFF | ON | 27 |
We can see that consumption is really to high!
Without display & touch
To see if this high consumption come from display and touchscreen, there are physically disconnected.
display | Connection ? | ADV | Consumption (mA) | |
---|---|---|---|---|
Mode 4 | - | OFF | OFF | 1,4 |
Mode 5 | - | OFF | ON | 1,46 |
Mode 6 | - | ON | OFF | 1,47 |
High consumption is still there and seems not to be related to display.
Regarding consumption well all is in sleep, we can imagine that touchscreen and display, in standby, consume about 30µA. (1.4mA without them, 1.43mA within)
Without HR sensor
Same think, but without HR sensor
HR | display | Connection ? | ADV | Consumption (mA) | |
---|---|---|---|---|---|
Mode 7 | - | - | OFF | OFF | 1,3 |
Mode 8 | - | - | OFF | ON | 1,42 |
Mode 9 | - | - | ON | OFF | 1,35 |
conclusion
there is still about 1mA of consumption that should not be there.
With that state of measurement, I can't say if it comes from flash, accelerometer, battery charger or nRF52.
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.
@JF002 is the flash memory used when watch is in standby?
from infinitime.
I don't have my jtag probe right now. I will get back it next week, then, I will be able to make that measurement.
from infinitime.
@aykevl That sounds quite nice.
By the way, I just watched a video by bigclivedotcom on YouTube the other day, where he made his own cables for his multimeter, to improve the preciseness of his results.
That may be a good source of information when dealing with these tiny variances.
from infinitime.
I don't think quality of cables matters that much to be honest, because we're dealing with very low currents so even bad cables should work just fine.
True, I had mixed up impedance with voltage. Sorry about that.
from infinitime.
Thanks a lot for testing!
I just received my Power Profiler Kit, and using it I found some interesting details:
- It uses around 15uA most of the time, with very little peaks every 10-20ms. Averaging this out, we get around 66uA on the short term (matching your original measurement).
- Every minute, it awakes for about 208ms and during that time it consumes around 2.8mA. I believe I've seen these very short blibs on my multimeter but of course couldn't measure them properly.
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.
from 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 do plan to continue working on my own custom firmware, which is written in Go.
from infinitime.
@vbelloir @aykevl Very interesting discussion! And 60-70µA is really amazing! I would really like to see if we could integrate those changes in InfiniTime to improve the battery life! I'll do it when I get a bit of free time ;-)
from infinitime.
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.
Disabling all the IRQ on the I/O (which disables the button, touch panel and charger detection) : -20µA
Did you try polling the button instead of relying on interrupts?
I have found that polling the button (using the mechanism described here) actually reduces current consumption. Polling each 100ms or so only uses very little current (<10µA) in TinyGo, while leaving pin 15 high uses something like 34µA. As an experiment, you could set pin 15 low and see whether it makes any difference for you.
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:
https://github.com/aykevl/board/blob/58ffd00a37e218cae35973885c8edd13048b934a/board-pinetime.go#L151
Importantly, there seem to be a few chip errata that cause higher than expected current consumption as a result of interrupts, that can be entirely avoided using pin sense.
(You may not need the direct register accesses I have used, IIRC there's something in nrfx to use the pin sense mechanism in an easy way).
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).
from infinitime.
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.
I can't promise anything, but if I continue this project and find some interesting settings I'll share them!
from infinitime.
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).
from infinitime.
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:
- Changing the configuration to acc_odr=100Hz and acc_bwp=norm_avg4 (I think this is the configuration in InfiniTime?) bumped power consumption to 50µA.
- Disabling power saving (in ACC_CONF) bumped power consumption to 99µA.
- Enabling performance mode bumped power consumption to 151µA. Probably not the case for InfiniTime otherwise I don't think you'd be able to reach 180µA current consumption.
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.
from infinitime.
I have a ppk here but no real experience. Can hook it up and see what we see
https://www.nordicsemi.com/Software-and-tools/Development-Kits/Power-Profiler-Kit
Im using it in the external DUT but with nrf52 attached configuration
remove battery, and im just hooking up the 2 pins form external DUT output so it can control power and read usage
https://infocenter.nordicsemi.com/pdf/PPK_User_Guide_v2.4.pdf
and this open source python sdk instead of their js stuff
https://github.com/inductivekickback/ppk_api/
upstream is be05997
this waits through startup, but screen still on
python3 main.py -p 3 -a 5
Average: 17999.27uA
waits long enough to be measuring when screen is off
python3 main.py -p 25 -a 5
Average: 1195.97uA
Not sure if these are the range of what you're expecting or if I need to dial this in
python3 main.py -p 25 -t 2000 -w 5850 -o trig_data.csv --png
Trigger buff average: 3554.10uA
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
from infinitime.
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
from infinitime.
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.
from infinitime.
@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?
from infinitime.
This was manly a "integration test framework" the automatic power profiling was just a bonus.
It was written to test various HW revisions of a cellular IoT product deployed in different countries.
I can put a few days to clean things up and then release it as open source, if you want to poke around.
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.
Most of the tests was based on parsing debug strings from the RTT feed. but there was also tests that verified that the power consumption was within expected range.
example of a test script:
def run(self):
self.timeSinceStart = 0
self.flash()
# verify that modem was detected
self.addDelayedParse(20,"IAmNow",1)
# run, then turn off'
self.addDelayedEvent(20,self.buttonIn,())
self.addDelayedEvent(5,self.buttonOut,())
self.addDelayedEvent(30,self.parse,("WillNowPowerOff",1))
# verify that we do not boot when off and charging starts
self.addDelayedEvent(10,self.chargerOn,())
self.addDelayedEvent(20,self.parse,("OFFcharging",1))
# wait, then turn on again, verify that we remember our modem type
self.addDelayedEvent(10,self.buttonIn,())
self.addDelayedEvent(5,self.buttonOut,())
self.addDelayedEvent(30,self.parse,("IKnowIAmA",1))
self.addDelayedEvent(1,self.end,())
self.start()
@JF002
The PPK is this:
https://infocenter.nordicsemi.com/pdf/Power_Profiler_Kit_PB_v1.0.pdf
https://www.digikey.com/products/en?keywords=NRF6707&v=1490 (80$ ish )
But i would go with a custom solution (Pineboard or rpi and a ina219 module) ^_^
from infinitime.
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 ;)
from infinitime.
@maidenone This is awesome! Keep us up to date with your progress!
from infinitime.
I have now started the "beautify" process, bootstrap really makes a difference, just compare the node/test/firmware form compared with the tables beneath.
I have also disassembled my pinetime again :'( are looking on how to wire everything together.
from infinitime.
This is awesome! I posted a reply on the forum post.
from infinitime.
@JF002 I posted some news on the forum, do not know if you get any notifications from there?
from infinitime.
I do not receive notifications from Pine64 forums, but I'll try to enable them!
Thanks for the additional informations and for your work!
from infinitime.
@JF002 check the forum again ;)
from infinitime.
@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
- this case called when the user pushes on the button : it sends a message to all the task to put them to sleep
- and this case when the devices are disabled before the systemtask goes to sleep.
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.
From what I read, this debug circuitry use a lot of power.
More info about this here.
*This wiki page document ways to disable the debug circuitry, but I don't know if they really work. You might be able to check them :)
If it is disabled and you still measure these high numbers, then, we are a lot of room for improvements :p
from infinitime.
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:
case Messages::GoToSleep:
isGoingToSleep = true;
NRF_LOG_INFO("[systemtask] Going to sleep");
xTimerStop(idleTimer, 0);
displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep);
heartRateApp->PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep);
break;
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.
I will try to put a debugger, to get RTT logs.
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.
from infinitime.
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.
from infinitime.
from infinitime.
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....
So, we can say that Infinitime is quite efficient ;)
EDIT : in parallel, I let my sealed device discharging itself, without any connection.
After 24h, watch still says that battery level is 100%.
from infinitime.
Just for example, I just flash on my dev kit, a Nordic beacon example, I get 800µA, without display, touchscreen, and HR sensor.
from infinitime.
I started some measurement on infinitime code (tag 0.13.0).
If I WFE before or after nimble_port_init in main function, and consumption increase from 60µA to 800µA.
If itt put just after start of scheduler, it increases to 1.06mA.
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 can create a Matrix account if you prefer.
from infinitime.
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 nrf_drv_saadc_uninit()
with the following fixed the issue for someone. Note that in InfiniTime a different function is used nrfx_saadc_uninit()
.
static void uninit_saadc_on_disconnect(void)
{
nrf_drv_timer_disable(&m_timer);
nrf_drv_timer_uninit(&m_timer);
nrf_drv_ppi_channel_disable(m_ppi_channel);
nrf_drv_ppi_uninit();
nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP);
nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
nrf_saadc_disable();
}
https://devzone.nordicsemi.com/f/nordic-q-a/34702/regarding-nrf-52832-power-consumption-saadc-ppi-timer
https://devzone.nordicsemi.com/f/nordic-q-a/74892/power-consumption-increases-1-1ma-after-first-adc-sample
from infinitime.
@Riksu9000 I'd like to step up to this, if this can be done with a simple multimeter.
If so, how do I go about this?
from infinitime.
@Riksu9000 I'd like to step up to this, if this can be done with a simple multimeter.
If so, how do I go about this?
First you'd need a multimeter that can measure currents lower than 1mA. Then I'd assume you could just attach it between the battery/power supply and the watch and measure all the current going into the watch. Please state whether you use a battery or a power supply, because the results will be different (because of the voltage).
EDIT: I should also mention that you could easily cause a short when measuring current with a multimeter, so make sure you know what you're doing.
from infinitime.
@Riksu9000 As of now, I only know how to measure voltages (and residence, to a degree), I am still trying to figure out how to measure amperages, so I have no idea what is the lower limit of my multimeter in that regard.
My multimeter runs off a 9V battery pack (nonrechargable).
from infinitime.
@vbelloir Regardless of whether I do anything or not, your methodology will be way better.
from infinitime.
I have a NRFPPK2 that I use for testing the PineTime now. So I have slowly been amassing some more info on power consumption and will slowly be documenting it as I go. Lots of optimizations to be had I am sure as we worth through stuff!
from infinitime.
@geekbozu That would be nice, as @vbelloir has already found many possible optimizations, but I couldn't find enough time to have a closer look at them :)
from infinitime.
@aykevl Thank you so much for sharing your findings! Your results are definitely better than what InfiniTime can do right now (around 1mA in sleep mode). This definitely shows that we have a lot of room for improvements!
from infinitime.
I believe I can get lower than the ~177µA I'm now at, by putting the SPI flash in deep sleep mode. The SPI flash uses 12µA in regular (non-deep) sleep mode according to the datasheet, so that would be a nice win. I'll report back when I manage to do that.
@vbelloir how did you get this 66µA value? I tried reproducing it and while I can get to roughly the same value as I get in my own firmware (~0.18mA) I can't get it any lower. This is my main function, based on the blinky tutorial:
int
main(int argc, char **argv)
{
int rc;
#ifdef ARCH_sim
mcu_sim_parse_args(argc, argv);
#endif
sysinit();
g_led_pin = LED_BLINK_PIN;
hal_gpio_init_out(g_led_pin, 1);
NRF_CLOCK->TASKS_HFCLKSTOP = 1;
hal_gpio_init_out(5, 1);
hal_gpio_init_out(25, 1);
hal_timer_deinit(0);
while (1) {
os_eventq_run(os_eventq_dflt_get());
}
assert(0);
return rc;
}
By the way, I just watched a video by bigclivedotcom on YouTube the other day, where he made his own cables for his multimeter, to improve the preciseness of his results.
My setup isn't exactly great. I wired up my broken multimeter cables directly between the VCC wires to measure current. The multimeter itself is a cheap Voltcraft one. I think I'll try to get a Nordic Power Profiler Kit, which is designed for this kind of stuff (unlike this multimeter).
I don't think quality of cables matters that much to be honest, because we're dealing with very low currents so even bad cables should work just fine.
from infinitime.
hi @aykevl, I'm happy to see that someone is looking on that point!
I really think that it is possible to reach 1 month of autonomy with pinetime.
You don't managed to reproduce my setup?
If you want I can do some measurement for you.
Unfortunately, I'm not enough good in firmware to go further.
from infinitime.
I really think that it is possible to reach 1 month of autonomy with pinetime.
With 0.18mA, 1 month should indeed be possible if the watch is lightly used. With 66µA, up to three months might be possible (but I suspect using the screen will then become a larger power drain).
You don't managed to reproduce my setup?
Unfortunately not. I'm not very familiar with Mynewt but I managed to get the blinky example to work.
Can you describe it in some more detail? What steps did you take and which files did you modify?
What I did was I followed the blinky tutorial and modified the main function as I posted above.
from infinitime.
I tried quickly to reproduce the setup, without any success. It is quiet old in my head....
Right now, I only managed to get 5mA consumption when backlight is off...
I don't remember if I was using bootloader in Feb 2021
from infinitime.
@vbelloir thank you for testing!
Maybe the LCD is still on? That would explain 5mA of current. You could try power cycling the watch, or send the SLPIN command.
As far as I know, it's not possible to use Mynewt without bootloader.
from infinitime.
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.
from infinitime.
Do you want me to test your bin file, and measure current also?
Your project is available on github or so?
from infinitime.
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.
You could also send me the ELF (or bin) file so I can try myself.
My project is here: https://github.com/aykevl/things/tree/master/watch
I don't have any documentation yet and I don't have a way to do OTA updates (it will destroy your bootloader if you have one, so be careful), I will try to add this some time.
from infinitime.
Are you sure of the url?
it is a GO software?
I was expecting a mynewt project or something around infinitime firmware.
I don't know anything about go.
How is it build?
I will use it with pinetime dev kit with jlink probe. No need of OTA.
from infinitime.
@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.
from infinitime.
ok, can you at least share me a bin/hex/elf file. It could be able to make some measurement.
Are you interested in a boot sequence measurement?
from infinitime.
Here is a zip of the ELF file: watch.zip
This is with all the optimizations I know applied. I'm getting 162µA right now from my multimeter.
from infinitime.
Since I mostly need the clock function, I am really looking forward to having my PineTime using this little power most of the time.
from infinitime.
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).
from infinitime.
It's very interesting. Will you try to do the same with infinitime? Or will you able to support a FW dev of infinitime?
from infinitime.
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).
That's great!
I'd be curious to look at the diff, perhaps I have some more suggestions :)
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!
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).
@aykevl How can I ensure that the low-frequency oscillator is enabled and used?
Pretty sure it is, if you manage to get such low current consumption. But if you want to be sure, you can read the LFCLKSRC
register (the SRC
field should be set to Xtal).
from infinitime.
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.
I don't know your setup, but perhaps you can try power cycling the watch after flashing my firmware?
from infinitime.
I don't know your setup, but perhaps you can try power cycling the watch after flashing my firmware?
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'd be curious to look at the diff, perhaps I have some more suggestions :)
I'll create a few PRs with the changes so we can review them and integrate them in InfiniTime :)
In the mean time, here's a patch with my changes :
power.zip
Note that those changes are pretty rough and disable most of the functionalities of the watch (button, ble, heart rate sensor, motion sensor,...).
Pretty sure it is, if you manage to get such low current consumption. But if you want to be sure, you can read the LFCLKSRC register (the SRC field should be set to Xtal).
I'll check, but I think I remember the SRC was effectively set to Xtal!
from infinitime.
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.
Thanks for the review, a second view is always interesting!
Did you try polling the button instead of relying on interrupts?
No, not yet, but it's probably something worth looking into! Thanks for the links!
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).
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!
from infinitime.
Very happy to read theses messages!
With about 30 days lifespan, Pinetime will become usable as daily watch!
from infinitime.
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!
from infinitime.
Related Issues (20)
- lv_img_conv.py doesn't handle 8-bit pixel mode HOT 3
- (v)snprintf space optimisations
- Restore timer duration when finished
- Timer holds changing time when turning off the watch
- Crash Screen (?) During Normal Use HOT 2
- Increased battery usage in 1.14.0 HOT 11
- App menu stays at second screen HOT 10
- State of GFX? HOT 4
- Watch freezes after some notifications HOT 25
- Watch freezes and reboot after interacting with external resources HOT 4
- Occasional Incorrect Dates Displayed in the Weather forecast HOT 2
- Turn off accelerometer in night mode HOT 3
- Can't connect to Gadgetbridge after Firmware 1.14 update. HOT 5
- Screen shifting upwards HOT 8
- Assert call being removed during compilation, causing NULL pointer dereference in ble_ll_task HOT 6
- Using GDB debugger in devcontainer does not load source map
- Stopwatch lap counter only goes up to 20 laps HOT 1
- Unable to update InfiniTime successfully
- Add unit testing framework and skeleton test project HOT 4
- looping recovery mode,.... infinite loop. ITime. HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from infinitime.