Page 1 of 3

Saving power

Posted: Tue May 17, 2016 10:20 pm
by Almoturg
I've been trying to reduce the power consumption of my esp-12 with micropython. Currently it uses 80-85mA (through a linear regulator with 20µA quiescent current from ~3.6V) no matter what I do. I have tried using esp.sleep_type() to set either esp.SLEEP_MODEM or esp.SLEEP_LIGHT but the power consumption remains constant. Creating a network.WLAN object and using wlan.active(False) also doesn't change anything.

I would like to at least disable the wifi to get down to ~20mA (here http://bbs.espressif.com/viewtopic.php?t=133 someone measured 15mA with modem sleep). Even better would be light sleep until a GPIO interrupt which seems to go down to below 1mA. (Deep sleep is not an option, I need it to react quickly to button presses.) Not sure if it would help but I don't need the REPL, so disabling that might also help.

Is modem/light sleep not working a bug, or am I missing something?

Re: Saving power

Posted: Fri May 20, 2016 8:23 pm
by pfalcon
If you look at the source code, we directly call underlying vendor SDK functions. So, it works as good, or as bad, as vendor did it. Well, there may be omissions like anywhere else, if someone can point us to any, we appreciate it, as it will allow to achieve improvements quicker. Otherwise, we didn't look into a deep details of low-power modes of ESP8266, and as many other aspects of ESP8266, this will require reverse engineering efforts, as vendor documentation and SDK functionality exposed in general not enough for any advanced usage.

Re: Saving power

Posted: Sun May 22, 2016 12:43 am
by Almoturg
There seems to be a separate function to actually force the sleep mode to begin, see here: https://github.com/esp8266/Arduino/issues/460

There is more info here: http://bbs.espressif.com/viewtopic.php?t=1134

Someone from Espressif posted this sample there

Code: Select all

//sleep over.
void fpm_wakup_cb_func1(void)
{
   wifi_fpm_close();   //disable sleep function
   wifi_set_opmode(STATION_MODE);      //set wifi mode to station mode
   wifi_station_connect();         //connect ap
}

void user_func(...)
{  
wifi_station_disconnect();
wifi_set_opmode(NULL_MODE);      //set wifi mode to null mode.
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);      //set force sleep type, clsoe rf&cpu
wifi_fpm_open();            //enable force sleep fucntion
wifi_fpm_set_wakeup_cb(fpm_wakup_cb_func1);   //Set fpm wakeup callback function 
wifi_fpm_do_sleep(10*1000);         // do sleep
...
}
It would be awesome if you could implement this in Micropython :)

Re: Saving power

Posted: Sun May 22, 2016 4:25 pm
by Almoturg
The force sleep API is described in the API guide in chapter 3.7. There is also a general guide about low power modes.

I have tried to add a simple function esp.force_modem_sleep

Code: Select all

STATIC mp_obj_t esp_force_modem_sleep() {
    wifi_station_disconnect();
    wifi_set_opmode(NULL_MODE);                             //set wifi mode to null mode.
    wifi_fpm_set_sleep_type(MODEM_SLEEP_T);                 //set force sleep type
    wifi_fpm_open();                                        //enable force sleep function
    return mp_obj_new_int(wifi_fpm_do_sleep(0xFFFFFFF));    //sleep until manual wakeup
}
but while it does return 0, the power consumption does not drop. In the API guide there is a note
If this API returned 0 means that the configuration is set successfully, but the ESP8266
will not enter sleep mode immediately, it is going to sleep in the system idle task. Please
do not call other WiFi related function right after calling this API.
could this be the issue (i.e. is the system idle task ever executed in micropython)?

Re: Saving power

Posted: Sun May 22, 2016 6:06 pm
by Almoturg
I just set MICROPY_REPL_EVENT_DRIVEN to 1 and my force_modem_sleep function works now! :D

The current drops to 15mA including regulator losses (the USB powerbank I was using actually switches off now because it thinks nothing is connected).

Is there some reason why MICROPY_REPL_EVENT_DRIVEN 1 is not the default state?

EDIT: light sleep also works with

Code: Select all

STATIC mp_obj_t esp_force_light_sleep() {
    wifi_station_disconnect();
    wifi_set_opmode(NULL_MODE); // set WiFi mode to null mode.
    wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); // light sleep
    wifi_fpm_open(); // enable force sleep
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U,3);
    gpio_pin_wakeup_enable(13, GPIO_PIN_INTR_LOLEVEL);
    //wifi_fpm_set_wakeup_cb(fpm_wakup_cb_func1); // Set wakeup callback
    return mp_obj_new_int(wifi_fpm_do_sleep(0xFFFFFFF));
}
goes down to 1.2mA (!) and wakes up as soon as gpio 13 is connected to ground. REPL works fine afterwards, variables are preserved.

Re: Saving power

Posted: Mon May 23, 2016 11:30 pm
by Almoturg
Unfortunately running any kind of main loop prevents the sleep modes from starting. I first tried using machine.Timer to call my loop function periodically but that doesn't work because you can't do very much in interrupt handlers.

So I thought that as the loop function should be the only thing that is running in non-interrupt mode anyway it should be possible to just call the callback function normally instead of in protected mode. I just copied the machine.Timer function (to machine.MainTimer) and changed "mp_call_function_1_protected" to "mp_call_function_1". I also added a MainTimer.reinit function to rearm a timer (I'm using ONE_SHOT so there can never be two instances of the loop function running in parallel). Everything seems to work fine, but I haven't tested it extensively.

It would be nice to have a non-hacky way of doing something like this. I guess I could try implementing that myself but this is really the first time I've even looked at a non-trivial C program, so someone else is probably more qualified.

Re: Saving power

Posted: Tue May 24, 2016 7:42 am
by pfalcon
Good research and please go ahead with it and share your finding and feel free to prepare patches (if you go that way, please start with small ones, as likely a lot will require changing before it will fit consistent MicroPython API).

MICROPY_REPL_EVENT_DRIVEN isn't default because it lacks many features and is effectively deprecated. Not removed just in case it will be useful for something, like this case.

Re: Saving power

Posted: Mon Aug 08, 2016 8:59 pm
by warren
Almoturg wrote:It would be nice to have a non-hacky way of doing something like this. I guess I could try implementing that myself but this is really the first time I've even looked at a non-trivial C program, so someone else is probably more qualified.
Is there any update to this?

Are you now able reliably and repeatedly to get the ESP into a light sleep mode so that it does not have power-hungry wifi but you can still process stuff with the processor...?

Do you have any code you can share?

Thanks!

Re: Saving power

Posted: Thu Jan 19, 2017 11:08 am
by ioukos
Hello,

I'm still looking for a way to shutdown/disable Wifi on the ESp8266 with microPython. If I've read this topic correctly I guess I can't.

Is there an update ?

Thanks

Re: Saving power

Posted: Sun Mar 26, 2017 12:17 pm
by timi19
Interested in an answer, too!