Hi,
How is it possible to light sleep with arduino framework on the ESP8266, i know how to deepsleep and it works but i am interested to do LIGHT_SLEEP so i can benefit from "low power" equal to 0.5mA and have GPIO wake up enabled with gpio_pin_wakeup_enable.
I can't seem to find examples how to do this, anyone tried it ?
donnib
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
Here's what I currently have, it runs, but does not go to Light_sleep.
#include "ESP8266WiFi.h"
#include "gpio.h"
extern "C" {
#include "user_interface.h"
uint16 readvdd33(void);
bool wifi_set_sleep_type(sleep_type_t);
sleep_type_t wifi_get_sleep_type(void);
}
bool sleep = false;
int switchPin = 2;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("before Sleep");
goToLightSleep();
Serial.println("Woken up");
}
void loop() {
// put your main code here, to run repeatedly:
}
void goToLightSleep()
{
if (!sleep)
{
Serial.println("switching off Wifi Modem and CPU");
//stop any clients
///thisclient.stop();
delay(1000);
wifi_set_sleep_type(LIGHT_SLEEP_T);
WiFi.disconnect();
WiFi.mode(WIFI_OFF);
// how do we call this:
//gpio_pin_wakeup_enable(GPIO_ID_PIN(switchPin),GPIO_PIN_INTR_NEGEDGE);
wifi_fpm_open();
wifi_fpm_do_sleep(26843455);
//if(WiFi.forceSleepBegin(26843455)) sleep = true;
}
}
From what i understand light sleep is on by default but only happens when the ESP is in station mode and connected to an access point. The default mode is WIFI_AP_STA so you need to call WiFi.mode(WIFI_STA) and then connect to an access point. I did test this out and it did seem to work and reduce power consumption to a bit less than 1 mA during inactivity, but that was quite a while back now and i've not verified it still works with the lastest ESP/Arduino code and SDK.
antelder - I think you might be talking about modem_sleep where power use goes down to 20mA, - that is on by default but has no effect for me, so I force modem sleep when I don't need wifi.
Light_sleep requires a pin interrupt to wake it, and switches off the CPU and WiFi, so it can't wake itself,
I don't think so but i admit all this area can be confusing and is not well documented so i may be mistaken. However, i'm pretty sure i've tried both those and what i described above is how i got light sleep to work and the power consumption was matching what they say it should be at a bit under 1 mA. Where have you seen it said that light sleep requires a pin interrupt to wake up?
Modem sleep is working an implemented in staring / git.
usage:
when you want to sleep (disable WiFi):
WiFi.forceSleepBegin();
and to enable WiFi again:
WiFi.forceSleepWake();
more info starting here:
https://github.com/esp8266/Arduino/issues/460#issuecomment-168775857
@stevescot yes exactly what i am looking for. I can't find somebody that got this to work yet.
I dug up the old sketch i had for testing light sleep and tried it again with the current 2.0.0 release. WIth this sketch light sleep definately only seems to kick in when in station mode and Wifi is connected and i see a minimum current of about 1 mA. Its a bit hard to see the current use on a multimeter as the current dances around (which is what you'd expect with light sleep, right?, as it keeps waking up every 300 milliseconds or so) but its most of the time showing well under 10mA:
#include <ESP8266WiFi.h>
extern "C" {
#include "user_interface.h"
}
const char* ssid = "BTHub5-72W5";
const char* password = "xxxxxxxxxx";
void setup() {
Serial.begin(115200);
Serial.println();
}
void loop() {
initWifi();
Serial.println("Light sleep:");
wifi_set_sleep_type(LIGHT_SLEEP_T);
doDelays();
Serial.println("None sleep:");
wifi_set_sleep_type(NONE_SLEEP_T);
doDelays();
WiFi.disconnect();
Serial.print("WiFi disconnected, IP address: "); Serial.println(WiFi.localIP());
Serial.println("Light sleep:");
wifi_set_sleep_type(LIGHT_SLEEP_T);
doDelays();
}
void doDelays() {
Serial.println("Yield for 20 sec");
long endMs = millis() + 20000;
while (millis() < endMs) {
yield();
}
Serial.println("Delay for 20 sec");
delay(20000);
}
void initWifi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while ((WiFi.status() != WL_CONNECTED)) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("WiFi connected, IP address: "); Serial.println(WiFi.localIP());
}
That sounds great - will try it...
Note: sleep in AP mode is not possible, since the connected client can send something to any time.
in STA mode the WiFi standard allows the client to sleep (the ESP)
Ran this script findings were:
with light_sleep, when delay is called the modem, and cpu will shut down (going down to 1mA and below for small periods between beacons, )
however - the yield time shows 70mA
Setting to modem_sleep - still when delay is called then power drops to 20mA, given that sleep only happens when you have called delay (then you are not using the CPU)- no reason not to set light sleep.
I am sorry for butting in on the conversation, but I would also be interested in learning how to make use of light-sleep. I just did some testing I can get modem-sleep to work just fine, but light-sleep only works when the ESP is actively connected to the WIFI-network -- I can't get light-sleep to work if I disconnect from the network.
If the ESP is connected to the network the current-draw keeps jumping up and down during delay() (it momentarily drops well below 10mA, so it is definitely working at times) and overall current-draw won't be anywhere near Espressif's claims. On the other hand, disconnecting from the network and forcing modem-sleep works fine -- current-draw stays stable <17mA during delay(). Disconnecting from the network and trying to enter light-sleep either draws current as if the was no power-management at all enabled, ie. >50mA or current-draw stays at <17mA if I force modem-sleep after disconnect.
Is it even possible to get light-sleep to work when disconnected so as to get power-draw down during longer periods of sleep?
I still don't get it, how can light_sleep work without having the GPIO
enable wake ? In the manual
http://russ.russmathis.com/wp-content/uploads/2015/09/9B-ESP8266__Sleep__Function-Description__EN_v1.0.pdf
it is stated that the CPU is in suspend and the clock is off so one need to
wake up the device with GPIO out of light_sleep or ?
On Mon, Jan 11, 2016 at 12:47 PM, WereCatf [email protected] wrote:
I am sorry for butting in on the conversation, but I would also be
interested in learning how to make use of light-sleep. I just did some
testing I can get modem-sleep to work just fine, but light-sleep only works
when the ESP is actively connected to the WIFI-network -- I can't get
light-sleep to work if I disconnect from the network.If the ESP is connected to the network the current-draw keeps jumping up
and down during delay() and overall current-draw won't be anywhere near
Espressif's claims. On the other hand, disconnecting from the network and
forcing modem-sleep works fine -- current-draw stays stable <17mA during
delay(). Disconnecting from the network and trying to enter light-sleep
either draws current as if the was no power-management at all enabled, ie.50mA or current-draw stays at <17mA if I force modem-sleep after
disconnect.Is it even possible to get light-sleep to work when disconnected so as to
get power-draw down during longer periods of sleep?—
Reply to this email directly or view it on GitHub
https://github.com/esp8266/Arduino/issues/1381#issuecomment-170517385.
Yeah that confused me - my assumption is that light sleep as implemented by the core code uses the real-time clock to do an interrupt - so it is not running code and not using WiFi during these periods. However if you manually put the chip into light sleep then you will need to generate an interrupt to wake. That is all empirical - haven't seen documents to tell me that its just what seems to make sense.
@donnib: The PDF says "Under the light-sleep mode, the CPU will not respond to the signal and interrupt from the peripheral hardware interface under the pause state. Therefore, the ESP8266 need to be waked up via external GPIO, and the wake process is less than 3 ms."
I read that as them saying that any interrupts you've attached to GPIO-pin state-changes won't work under light-sleep, but you can designate one GPIO-pin that the ESP will monitor in order to wake up from light-sleep and then it will be able to handle those interrupts. Internal mechanisms based on WIFI and RTC, however, will keep running and working even during light-sleep.
My interpretation may be completely off the base, but that's how I read it.
@torntrousers Thanks! I've spent lot of time to lower current draw by LIGHT_SLEEP_T and the trick is to NOT use WiFi.disconnect();
finally my working the code is:
// Required for LIGHT_SLEEP_T delay mode
extern "C" {
#include "user_interface.h"
}
...
//WiFi.disconnect(); // DO NOT DISCONNECT WIFI IF YOU WANT TO LOWER YOUR POWER !
wifi_set_sleep_type(LIGHT_SLEEP_T);
delay(20000); // 20s
I used it in my ESP8266 with DHT22 IoT client project.
After some head scratching, many many cups of tea and some beer this is my implementation of a stable mA light sleep with gpio_pin_wakeup_enable(GPIO_ID_PIN(1), GPIO_PIN_INTR_HILEVEL);
uses staring / git. for WiFi.forceSleepBegin();
#include <ESP8266WiFi.h>
//include ESP8266WiFi.h needed doesnt show up on post code
extern "C" {
#include "e:/gpio.h" //change to where you have saved gpio.h listed below
}
extern "C" {
#include "user_interface.h"
}
const char* ssid = "SKY8606B";
const char* password = "*******";
int val = 0;
WiFiClient client;
void setup() {
// put your setup code here, to run once:
pinMode(5, INPUT); // set pin to input
digitalWrite(5, LOW); // turn off pullup resistors
Serial.begin(115200);
delay(10);
WiFi.begin(ssid, password);
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
//gpio_pin_wakeup_disable();
gpio_pin_wakeup_enable(GPIO_ID_PIN(1), GPIO_PIN_INTR_HILEVEL);
wifi_set_sleep_type(LIGHT_SLEEP_T);
}
void loop() {
// put your main code here, to run repeatedly:
val = digitalRead(5);
while (val == 1){
// do something repetitive
Serial.println("Pin 5 high");
delay (20000);
}
WiFi.forceSleepBegin();
delay(20000); // 20s
//ESP.deepSleep(60000000, WAKE_RF_DEFAULT); // Sleep for 60 seconds
}
Code needed for gpio_pin_wakeup_enable(GPIO_ID_PIN(1), GPIO_PIN_INTR_HILEVEL); needs to be saved as gpio.h
/*
* copyright (c) Espressif System 2010
*
*/
#ifndef _GPIO_H_
#define _GPIO_H_
#define GPIO_PIN_ADDR(i) (GPIO_PIN0_ADDRESS + i*4)
#define GPIO_ID_IS_PIN_REGISTER(reg_id) \
((reg_id >= GPIO_ID_PIN0) && (reg_id <= GPIO_ID_PIN(GPIO_PIN_COUNT-1)))
#define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0)
typedef enum {
GPIO_PIN_INTR_DISABLE = 0,
GPIO_PIN_INTR_POSEDGE = 1,
GPIO_PIN_INTR_NEGEDGE = 2,
GPIO_PIN_INTR_ANYEDGE = 3,
GPIO_PIN_INTR_LOLEVEL = 4,
GPIO_PIN_INTR_HILEVEL = 5
} GPIO_INT_TYPE;
#define GPIO_OUTPUT_SET(gpio_no, bit_value) \
gpio_output_set((bit_value)<<gpio_no, ((~(bit_value))&0x01)<<gpio_no, 1<<gpio_no,0)
#define GPIO_DIS_OUTPUT(gpio_no) gpio_output_set(0,0,0, 1<<gpio_no)
#define GPIO_INPUT_GET(gpio_no) ((gpio_input_get()>>gpio_no)&BIT0)
/* GPIO interrupt handler, registered through gpio_intr_handler_register */
typedef void (* gpio_intr_handler_fn_t)(uint32 intr_mask, void *arg);
/*
* Initialize GPIO. This includes reading the GPIO Configuration DataSet
* to initialize "output enables" and pin configurations for each gpio pin.
* Must be called once during startup.
*/
void gpio_init(void);
/*
* Change GPIO pin output by setting, clearing, or disabling pins.
* In general, it is expected that a bit will be set in at most one
* of these masks. If a bit is clear in all masks, the output state
* remains unchanged.
*
* There is no particular ordering guaranteed; so if the order of
* writes is significant, calling code should divide a single call
* into multiple calls.
*/
void gpio_output_set(uint32 set_mask,
uint32 clear_mask,
uint32 enable_mask,
uint32 disable_mask);
/*
* Sample the value of GPIO input pins and returns a bitmask.
*/
uint32 gpio_input_get(void);
/*
* Set the specified GPIO register to the specified value.
* This is a very general and powerful interface that is not
* expected to be used during normal operation. It is intended
* mainly for debug, or for unusual requirements.
*/
void gpio_register_set(uint32 reg_id, uint32 value);
/* Get the current value of the specified GPIO register. */
uint32 gpio_register_get(uint32 reg_id);
/*
* Register an application-specific interrupt handler for GPIO pin
* interrupts. Once the interrupt handler is called, it will not
* be called again until after a call to gpio_intr_ack. Any GPIO
* interrupts that occur during the interim are masked.
*
* The application-specific handler is called with a mask of
* pending GPIO interrupts. After processing pin interrupts, the
* application-specific handler may wish to use gpio_intr_pending
* to check for any additional pending interrupts before it returns.
*/
void gpio_intr_handler_register(gpio_intr_handler_fn_t fn, void *arg);
/* Determine which GPIO interrupts are pending. */
uint32 gpio_intr_pending(void);
/*
* Acknowledge GPIO interrupts.
* Intended to be called from the gpio_intr_handler_fn.
*/
void gpio_intr_ack(uint32 ack_mask);
void gpio_pin_wakeup_enable(uint32 i, GPIO_INT_TYPE intr_state);
void gpio_pin_wakeup_disable();
void gpio_pin_intr_state_set(uint32 i, GPIO_INT_TYPE intr_state);
#endif // _GPIO_H_
The reason for setting gpio_pin_wakeup_enable(GPIO_ID_PIN(1), for pin 5
http://esp8266.co.uk/tutorials/introduction-to-the-gpio-api/
Yours pigglet
@ pigglet thanks for posting the code for light sleep with GPIO. Could you please let me know regarding
a. do we need to keep polling the GPIO pin to check the IO status?
b. link http://esp8266.co.uk/tutorials/introduction-to-the-gpio-api/ is not working
c. The GPIO code looks like part of lib, will there be a conflict if we use another gpio.h file in our project? "copyright (c) Espressif System 2010"
d. In my application I am developing I want to be continuously stay in light sleep mode <1-2 mA current and wakeup with MQTT message or GPIO level high, please advice how it could be achieved?
Regards, kk
For anyone else still wondering, the above posters code didn't work for me. I was however able to get light sleep working with a button interrupt for wake up, current draw dropped to 0 mA on my bench power supply. The gpio.h the above poster provided is exactly the same as the one provided in the ESP8266 Arduino library so shouldn't need to save your own.
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
extern "C" {
#include "gpio.h"
}
extern "C" {
#include "user_interface.h"
}
void setup()
{
/* connect to WiFi/normal setup stuff */
gpio_init(); // Initilise GPIO pins
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); // set sleep type, the above posters wifi_set_sleep_type() didnt seem to work for me although it did let me compile and upload with no errors
}
void loop()
{
/* do whatever you want */
gpio_pin_wakeup_enable(GPIO_ID_PIN(2), GPIO_PIN_INTR_LOLEVEL); // GPIO_ID_PIN(2) corresponds to GPIO2 on ESP8266-01 , GPIO_PIN_INTR_LOLEVEL for a logic low, can also do other interrupts, see gpio.h above
wifi_fpm_open(); // Enables force sleep
wifi_fpm_do_sleep(0xFFFFFFF); // Sleep for longest possible time
}
}
The WiFi.forceSleepBegin() function seems to set the sleep type to MODEM_SLEEP_T which would explain why people have had trouble getting into light sleep. (from ...AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.1.0\libraries\ESP8266WiFisrc\ESP8266WiFiGeneric.cpp)
bool ESP8266WiFiGenericClass::forceSleepBegin(uint32 sleepUs) {
_forceSleepLastMode = getMode();
if(!mode(WIFI_OFF)) {
return false;
}
if(sleepUs == 0) {
sleepUs = 0xFFFFFFF;
}
wifi_fpm_set_sleep_type(MODEM_SLEEP_T);
wifi_fpm_open();
return (wifi_fpm_do_sleep(sleepUs) == 0);
}
Do you know whether it restarts the whole device on wakeup like deep sleep does or does it continue in the loop()? I would assume keeping a wireless connection does not work during light sleep, right?
It actually does keep the wireless connection and doesn't restart, just continues in the loop(). I had it sending UDP packets on button press (same GPIO pin that woke up the device) and it didn't need to reset or reconnect.
@mikeyoyoyo
Is it possible to make it light sleep till the device get MQTT message or interrupt triggered?
I haven't tried but the documentation would imply not, "Under the light-sleep mode, the CPU will not respond to the signal and interrupt from the peripheral hardware
interface under the pause state. Therefore, the ESP8266 need to be waked up via external GPIO,". (from Sleep_Function_Description_V1 http://espressif.com/sites/default/files/documentation/9b-esp8266_sleep_function_description_en_v1.0.pdf)
Not much luck for me, I can get it to sleep, but it won't wake up on the designated pin (GPIO4, made sure with an LED that I was using the correct one), not on GPIO_PIN_INTR_LOLEVEL or GPIO_PIN_INTR_HILEVEL or …ANY
GPIO2 and CH_PD are connected as well as RESET and GPIO16 which is supposedly required to enable deep_sleep (which seems to work, although I can't really say that waking up from deep sleep is any faster than a "cold start", it runs through setup() as well).
You couldn't wake it from light sleep or deep sleep? If light what was your code?
I realized I also gave up on deep sleep some time ago and are actually powering down. So the restart is no surprise.
I slightly changed to code above to this:
void setup() {
Serial.write("Setup!");
// Edited to what code really looks like in reply to @mikeyoyoyo
gpio_init();
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
}
void loop() {
sleep();
delay(100);
Serial.write("Woke up!");
}
void sleep()
{
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
gpio_pin_wakeup_enable(GPIO_ID_PIN(4), GPIO_PIN_INTR_HILEVEL); // or LO/ANYLEVEL, no change
wifi_fpm_open();
wifi_fpm_do_sleep(0xFFFFFFF);
}
Without the delay in the loop, I saw continuous writes to Serial which reminded me that I read somewhere that the CPU keeps going for a few more cycles after being put to sleep. With the delay, I don't get to see the "woke up" message anymore and I assume real sleep. Then however, it neither will wake up when I pull up Pin4 to 3.3V.
So if it needs to be sent to sleep in a loop() continuously, this seems strange and I don't understand why you still saw 0mA.
Can you confirm the loop() does in fact stop, without a delay() on the first call to wifi_fpm_do_sleep() in your case?
Did you set
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
anywhere?
I tried your code, it wouldn't compile unless I moved sleep() above loop() after I did, it just seemed to make my chip reset until I added a delay before the sleep() function in loop, but otherwise this worked (I used gpio 2 and low level though)
extern "C" {
#include "gpio.h"
}
extern "C" {
#include "user_interface.h"
}
void setup() {
Serial.begin(115200);
delay(10);
Serial.write("Setup!");
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
}
void sleep()
{
gpio_pin_wakeup_enable(GPIO_ID_PIN(2), GPIO_PIN_INTR_LOLEVEL); // or LO/ANYLEVEL, no change
wifi_fpm_open();
wifi_fpm_do_sleep(0xFFFFFFF);
}
void loop() {
delay(1000);
sleep();
delay(100);
Serial.write("Woke up!");
}
And yes if I removed the delay after sleep() it would still execute Serial.write("Woke up!"); before it went to sleep.
@mikeyoyoyo Thanks! That was a sloppy job of mine, I did not copy and paste real code but wrote it on the fly from memory; I basically put your code from loop() in a separate function and added Serial.write()s and delay().
In your example, there's no more gpio_init() – maybe I'll try it without!
@Yoshi20 writes in #557:
The problem now is, that light sleep won't be activated unless the ESP8266 is connected to a WLAN (or was connected once -> it seems to save the ssid and the ssid-pw internaly!)
@mikeyoyoyo It seems to work for you w/o being connected to an AP, right?
whats written is copied code i posted the other day all be it with altering such as woke up as opposed to waking up, but still it is wrong. To wake up after the cpu has gone to sleep requires an interrupt on GPIO.0 i.e pin taken high and your tristate and port pins set accordingly. I am still unsure until a full data sheet showing all registers is available if using this device is viable or not
@TomTom101
No worries, yeah I found gpio_init() was needed if I wanted to use digitalRead() or something in my actual code but not needed just to wake it up, I assume pinMode() or the arduino functions call it somewhere.
Yeah I wondered initially if that was a problem (not connected to an AP) but it worked without it being connected so I guess not. Not mentioned in the documentation either (like it does for modem sleep).
I sort of see some sleeping now with this
#include <ESP8266WiFi.h>
extern "C" {
#include "gpio.h"
}
extern "C" {
#include "user_interface.h"
}
#define LIGHT_WAKE_PIN 4
void setup()
{
Serial.begin(115200);
Serial.println("Setup");
delay(100);
}
void loop()
{
sleep();
delay(100);
Serial.println("Woke up form sleep");
}
void sleep()
{
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
wifi_fpm_open();
gpio_pin_wakeup_enable(GPIO_ID_PIN(LIGHT_WAKE_PIN), GPIO_PIN_INTR_HILEVEL);
wifi_fpm_do_sleep(0xFFFFFFF);
}
I pulled down PIN2 and it wakes on high level. However I see around 970µA of power consumption, not the 500µA as mentioned in #460 :-/
When I connect to an AP in setup(), it consumes 3.3mA during sleep, not quite battery compatible …
@TomTom101 @mikeyoyoyo
Hello, I've given up with deep sleep, because it works for some times then it hangs on reset (gpio 0 and 2 up, 15 down, 16 to RST), as it is reported in many other forums.
I've made modem sleep work, it activates and deactivates, but it passes from 76mA to 22mA only:
WiFi.disconnect();
WiFi.mode(WIFI_OFF);
delay(1);
WiFi.forceSleepBegin();
delay(15000);
when in delay stays at 22mA and then loops.
I've managed to enter light sleep, and it goes from 76mA to 7mA, but I'm unable to wake it up:
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
wifi_fpm_open(); // Enables force sleep
Serial.println("A");
wifi_fpm_do_sleep(0xFFFFFFF); // Sleep for longest possible time
delay(1);
Serial.println("A");
it never gets to "A", and it stays at 7mA
Doing any combination of wait with both the wifi_fpm_do_sleep argument or with the delay:
wifi_fpm_do_sleep(10000000); // Sleep for longest possible time
delay(10000);
Serial.println("A");
it gets to print "A", but never goes to 7mA, always 76mA.
Any suggestion?
At this point going to 7mA and back would be great.
Hi check this out. (3.3 point in the PDF) Light sleep requires External signal to wake up that is what I understand from this doc. Still 7mA seems more may be you have power led on board. By the way anyone has a well documented code?
http://espressif.com/sites/default/files/documentation/9b-esp8266_sleep_function_description_en_v1.0.pdf
@torntrousers I used your code for testing that device goes in sleep or not and to find the activity. I am using a 0.1Ohm Resistor in my system(I can't show you schematic, contain other things of company) but has ESP8266 as Network processor. so I tested your code on it and thus found that your code works in delay for light sleep and around 20mA of power is consumed. We have a efficient DC-DC convertor for 3.3 volt but Signals have lots of noise I am not sure why(We have a very indian made oscilloscope can trust on filtering :P ) bt here is the video.
@shirish47 Can you check my code ? I have 1mA at light sleep.
Serial.println("going to light sleep / 0xFFFFFFF");
delay(100);
wifi_station_disconnect();
wifi_set_opmode(NULL_MODE);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
wifi_fpm_open();
gpio_pin_wakeup_enable(GPIO_ID_PIN(DOOR_INT_PIN), GPIO_PIN_INTR_HILEVEL);
wifi_fpm_do_sleep(0xFFFFFFF);
delay(200);
gpio_pin_wakeup_disable();
Serial.println("wake up / 0xFFFFFFF");
wifi_fpm_close();
wifi_set_opmode(STATION_MODE);
wifi_station_connect();
wifi_connect();
delay(100);
@chaeplin I will do it bt right now my hardware has other controller on board so I can't give to exact current. I am working on making a power meter to do such things. :) that will give use better comparision intead of just pick current. My board might be taking more current because of other reasons but I would make a seperate ESP board to do current test.
@shirish47 I have removed all the LEDs(20mA). I use ucurrent gold to check current.
graph is here
Oh thats an awesome tool. your graph looks cool . My ESP8266 is ESP-12E module(I am not sure of this but it only has one LED connected to GPIO pin and PCB antenna)
Btw It would be great if we can measure power for 1min operation in each mode. that kind of test can give better view that is what I am thinking of. so working on that.
Sorry to maybe ask a dumb question, but if I just want to get into light sleep during delays, I just call "wifi_set_sleep_type(LIGHT_SLEEP_T);" in setup() and it will go into light sleep whenever I call delays?
No not quite, you call "wifi_set_sleep_type(LIGHT_SLEEP_T);" in setup(), then you have to put it to sleep by calling wifi_fpm_do_sleep(0xFFFFFFF) where 0xFFFFFFF is the length of sleep (not sure which units its in) and you generally have to put a delay call after the sleep call as it take a little bit of time to go to sleep (to stop it running code after the do_sleep call but before it goes to sleep).
Thanks! I could get it to work with that, but any hexadecimal value other than 0xFFFFFFF / 0xFFFFFF produces WDT resets or gibberish for me, so it seems it's unfortunately not useable for what I wanted to do, i.e. wake up after a minute or so of sleep.
I see that's a bit odd I wonder why, I know the length of your program has to be longer than the beacon time of the router for it to enable light sleep. That doesn't really explain resets though.
I searched around and according to http://bbs.espressif.com/download/file.php?id=1294 wifi_set_sleep_type(MODEM_SLEEP_T) should be enough to use light sleep during delays etc, strangely. I unfortunately don't have a way to test the current consumption at those values, otherwise I'd test that. Would be a nice, clean and easy way if it worked.
hey light sleep does not make the ESP sleep it just makes wifi radio turned on and off based on DTMI interval. you just check that out in datasheet. I am not sure because its long I forgot stuff. but I think you need deep sleep instead of light.
I now have a USB ammeter to test the current and tried to get light sleep to work using the code provided in the SDK documentation, I even tried adding delays copiously, but no dice... Current consumption stays the same and the loop continues, even though the callback function seems to fire after the specified 60 seconds... (I'm using the latest stable release, before it would not compile anyway)
Code:
#include <ESP8266WiFi.h>
extern "C" {
#include "user_interface.h"
}
const char* ssid = "***";
const char* password = "***";
const char* espname = "D1-Sleep";
int counter = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
//wifi_set_sleep_type(LIGHT_SLEEP_T); // LIGHT_SLEEP_T for sleep, NONE_SLEEP_T FOR NO SLEEP
WiFi.hostname(espname);
WiFi.mode(WIFI_STA);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
WiFi.begin(ssid, password);
delay(500);
}
}
void loop() {
Serial.println(counter);
counter++;
if (counter % 10 == 9) {
sleepNow();
}
delay(2000);
}
void fpm_wakup_cb_func1(void) {
wifi_fpm_close(); // disable force sleep function
wifi_set_opmode(STATION_MODE); // set station mode
wifi_station_connect();
Serial.println("Woken up...");
}
void sleepNow() {
Serial.println("Going to sleep...");
wifi_station_disconnect();
wifi_set_opmode(NULL_MODE);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); // light sleep
wifi_fpm_open(); // enable force sleep
wifi_fpm_set_wakeup_cb(fpm_wakup_cb_func1); // Set wakeup callback
delay(1000);
wifi_fpm_do_sleep(60*1000*1000);
delay(1000);
}
Serial output:
0
1
2
3
4
5
6
7
8
Going to sleep...
9
10
11
12
13
14
15
16
17
18
Going to sleep...
19
20
21
22
23
24
25
26
27
28
Going to sleep...
29
30
31
32
33
34
35
Woken up...
36
37
38
Going to sleep...
39
40
41
42
43
44
45
46
47
48
Going to sleep...
49
50
51
52
53
54
55
56
57
58
Going to sleep...
59
60
61
62
63
64
65
Woken up...
66
67
68
Going to sleep...
69
70
71
72
73
74
75
76
77
78
Going to sleep...
79
80
81
82
83
84
85
86
87
88
Going to sleep...
89
90
91
92
93
94
95
Woken up...
96
97
98
Going to sleep...
99
100
101
102
103
104
105
106
107
108
Going to sleep...
109
110
111
112
113
114
115
116
117
118
Going to sleep...
119
120
121
122
123
124
125
Woken up...
126
Is it possible to leave ESP8266 in light sleep (as STA) and still periodically respond to messages from a smartphone App that is on the same AP? Could the App send out a set of redundant messages, which the ESP could periodically wake up and listen for? Or would I have to buffer the instructions on a server which ESP would query 1x per minute?
I have reliable communication between ESP / phone, but only tried it in full power mode. I need average current <= 1 mA.
Would really appreciate advice / feedback.
I think you could set it to light sleep for a set period of time and then
wake up and be able to receive messages. If you want current average less
than 1mA it would have to be asleep for large percentage of time though.
On 12 Aug 2016 11:29 AM, "JohnHeath2" [email protected] wrote:
Is it possible to leave ESP8266 in light sleep (as STA) and still
periodically respond to messages from a smartphone App that is on the same
AP? Could the App send out a set of redundant messages, which the ESP could
periodically wake up and listen for? Or would I have to buffer the
instructions on a server which ESP would query 1x per minute?I have reliable communication between ESP / phone, but only tried it in
full power mode. I need average current <= 1 mA.Would really appreciate advice / feedback.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/esp8266/Arduino/issues/1381#issuecomment-239340380,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALPNydMmrUHDIXXgMDDPU8Khek49DhZfks5qe8x_gaJpZM4HAMqu
.
This sleep has been quite an adventure. I wanted precise sleep. When the device goes in light sleep the main counter goes slower and thus things like millis() are slower. Normally it's ok, but actually it causes delay() to wake up about 1% later witch is rather stupid. I tried to use the internal RTC(witch I think stands for real time counter, not clock), but after fiddling with the calibration value, it was still quite imprecise. So I did some measurements and calculated how much i have to subtract from the sleep delay to get the delay I want.
In the end, my code looks something like this.
void setup()
{
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
WiFi.setSleepMode(WIFI_LIGHT_SLEEP);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
// ...
}
void loop()
{
// ...
if (toSleep > 0)
{
wifi_set_sleep_type(LIGHT_SLEEP_T);
unsigned long extraSleep = toSleep * 0.011;
delay(toSleep - extraSleep);
previousMillis -= extraSleep;
}
}
Now this works almost perfectly except that after some time (~20 hours) delay() stops sleeping, the ESP starts using full power and delay() becomes very precise again. Maybe because wifi reconnected?
Did someone have similar issues? Any help?
I'm using the following code and it can only be wake up for one time then doesn't response to GPIO2 state changes.
Update: it is now working if when I pull down GPIO2. (GPIO2 is pulled up with external 1K resistor to 3.3V)
#include <FS.h> //this needs to be first, or it all crashes and burns...
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <Ethernet.h>
extern "C" {
#include "gpio.h"
}
extern "C" {
#include "user_interface.h"
}
#define ioctrl 14
#define LIGHT_WAKEUP 2 //define GPIO5 as wake up pin for light sleep
IPAddress broadcastIp(255, 255, 255, 255);
unsigned int relay1Port = 8267; //remote udp port of the relay1
char packetBuffer[10]; //only read 10 bytes of the udp packet
char onBuffer[] = "LAMPON";
char offBuffer[] = "LAMPOFF";
int onflag = 0;
WiFiUDP Udp;
WiFiClient client;
void configModeCallback (WiFiManager *myWiFiManager) {
Serial.println("Entered config mode");
Serial.println(WiFi.softAPIP());
//if you used auto generated SSID, print it
Serial.println(myWiFiManager->getConfigPortalSSID());
}
void setup() {
// put your setup code here, to run once:
// gpio_init(); // Initilise GPIO pins
Serial.begin(115200);
Serial.println();
pinMode(ioctrl, INPUT);
pinMode(LIGHT_WAKEUP, INPUT);
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wifiManager;
//exit after config instead of connecting
wifiManager.setBreakAfterConfig(true);
wifiManager.setAPCallback(configModeCallback);
wifiManager.autoConnect();
while (WiFi.status() != WL_CONNECTED)//
{
delay(500);
Serial.print(".");
//if you get here you have connected to the WiFi
Serial.println("Wifi Connected :)");
Serial.println("Local Ip Address");
Serial.println(WiFi.localIP());
delay(100);
}
void loop()
{
Serial.println("Ready to go into light sleep...");
delay(1000);
Serial.println("3...");
delay(1000);
Serial.println("2...");
delay(1000);
Serial.println("1...");
sleepNow();
/*some udp code here...*/
}
void fpm_wakup_cb_func1(void) {
wifi_fpm_close(); // disable force sleep function
wifi_set_opmode(STATION_MODE); // set station mode
wifi_station_connect();
Serial.println("Woke up from sleep...");
}
void sleepNow() {
Serial.println("Going into light sleep...");
wifi_station_disconnect();
wifi_set_opmode(NULL_MODE);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); // light sleep
gpio_pin_wakeup_enable(GPIO_ID_PIN(LIGHT_WAKEUP), GPIO_PIN_INTR_LOLEVEL);
wifi_fpm_open(); // enable force sleep
delay(100);
wifi_fpm_set_wakeup_cb(fpm_wakup_cb_func1); // Set wakeup callback
wifi_fpm_do_sleep(0xFFFFFFF);
delay(100);
}
I am finding difficulty in waking esp from deep sleep. it worked on GPIO 4 pin but on GPIO pin its not responding to the signal. I actually changed the library line from NONE_LIGHT_SLEEP to LIGHT_SLEEP.
if((digitalRead(tiltupdate) == HIGH)&&(digitalRead(updateline) == HIGH)){
// digitalWrite(wakestate,LOW);
delay(10);
gpio_pin_wakeup_enable(GPIO_ID_PIN(16), GPIO_PIN_INTR_LOLEVEL);
delay(20);
WiFi.forceSleepBegin(0xFFFFFFF);
delay(50);
WiFi.forceSleepWake();
}
Hi All - I've read through this thread a bunch and it's been super helpful! Unfortunately, I'm also having a difficult time getting the ESP to wake up from light sleep. I can get it to sleep but it seems like the interrupt on my pin never registers. I'm using Arduino IDE on a Huzzah ESP8266 breakout. I have a PIR sensor connected to two pins: Pin 4 to listen and Pin 0 for the interrupt. Once it goes to sleep, it never wakes up however, I have noticed that the built-in LED (on gpio0) still blinks when I pass in front of the PIR even in sleep. That tells me something is registering and I'm not that far off. But can some help me understand what I'm missing?
`#include
extern "C" {
}
extern "C" {
}
int state = LOW;
const char* ssid = "myNetwork";
const char* password = "myPassword";
WiFiClient client;
void setup() {
//WifiClient client;
Serial.begin(115200);
Serial.print("initializing GPIOs");
gpio_init();
pinMode(4, INPUT); //this pin is connected to the PIR sensor
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
delay(1000);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
gpio_pin_wakeup_enable(GPIO_ID_PIN(0), GPIO_PIN_INTR_HILEVEL); //I've also connected the PIR sensor to pin 0.
}
void loop() {
delay(3000);
Serial.println("reading PIR");
int state = digitalRead(4);
if (state == HIGH) {
Serial.println("Motion detected");
state = LOW;
} else {
Serial.print("about to go to sleep");
wifi_fpm_open();
wifi_fpm_do_sleep(0xFFFFFFF);
delay(5000);
return;
}
}`
Do any of the serial prints happen? Or it just seems to never wake up?
On 5 Nov 2016 5:19 AM, "davescherler" [email protected] wrote:
Hi All - I've read through this thread a bunch and it's been super
helpful! Unfortunately, I'm also having a difficult time getting the ESP to
wake up from light sleep. I can get it to sleep but it seems like the
interrupt on my pin never registers. I'm using Arduino IDE on a Huzzah
ESP8266 breakout. I have a PIR sensor connected to two pins: Pin 4 to
listen and Pin 0 for the interrupt. Once it goes to sleep, it never wakes
up however, I have noticed that the built-in LED (on gpio0) still blinks
when I pass in front of the PIR even in sleep. That tells me something is
registering and I'm not that far off. But can some help me understand what
I'm missing?`#include
extern "C" {
include "gpio.h"
}
extern "C" {include "user_interface.h"
}
int state = LOW;
const char* ssid = "myNetwork";
const char* password = "myPassword";
WiFiClient client;void setup() {
//WifiClient client;
Serial.begin(115200);
Serial.print("initializing GPIOs");
gpio_init();
pinMode(4, INPUT); //this pin is connected to the PIR sensor
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);delay(1000);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
gpio_pin_wakeup_enable(GPIO_ID_PIN(0), GPIO_PIN_INTR_HILEVEL); //I've
also connected the PIR sensor to pin 0.
}void loop() {
delay(3000);
Serial.println("reading PIR");
int state = digitalRead(4);
if (state == HIGH) {
Serial.println("Motion detected");
state = LOW;
} else {
Serial.print("about to go to sleep");
wifi_fpm_open();
wifi_fpm_do_sleep(0xFFFFFFF);
delay(5000);
return;
}
}`—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/esp8266/Arduino/issues/1381#issuecomment-258509190,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALPNyaScFgN-lrsibM7ihHJkvtUYwcYoks5q63cWgaJpZM4HAMqu
.
Hey Mike - thanks for the reply. I have good news! On a whim, I decided to use some of Simonliu009 callback code and everything seems to be working as I expected. I think what I wasn't putting together is that I needed to declare wifi_fpm_set_wakeup_cb(some_wakeup_function); before I called wifi_fpm_do_sleep(0xFFFFFFF); so that it knows what to do when the interrupt registers on the Pin. Now that I type that out it's like, duh, but I guess I had a hard time making sense of the comments in the gpio header file. Anyway, I wanted to share my successful code since I'm able to put the ESP to sleep, and wake it up using a PIR sensor, without having to pull any gpio's up or down, or have RST connected to 16 or EN. So a pretty simple hardware solution to use as a starting place for others. Thanks to everyone for helpful thread! I learned a lot.
#include <ESP8266WiFi.h
extern "C" {
#include "gpio.h"
}
extern "C" {
#include "user_interface.h"
}
const char* ssid = "myNetwork";
const char* password = "myPassword";
WiFiClient client;
void setup() {
Serial.begin(115200);
Serial.print("initializing GPIOs");
gpio_init();
pinMode(0, INPUT); // this pin is connected to the PIR sensor.
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
delay(1000);
}
void loop() {
Serial.println("Ready to go into light sleep...");
delay(1000);
Serial.println("3...");
delay(1000);
Serial.println("2...");
delay(1000);
Serial.println("1...");
sleepNow();
}
void sleepNow() {
Serial.println("going to light sleep...");
wifi_station_disconnect();
wifi_set_opmode(NULL_MODE);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); //light sleep mode
gpio_pin_wakeup_enable(GPIO_ID_PIN(0), GPIO_PIN_INTR_HILEVEL); //set the interrupt to look for HIGH pulses on Pin 0 (the PIR).
wifi_fpm_open();
delay(100);
wifi_fpm_set_wakeup_cb(wakeupFromMotion); //wakeup callback
wifi_fpm_do_sleep(0xFFFFFFF);
delay(100);
}
void wakeupFromMotion(void) {
wifi_fpm_close;
wifi_set_opmode(STATION_MODE);
wifi_station_connect();
Serial.println("Woke up from sleep");
}
Good to hear Dave. Although you don't have to do a callback function as I never had to use one, I assume it just re-enters the line after the do_sleep() call. Nicer to use a function though so thanks for sharing.
@davescherler that sounds great, I'll give your code a try. Do you know what current consumption you get while its sleeping and/or how long it takes to connect the WiFi when waking up?
hey @torntrousers I haven't been able to find my multimeter anywhere - so no, unfortunately I don't know the consumption rate. Were you able to get the code to work? I'm curious because after several successful tests, I decided it was time to incorporate the code into my larger project - which I just did this afternoon. But now, the callback function (wakeupFromMotion) doesn't seem to get called. Once it goes to sleep, it's asleep and can't be woken up. I'm using the same exact pins and header files and everything. So bizarre. I'm running out of ideas on why this is happening. I was hoping you might have given it a go and have some insight? Thanks!
Hi @davescherler , I have given it a try now. I've got it to work once but the rest of the time its like you see now and it wont wake up from light sleep. Odd that it did work correctly once, I don't think I changed anything before or after that time. When its light sleeping the current consumption drops to about 6.5mA. I'll keep playing around and see if I can find any way to get it to wake up consistently.
Some success - the wake up pin can not be floating. If its floating when it enters light sleep then it wont wake up, but if its pulled low then it does seem to consistently wake up by taking it high.
I'm just using a jumper to connect the pin to GND or VCC, hopefully a pull down resistor would work too.
Still some oddness with the current consumption. From the doc light sleep current should be under 1mA, occasionally I get that and it light sleeps at about 0.7mA, but more often its 3mA and occasionally 6.5mA.
@torntrousers thanks for sharing that update. The failure I experienced makes more sense now. The project I'm trying to incorporate this light-sleep/wake up with PIR is still in the breadboarding phase and has a good amount of components connected. Your conclusion - which is in line with other threads on this issue - that the pin can't be floating tells me I might be getting some noise on my pin that's disrupting the HIGH pulse to be detected. So that is very helpful! I will try again with a pull down resistor and see if that sorts things out. I hope it's that simple! Also, I bought another multimeter today so I'll check the consumption rate during light sleep and report back so we can compare notes.
@torntrousers so I've been able to have some consistent success with waking the unit up from light sleep using a pull down resistor (22K). The pin seems to register movement consistently and fire the callback function so that makes me happy.
Great. Have you looked at current consumption? Consistently sleeping at 0.7mA too would be a bonus.
FWIW the latest git code has been updated to the 2.0 sdk now and light sleep seems to work reliably. I'm consistently getting light sleep at less than 0.5mA now.
Somehow i didn't find a working example of a working timed LIGHT_SLEEP, so after trying lots of things in the last couple of nights to get it work, i decided to post mine, as well as some observations, that could be helpful for others that dig into the topic.
So the example that works, and the device is consistently sleeping @ <1ma is this one
void callback() {
Serial << "a"<<endl;
Serial.flush();
}
void loop() {
//wifi_station_disconnect(); //not needed
uint32_t sleep_time_in_ms = 2000;
wifi_set_opmode(NULL_MODE);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
wifi_fpm_open();
wifi_fpm_set_wakeup_cb(callback);
wifi_fpm_do_sleep(sleep_time_in_ms *1000 );
delay(sleep_time_in_ms + 1);
}
Keep in mind that all of those are observations. I've tried to test all permutations, but it is possible that i've missed something important
I am using the GIT as of today.
Really hope this would help someone not spend hours trying all this out :)
I also did some testing on the current stable version. Sadly it is missing some of the fixes in the later cores, but anyway, it is possible to get to ~5ma light sleep, which is not optimal, but also a bit better than the modem_sleep. So far what i tested is this code
void loop() {
connectToWifi();
delay(1000);
wifi_station_disconnect(); //not needed
wifi_set_opmode(NULL_MODE);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
wifi_fpm_open();
wifi_fpm_set_wakeup_cb(callback);
for (int i=0; i < 2000; i++) {
wifi_fpm_do_sleep(500L*1000 );
delay(1050);
}
wifi_fpm_close();
}
it looks like that if the sleep time is more than 2seconds, it does not go to lightsleep, rather just modem_sleep
Also in one out of 4 iterations when the sleep time is < 2 seconds it does not go to light sleep.
When the sleep time is 2 seconds, it seems like half of the iterations it does not go to light sleep.
With the sample above, what i get as current consumption, looks like this

the 500ms high parts are ~20ma, the rest is <1ma.
And the peaks, at 5ms/div resolution look like this

and repeat each 500 ms. They are about 80 ma, and last for 5 ms. This is when the callback function is called. Which means that in those iterations the avg consumption is ~0,8 ma, but given the fact that 25% of the time it is ~20ma, it would average to ~5ma.
Maybe there is more that can be done, but with the skills in electronics and programming i have, this is what i could extract
It is definitely not for ultra-low power scenarios, but i need to turn on and off sensors that consume ~20-30 ma. So sleeping at 5ma and no consumption from the sensors is a bit better than deep sleep and no ability to manipulate the sensors (at least i wasn't able to have GPIOs hold their state during deep sleep)
I'll throw in my 2 cents, too. Thanks to @davescherler and @torntrousers, I realized that my board would not ever wake when the pin was already high (or low, if that's how you set it up). So, I added a little loop to wait until the pin is in the right state before entering sleep mode.
My working code (using the latest library from git today...not tested against the last official release, which is about 9 months old at this point):
#include <ESP8266WiFi.h>
extern "C" {
#include "user_interface.h"
}
void setup() {
Serial.begin(115200);
Serial.write("\n\nSetup!\n");
}
void loop() {
Serial.write("Go to Sleep!\n");
sleep();
Serial.write("Am awake!\n");
}
void sleep()
{
while(digitalRead(GPIO_ID_PIN(15))){
delay(1);//can't go to sleep when the pin is high, otherwise we won't wake!
}
wifi_station_disconnect();
wifi_set_opmode(NULL_MODE);
wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
wifi_fpm_open();
gpio_pin_wakeup_enable(GPIO_ID_PIN(15), GPIO_PIN_INTR_HILEVEL); // or LO/ANYLEVEL, no change
Serial.write("Sleep!\n");
Serial.flush();
wifi_fpm_do_sleep(0xFFFFFFFF);
delay(100);
Serial.write("Woke up!\n");
//Restore WiFi settings here?
}
A few notes:
gpio_pin_wakeup_enable and the wifi_fpm_do_sleep, and still had problems, so I suspect that the gpio_pin_wakeup_enable is really what's sensitive to the pin level.wifi_fpm_do_sleep, and 0xFFFFFFFF seems to be necessary.To add to this topic, Deep Sleep behaves differently with different NodeMCUs.
I spent 3 hours yesterday trying to get my mA under 2, as many have experienced. Only when I changed my device to a different NodeMCU could I get it working.
Summary: verify your device. :)
Device 1 @ 10 mA!
Device 2 @ .24 mA!
Compare the Devices!
Using the code:
`#include
WiFiClientSecure espClient;
String ssid = "myWiFi";
String password = "myPSK";
void connectToWiFi() {
if (WiFi.status() != WL_CONNECTED) {
WiFi.mode(WIFI_STA);
WiFi.stopSmartConfig();
WiFi.enableAP(false);
WiFi.begin(ssid.c_str(), password.c_str());
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
}
void setup() {
Serial.begin(115200);
connectToWiFi();
}
void loop() {
connectToWiFi();
delay(1000);
ESP.deepSleep(1000000 * 60 * 3); // deepSleep for 3 minutes
delay(20000); // will never get here, deepSleep will take over
}
`
keep in mind that if you power via 5v, also the usb2serial chip can be
powered (or even via 3.3v) for best consistency power it using a usb cable
that has the D+ and D- cut through, this way the usb 2 serial chip will go
to sleep and consume ~0.5 ma, else it consumes 15 ma (ch340g)
On Fri, Mar 31, 2017 at 10:49 PM, ksaye notifications@github.com wrote:
To add to this topic, Deep Sleep behaves differently with different
NodeMCUs.I spent 3 hours yesterday trying to get my mA under 2, as many have
experienced. Only when I changed my device to a different NodeMCU could I
get it working.Summary: verify your device. :)
Device 1 @ 10 mA! https://1drv.ms/i/s!As1Irph5sA_-o_QkCgXSy2mJ3cNTtw
Device 2 @ .24 mA! https://1drv.ms/i/s!As1Irph5sA_-o_Qlwg_Z9QKLXZ5yQw
Compare the Devices! https://1drv.ms/i/s!As1Irph5sA_-o_Qjmg6pD6QBBFm2EgUsing the code:
`#include
include
include
include
include
include
include
include
include
include
WiFiClientSecure espClient;
String ssid = "myWiFi";
String password = "myPSK";void connectToWiFi() {
if (WiFi.status() != WL_CONNECTED) {
WiFi.mode(WIFI_STA);
WiFi.stopSmartConfig();
WiFi.enableAP(false);
WiFi.begin(ssid.c_str(), password.c_str());
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
}void setup() {
Serial.begin(115200);
connectToWiFi();
}void loop() {
connectToWiFi();
delay(1000);
ESP.deepSleep(1000000 * 60 * 3); // deepSleep for 3 minutes
delay(20000); // will never get here, deepSleep will take over
}
`—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/esp8266/Arduino/issues/1381#issuecomment-290812608,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAeDpxBcGU2sRg-hGulY1BQ33YtSqd-vks5rrVjEgaJpZM4HAMqu
.
I can confirm @ksaye findings with the provided code. NodeMCU v0.9 consumes 1mA where NodeMCU v1 consumes 11mA.
This is with both units powered with 3.3V on the 3.3V pin, no USB attached.
The one at the right seems to be the Lolin v3 one, could it be?
I have that one, so it seems I'm out of luck....
I can't confirm the exacts. It was purchased here: https://www.amazon.com/HiLetgo-Version-NodeMCU-Internet-Development/dp/B010O1G1ES/
Get Outlook
From: Naguissa
Sent: Wednesday, April 5, 5:29 PM
Subject: Re: [esp8266/Arduino] LIGHT_SLEEP HOW ? (#1381)
To: esp8266/Arduino
Cc: Kevin Saye, Mention
The one at the right seems to be the Lolin v3 one, could it be?
I have that one, so it seems I'm out of luck....
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://github.com/esp8266/Arduino/issues/1381#issuecomment-292015788, or mute the threadhttps://github.com/notifications/unsubscribe-auth/APGndEeOU3xK2aXu6V9sq-Iq5dNNtVKCks5rtBWxgaJpZM4HAMqu.
Or both commited same error or you correctly supposed I was wrong:
Linked o e is Amica one, NodeMCU v.1.0 (or v2).
The mistake was that I was referring to left one but wrote right...
Then I have to try with Lolin o ne. It's same v.1.0 with minor changes and they called it v3...
Hello !
This light sleep mode drive me a bit mad ...
From the esp spec, I understood that light sleep is supposed to be still connected to AP, only go in standby between DTIM beacon.
So, why is it needed to disconnect() and/or set to "WIFI_OFF" ? Then when waking up, wifi is disconnected (or IDLE status)
My target is send some MQTT data every 3 seconds. I am interested in light sleep instead of deep sleep because I would like to avoid reconnecting every 3 seconds (it take ~500ms, killing my average consumption).
I managed to go in light sleep (consumption is not visible anymore on my USB ampmeter) but wifi need a full reconnexion when I'm back from sleep.
Any ideas ?
Hi @mblythe86,
I need to use the same light sleep mode in my project where i need to wake it up by a constant power supply.(i.e., Whenever it external supply connected it will wake up the circuit).
The biggest problem for me is when i connect the external power supply it will wake up and doesn't go to Sleep, Since the gpio is still HIGH.
I have tried that POSEDGE and NEGEDGE interrupts nothing works in my case.
how to achieve this ????
Any Suggestions ????
Hey @bonjour81, did you manage to get light sleep to work? I have the same problem, also tried with modem sleep but still get disconnected during sleep.
Hello! Well on consumption point of view it looks like light sleep but connexion is lost (while I expected to keep connexion)
I wanted to use it for wind speed sensor, sending data every 3sec. But as connexion is lost, it has no advantages I need ~0.5sec to reconnect so average current is too high :-(.
All examples I found use a disconnect command before going to light sleep...
@vlast3k
Checking software timers from this variable (extern os_timer_t *timer_list;) always shows there are, but this is not a problem (at least in this plain program, and i couldn't understand how to check if one of them is running)
extern os_timer_t *timer_list;
for(uint8_t i = 0; i < 20; i++){
Serial.printf("address_current= %p\n", timer_list);
Serial.printf("timer_expire= %u\n", timer_list->timer_expire);
Serial.printf("timer_period= %u\n", timer_list->timer_period);
Serial.printf("address_next= %p\n", timer_list->timer_next);
//os_timer_disarm(timer_list);
if(timer_list->timer_next){
timer_list = timer_list->timer_next;
}
else{
break;
}
In the first loop, there are 3 timers running, in my second loop still one.
When not running, the timer is not in the list.
you can disarm the timer like in the comment. This crashes (on the last timer?)
I am not sure my printout is correct.
I create a timer in setup:
os_timer_t myTimer;
os_timer_setfn(&myTimer, timerCallback, NULL);
os_timer_arm(&myTimer, 1000, true);
Serial.printf("address_myTimer= %p\n", &myTimer);
//os_timer_disarm(&myTimer);
void timerCallback(void *pArg){
digitalWrite(PIN_LED, !digitalRead(PIN_LED));
}
Gives me following printout:
//In setup
address_myTimer= 3ffee488
//In first loop
address_current= 3ffee488 //My created timer
timer_expire= 1993110
timer_period= 312500
address_next= 3ffede68
address_current= 3ffede68 //Unknown timer
timer_expire= 2648605
timer_period= 937500
address_next= 3ffe8ac4
address_current= 3ffe8ac4 //Unknown timer
timer_expire= 2648611
timer_period= 0
address_next= 3ffee4c4
address_current= 3ffee4c4 //Unknown timer
timer_expire= 18830985
timer_period= 18750000
address_next= 00000000
//Next loop
//My timer has stopped working
address_current= 3ffee4c4 //Unknown timer
timer_expire= 18830985
timer_period= 18750000
address_next= 00000000
I can't get my sleep under 15 mA, and did everything carefully as described.
Spent some hours searching but can't get past modem sleep I suppose because of the timers.
@DarkShadowNight , have you checked if this isn't the power consumed by the usb2serial chip (if you are using a board with such), e.g. going to deepsleep should get you to 0ma successfully
apart from this, i haven't played with this since then, so i am not sure how it behaves now
@vlast3k
I use ESP-12, so no external components like LED's.
USB to serial is exernal converter, and disconnecting does not make any difference.
Going to try deep sleep now ;-)
@DarkShadowNight , yeah, then what you are using is indeed the modem sleep.. i do not know why it is failing, but indeed it was quite tricky to get it run
@vlast3k
Deep sleep is working with 230 µA
I need the light sleep for my application :-(
Can you provide me your complete working and tested code?
@vlast3k
I did it!!!
wifi_fpm_set_sleep_type instead of wifi_set_sleep_type
aahh great :) maybe something changed, anyway - good to know how it works
now :)
On Mon, Jun 5, 2017 at 12:50 PM, DarkShadowNight notifications@github.com
wrote:
@vlast3k https://github.com/vlast3k
I did it!!!wifi_fpm_set_sleep_type instead of wifi_set_sleep_type
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/esp8266/Arduino/issues/1381#issuecomment-306148641,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAeDp4-YZudU7v-P71iosj1fyS1y2NMFks5sA89ggaJpZM4HAMqu
.
i've made some test, without luck ...
if i use wifi_fpm_do_sleep(0xFFFFFFF) , all is ok i can wake up with a gpio , but if i change the value from 0xFFFFFFFF to whatever i use , i cant reach sleep status ....
is even possible to reach the sleep status and wake up it or with a gpio or with the time?
what i will do , is put it in light sleep , and wake it
@davidea72
confirmed again. only 0XFFFFFFF work for light-sleep esp8266 arduino core ver 2.3.0
others just went into modem sleep ~14mA
that means the "automatic" light sleep , not the forced one.
2017-09-05 13:56 GMT+08:00 Eric Middleton notifications@github.com:
In the ESP8266 datasheets, they explain that light sleep mode will
maintain a connection to the AP. I can't get that to work, and it doesn't
look like anyone in this thread has posted a way to get this to work. Has
anyone been able to get this to work properly?—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/esp8266/Arduino/issues/1381#issuecomment-327078417,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AeJ7oQ_e3Hw0CRwJvUMKN8lEv5Lno95Pks5sfOJ3gaJpZM4HAMqu
.
--
Yours sincerely,
Bertrand Lo
@igrr from looking at the current code base, I see that there is a way to set the sleep mode to light-sleep, but from reading the Espressif docs, I suspect that means "automatic sleep". When doing a forced sleep, the current code forces modem-sleep.
Does the code propsed in this discussion make sense?
Hey @mikeyoyoyo and @torntrousers it's been nearly a year since I last posted but I'm hoping you guys are able to help me out with a similar issue. So my project is going on like 10 months and working perfectly. Much thanks to the many contributors to this thread! But now I want to make some hardware adjustments and wake up my ESP from light sleep using a alarm-based interrupt generated from a DS3231 real time clock. When the alarm is asserted, its active-low SQW/INT pin is supposed to produce a logic 0 pulse. So what that means for this thread is that I need to go from using gpio_pin_wakeup_enable(GPIO_ID_PIN(12), GPIO_PIN_INTR_HILEVEL); to gpio_pin_wakeup_enable(GPIO_ID_PIN(12), GPIO_PIN_INTR_LOLEVEL);. The thing is, the LOLEVEL just isn't working. The ESP goes to sleep but never wakes up. It seems like you guys have had success using LOLEVEL and getting the ESP to wake up. Are you using pullup resistors? If so what value? And what is triggering the pulse? External hardware or some software based event? I'd appreciate your input!
Hi @davesherler, I'll be honest I haven't used it in a while. When I was I
only ever tested with a switch and a pull up/pull down resistor. Probably
used 5k of 10k, doesn't really matter.
Were you able to verify the low pulse?
On 27 Oct. 2017 12:51 am, "davescherler" notifications@github.com wrote:
Hey @mikeyoyoyo https://github.com/mikeyoyoyo and @torntrousers
https://github.com/torntrousers it's been nearly a year since I last
posted but I'm hoping you guys are able to help me out with a similar
issue. So my project is going on like 10 months and working perfectly. Much
thanks to the many contributors to this thread! But now I want to make some
hardware adjustments and wake up my ESP from light sleep using a
alarm-based interrupt generated from a DS3231 real time clock. When the
alarm is asserted, its active-low SQW/INT pin is supposed to produce a
logic 0 pulse. So what that means for this thread is that I need to go from
using gpio_pin_wakeup_enable(GPIO_ID_PIN(12), GPIO_PIN_INTR_HILEVEL); to
gpio_pin_wakeup_enable(GPIO_ID_PIN(12), GPIO_PIN_INTR_LOLEVEL);. The thing
is, the LOLEVEL just isn't working. The ESP goes to sleep but never wakes
up. It seems like you guys have had success using LOLEVEL and getting the
ESP to wake up. Are you using pullup resistors? If so what value? And what
is triggering the pulse? External hardware or some software based event?
I'd appreciate your input!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/esp8266/Arduino/issues/1381#issuecomment-339672489,
or mute
the thread
https://github.com/notifications/unsubscribe-auth/ALPNydXw9DFC2AK8PiuaR-cRT3oS3Pdpks5swI5pgaJpZM4HAMqu
.
Hey @mikeyoyoyo thanks for the reply. That helps. I was able to confirm the low pulse. But unfortunately, I also confirmed that what I've been working on is programmatically impossible - at least with my current skills and knowledge. I've been trying to wake up my ESP using the alarm function of my RTC, since the RTC can be configured to output a low pulse when the alarm is asserted. The thing is, you have to clear the alarm register every time its asserted or else the RTC constantly outputs a low pulse, i.e. there's no momentary "pulse". So once my ESP goes to sleep, the pin thats monitoring for the low pulse goes low but just stays low because I can't clear the alarm flag. I'm glad I at least understand my problem now but bummed cause I'm sort of back at square one. Anyway, I appreciate you following up.
Add a "one shot ic" in series with the RTC output (and a couple of inverters)
If you only want a low pulse, add a capacitor coupling (or another one shot)
Of course these will use more power :-(
the LTC6993 uses 70uA
I managed to get some timed light-sleep code working... its not pretty but it works, tested with 2.4.0
Apart from GPIO waking, 2.4.1 and 2.4.2 has issues with light sleep.
Use 2.4.0 and WiFi.setSleepMode(WIFI_LIGHT_SLEEP); command.
When you issue delay(); you will see your device enter LIGHT_SLEEP.
But you also need to adjust your router's DTIM. Extended explanation is here:
https://github.com/esp8266/Arduino/issues/4485#issuecomment-427395160
Light sleep is now reported to work correctly with #5210 . In addition, you can set DTIM if desired, but that could miss broadcasts. See Espressif docs quoted in the comments in the PR for details.
long time no see this issue. Thanks for the work.
Hey Mike - thanks for the reply. I have good news! On a whim, I decided to use some of Simonliu009 callback code and everything seems to be working as I expected. I think what I wasn't putting together is that I needed to declare
wifi_fpm_set_wakeup_cb(some_wakeup_function);before I calledwifi_fpm_do_sleep(0xFFFFFFF);so that it knows what to do when the interrupt registers on the Pin. Now that I type that out it's like, duh, but I guess I had a hard time making sense of the comments in the gpio header file. Anyway, I wanted to share my successful code since I'm able to put the ESP to sleep, and wake it up using a PIR sensor, without having to pull any gpio's up or down, or have RST connected to 16 or EN. So a pretty simple hardware solution to use as a starting place for others. Thanks to everyone for helpful thread! I learned a lot.#include <ESP8266WiFi.h extern "C" { #include "gpio.h" } extern "C" { #include "user_interface.h" } const char* ssid = "myNetwork"; const char* password = "myPassword"; WiFiClient client; void setup() { Serial.begin(115200); Serial.print("initializing GPIOs"); gpio_init(); pinMode(0, INPUT); // this pin is connected to the PIR sensor. WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); delay(1000); } void loop() { Serial.println("Ready to go into light sleep..."); delay(1000); Serial.println("3..."); delay(1000); Serial.println("2..."); delay(1000); Serial.println("1..."); sleepNow(); } void sleepNow() { Serial.println("going to light sleep..."); wifi_station_disconnect(); wifi_set_opmode(NULL_MODE); wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); //light sleep mode gpio_pin_wakeup_enable(GPIO_ID_PIN(0), GPIO_PIN_INTR_HILEVEL); //set the interrupt to look for HIGH pulses on Pin 0 (the PIR). wifi_fpm_open(); delay(100); wifi_fpm_set_wakeup_cb(wakeupFromMotion); //wakeup callback wifi_fpm_do_sleep(0xFFFFFFF); delay(100); } void wakeupFromMotion(void) { wifi_fpm_close; wifi_set_opmode(STATION_MODE); wifi_station_connect(); Serial.println("Woke up from sleep"); }
Hi, sorry any idea about why only woke up one time? I've tried to copy parts from the setup to "initialize again", but it keeps just working one time (wake up) , I'm using a cable in (D5-14) to switch G - V, not a button, do you think that can be the problem?
Most helpful comment
Hey Mike - thanks for the reply. I have good news! On a whim, I decided to use some of Simonliu009 callback code and everything seems to be working as I expected. I think what I wasn't putting together is that I needed to declare
wifi_fpm_set_wakeup_cb(some_wakeup_function);before I calledwifi_fpm_do_sleep(0xFFFFFFF);so that it knows what to do when the interrupt registers on the Pin. Now that I type that out it's like, duh, but I guess I had a hard time making sense of the comments in the gpio header file. Anyway, I wanted to share my successful code since I'm able to put the ESP to sleep, and wake it up using a PIR sensor, without having to pull any gpio's up or down, or have RST connected to 16 or EN. So a pretty simple hardware solution to use as a starting place for others. Thanks to everyone for helpful thread! I learned a lot.