Saving power
Saving power
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?
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
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.
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
Re: Saving power
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
It would be awesome if you could implement this in Micropython
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
...
}
Re: Saving power
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
but while it does return 0, the power consumption does not drop. In the API guide there is a note
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
}
could this be the issue (i.e. is the system idle task ever executed in micropython)?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.
Re: Saving power
I just set MICROPY_REPL_EVENT_DRIVEN to 1 and my force_modem_sleep function works now!
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
goes down to 1.2mA (!) and wakes up as soon as gpio 13 is connected to ground. REPL works fine afterwards, variables are preserved.
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));
}
Re: Saving power
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.
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
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.
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.
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/
Re: Saving power
Is there any update to this?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.
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
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
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
Interested in an answer, too!