low power support?

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
manitou
Posts: 73
Joined: Wed Feb 25, 2015 12:15 am

low power support?

Post by manitou » Thu Mar 19, 2015 8:54 pm

On 3/12 Damien says: Low power sleep modes are almost there... it just needs a decision on the API that the user sees, and some tidying up. The pyboard will do down to about 400uA in suspend mode where it can wake and continue where it left off.
Any updates on low power API for pyboard? (Is it OK to power pyboard with regulated 3.3v to the 3.3v pin, and no power at Vin or USB?)

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Re: low power support?

Post by Damien » Fri Mar 20, 2015 11:51 am

manitou wrote: Any updates on low power API for pyboard? (Is it OK to power pyboard with regulated 3.3v to the 3.3v pin, and no power at Vin or USB?)
It's in the very latest firmware image, so if you upgrade then you can get this functionality.

pyb.stop() will enter low power mode. Upon waking execution continues from where it left off.

To wake, any external interrupt on a pin (see ExtInt class) will do it. Also there is a RTC wakeup feature that wakes the chip at regular intervals; example:

Code: Select all

import pyb
rtc = pyb.RTC()
rtc.wakeup(2000) # wakeup every 2000 ms (2 seconds)
while True:
    do_some_processing()
    pyb.stop()

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Re: low power support?

Post by Damien » Fri Mar 20, 2015 11:56 am

manitou wrote:Is it OK to power pyboard with regulated 3.3v to the 3.3v pin, and no power at Vin or USB?
I've done a very quick test of the hardware to see if this is possible and it seems yes, it is possible.

I tried tying VIN to 3V3, and powering 3V3 by a 3.3v regulated source and it works. I also tried leaving VIN floating and it works. In both cases the current consumption was around 450uA in the pyb.stop() mode. (Of course, you can't power by USB with this configuration of power!)

One other thing, to get low power you need to disable USB. In boot.py put:

Code: Select all

pyb.usb_mode(None)
If you want even lower power you can try pyb.standby() to get around 25uA. It acts similar to pyb.stop() but upon waking the MCU is reset. It's not well tested and there's currently no way to tell if the MCU was reset first time or from waking from pyb.standby().

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: low power support?

Post by pythoncoder » Tue Mar 24, 2015 9:03 am

there's currently no way to tell if the MCU was reset first time or from waking from pyb.standby().
Could you not do this with a 1-byte file? At the start you'd read the byte, then write 0, writing 1 before executing the standby(). If the program had terminated normally or been reset (hardware or software) you'd read 0, but after a standby you'd read 1.
Peter Hinch
Index to my micropython libraries.

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Re: low power support?

Post by Damien » Tue Mar 24, 2015 10:19 pm

pythoncoder wrote:
there's currently no way to tell if the MCU was reset first time or from waking from pyb.standby().
Could you not do this with a 1-byte file? At the start you'd read the byte, then write 0, writing 1 before executing the standby(). If the program had terminated normally or been reset (hardware or software) you'd read 0, but after a standby you'd read 1.
Actually I found a way to do it: use the RTC backup registers. Eg:

Code: Select all

import stm

if stm.mem32[stm.RTC + stm.RTC_BKP1R] == 0:
    # first boot
else:
    # got out of standby mode

stm.mem32[stm.RTC + stm.RTC_BKP1R] = 1 # indicate that we are going into standby mode
pyb.standby() # we reset when woken

There's also a bit 1 of the PWR_CSR register which indicates if the device has been in standby mode since the last power-on-reset. This bit can be cleared using bit 3 of the PWR_CR register.

manitou
Posts: 73
Joined: Wed Feb 25, 2015 12:15 am

Re: low power support?

Post by manitou » Tue Mar 24, 2015 11:05 pm

Here are results (milliamps from a DMM) for my pyboard low power tests.

Code: Select all

Config      clock  168Mhz   84    42    24    8

USB power
 spin-loop          65ma    37    23    16    11 ma
  some IO off       54ma    30
 sleep/wfi          26      18    13 ma
  some IO off       15ma    10
 
3.3v power
 spin-loop          61ma    
  some IO off       52ma    29
 sleep/wfi          24      16    13
  some IO off       14ma     9     6      5    4 ma


stop    2.6ma     (1.4ma at 3.3v)
standby 29ua (FLASH)     0.18ma (SD)
The little test program can be configured for various power tests including disabling some of the IO
https://github.com/manitou48/pyboard/bl ... owpower.py

Data sheet for the chip suggests at 168MHz from flash and peripherals enabled power is 93ma, with no IO 46ma. Sleep mode 59 ma or 12ma. Stop mode 0.45 ma. Standby mode 3 ua.

Note, pyb.delay() uses wfi which lowers power during delay.
Last edited by manitou on Wed Apr 29, 2015 9:04 pm, edited 1 time in total.

Damien
Site Admin
Posts: 647
Joined: Mon Dec 09, 2013 5:02 pm

Re: low power support?

Post by Damien » Wed Mar 25, 2015 9:47 pm

I managed to get the pyboard down to around 300uA in stop mode and 30uA in standby mode using this script:

https://gist.github.com/dpgeorge/bf477eb883b6d189eae9

The 30uA in standby mode is as low as it'll go because it's limited by the quiescent current of the LDO (which is 25uA).

moose
Posts: 9
Joined: Fri Apr 17, 2015 4:22 pm
Location: Anchorage, Alaska
Contact:

Re: low power support?

Post by moose » Mon Apr 27, 2015 4:11 am

Is there any way to reduce the amount of time and/or current required to come out of pyb.standby()? I ran a do-nothing program to determine how much current (actually, charge) is consumed during the bootup after pyb.standby():

Code: Select all

import pyb

rtc = pyb.RTC()
rtc.wakeup(2000)
pyb.standby()
Here is the time pattern of current consumption during the boot-up:
Image

If you need to wake up every 15 seconds to do something, this startup cost is pretty large. Its contribution to the average current consumption would be:

(63 mA * 0.125 s + 21 mA * 0.055 s) / 15 s = 0.602 mA, or 602 uA.

This dwarfs the very nice 32 uA sleep current. During the boot up, I see the green LED blink. Is there a way to stop that? Is that significantly lengthening the startup time? Any other ideas on how to make this more efficient?
Last edited by moose on Sat Nov 07, 2015 7:13 pm, edited 1 time in total.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: low power support?

Post by dhylands » Mon Apr 27, 2015 5:25 am

During a normal boot, the green LED is turned on here:
https://github.com/micropython/micropyt ... ain.c#L317

and turned off here:
https://github.com/micropython/micropyt ... ain.c#L470

So that adds virtually no delay. I think you'd need to profile the boot to see where the time is being spent.

I'm going to guess that initializing the file system is a big chunk of it.

manitou
Posts: 73
Joined: Wed Feb 25, 2015 12:15 am

Re: low power support?

Post by manitou » Tue Apr 28, 2015 10:15 pm

moose wrote:Is there any way to reduce the amount of time and/or current required to come out of pyb.standby()? I ran a do-nothing program to determine how much current (actually, charge) is consumed during the bootup after pyb.standby():
@moose what did you use to measure/plot current?

Post Reply