Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WiFi dropouts unless using WiFi.setSleepMode(WIFI_NONE_SLEEP) #5998

Closed
CRCinAU opened this issue Apr 18, 2019 · 54 comments · Fixed by #6889
Closed

WiFi dropouts unless using WiFi.setSleepMode(WIFI_NONE_SLEEP) #5998

CRCinAU opened this issue Apr 18, 2019 · 54 comments · Fixed by #6889

Comments

@CRCinAU
Copy link

CRCinAU commented Apr 18, 2019

I've noticed lately that multiple devices I have have started dropping off WiFi and reconnecting (causing MQTT dropouts etc) unless I specify WiFi.setSleepMode(WIFI_NONE_SLEEP) when setting up the WiFi adapter.

ESP.getFullVersion() output:

SDK:3.0.0-dev(c0f7b44)/Core:2.5.0=20500000/lwIP:STABLE-2_1_2_RELEASE/glue:1.1/BearSSL:6778687

WiFi setup code in setup():

mConnectHandler = WiFi.onStationModeConnected(onConnected);
mDisConnectHandler = WiFi.onStationModeDisconnected(onDisconnect);
mGotIpHandler = WiFi.onStationModeGotIP(onGotIP);

WiFi.disconnect() ;
WiFi.persistent(false);
WiFi.setSleepMode(WIFI_NONE_SLEEP);
WiFi.mode(WIFI_STA);            // Client mode
WiFi.setOutputPower(17);        // 10dBm == 10mW, 14dBm = 25mW, 17dBm = 50mW, 20dBm = 100mW
WiFi.begin(ssid, password);     // Start WiFi.

And the functions:

void onConnected(const WiFiEventStationModeConnected& event){
update_status += millis();
update_status += ": Connected to AP.";
update_status += "\n";
}
void onDisconnect(const WiFiEventStationModeDisconnected& event){
update_status += millis();
update_status += ": Station disconnected";
update_status += "\n";
client.disconnect();
}
void onGotIP(const WiFiEventStationModeGotIP& event){
update_status += millis();
update_status += ": Station connected, IP: ";
update_status += WiFi.localIP().toString();
update_status += "\n";
timer.setTimeout(1000, checkForUpdate);
}

update_status is a global string that is included on the web page interface.

If I comment out the setSleepMode line, I get regular wifi disconnections.

@CRCinAU
Copy link
Author

CRCinAU commented Apr 18, 2019

Issue moved across from platformio/platform-espressif8266#135

@d-a-v
Copy link
Collaborator

d-a-v commented Apr 18, 2019

Can you try that and report back wether it is sufficient without WiFi.setSleepMode(WIFI_NONE_SLEEP) (regarding power consumption) ?
#2330 (comment)

@CRCinAU
Copy link
Author

CRCinAU commented Apr 21, 2019

I've implemented this as a SimpleTimer via:

void GratuitousARPTask() {
        netif *n = netif_list;

        while (n) {
                etharp_gratuitous(n);
                n = n->next;
        }
}

SimpleTimer then triggers every ~5000ms for that task.

I can see the following on the network via tcpdump:

03:21:22.728282 ARP, Request who-has 10.1.1.11 tell 10.1.1.11, length 46
03:21:27.704425 ARP, Request who-has 10.1.1.11 tell 10.1.1.11, length 46
03:21:32.699405 ARP, Request who-has 10.1.1.11 tell 10.1.1.11, length 46
03:21:37.726173 ARP, Request who-has 10.1.1.11 tell 10.1.1.11, length 46
03:21:42.708973 ARP, Request who-has 10.1.1.11 tell 10.1.1.11, length 46
03:21:47.688705 ARP, Request who-has 10.1.1.11 tell 10.1.1.11, length 46
03:21:52.726033 ARP, Request who-has 10.1.1.11 tell 10.1.1.11, length 46

I've also disabled the WiFi.setSleepMode(WIFI_NONE_SLEEP);, so we'll see what happens.

@CRCinAU
Copy link
Author

CRCinAU commented Apr 23, 2019

Setting WIFI_LIGHT_SLEEP and sending GARP's - and it doesn't seem to fix the issue. I don't have any of the ESP8266 units with over an hour uptime according to the AP.

I even tried setting one to 802.11g mode, no real difference.

@d-a-v
Copy link
Collaborator

d-a-v commented Apr 23, 2019

Have you tried with latest git which uses a more stable espressif firmware ?

@CRCinAU
Copy link
Author

CRCinAU commented Apr 26, 2019

Embarrassingly, I can't quite remember what to feed into PlatformIO to try this.

Currently, I have the following in platformio.ini:

platform = espressif8266
;platform = https://github.com/platformio/platform-espressif8266.git
;platform = https://github.com/platformio/platform-espressif8266.git#feature/stage

I'm pretty sure none of these are directly from this repo. I'm pretty sure I've done this before - but I can't find my notes that mention it. Any hints on being able to get this to reflect here instead?

@Jason2866
Copy link
Contributor

This entry use latest ESP8266 dev version: platform = https://github.com/platformio/platform-espressif8266.git#feature/stage

@CRCinAU
Copy link
Author

CRCinAU commented Apr 28, 2019

This entry use latest ESP8266 dev version: platform = https://github.com/platformio/platform-espressif8266.git#feature/stage

That doesn't map up with whats in this repo though....

From https://github.com/platformio/platform-espressif8266/tree/feature/stage (in your browser):
Latest commit 645d2d9 14 days ago

The commit list here has:
Latest commit cdb5495 2 days ago

I'm not sure the two compare...

@Jason2866
Copy link
Contributor

You have to force platformio to update!

@CRCinAU
Copy link
Author

CRCinAU commented Apr 28, 2019

Ah! That's what I was missing....

Platform Espressif 8266 (Stage)
--------
Updating espressif8266                   @ 645d2d9        [Up-to-date]
Updating framework-arduinoespressif8266  @ cdb5495        [Up-to-date]
Updating tool-esptool                    @ 1.413.0        [Up-to-date]
Updating toolchain-xtensa                @ 1.40802.0      [Up-to-date]

Let me start testing again.

@CRCinAU
Copy link
Author

CRCinAU commented Apr 28, 2019

Woah, this seems to lead to hard hangs if I set WiFi.setSleepMode(WIFI_LIGHT_SLEEP);

I hit the reset button to bring it back to life after each of the disconnection timeouts below. Setting WiFi.setSleepMode(WIFI_NONE_SLEEP); seems to restore functionality with no hangs.

Version string is now:

SDK:2.2.1(cfd48f3)/Core:2.6.0-dev=20600000/lwIP:STABLE-2_1_2_RELEASE/glue:1.1-7-g82abda3/BearSSL:a143020

MQTT logs for timing:

Apr 28 23:11:33 mosquitto[538]: 1556457093: New connection from 10.1.1.11 on port 1883.
Apr 28 23:11:33 mosquitto[538]: 1556457093: New client connected from 10.1.1.11 as 84:F3:EB:10:75:2C (c1, k15).                                                                                                                
Apr 28 23:12:08 mosquitto[538]: 1556457128: Client 84:F3:EB:10:75:2C has exceeded timeout, disconnecting.                                                                                                                      
Apr 28 23:12:08 mosquitto[538]: 1556457128: Socket error on client 84:F3:EB:10:75:2C, disconnecting.
Apr 28 23:13:28 mosquitto[538]: 1556457208: New connection from 10.1.1.11 on port 1883.
Apr 28 23:13:28 mosquitto[538]: 1556457208: New client connected from 10.1.1.11 as 84:F3:EB:10:75:2C (c1, k15).                                                                                                                
Apr 28 23:13:52 mosquitto[538]: 1556457232: Client 84:F3:EB:10:75:2C has exceeded timeout, disconnecting.                                                                                                                      
Apr 28 23:13:52 mosquitto[538]: 1556457232: Socket error on client 84:F3:EB:10:75:2C, disconnecting.

@TD-er
Copy link
Contributor

TD-er commented Apr 30, 2019

Make sure you do a clean build and build again after updating the core library, when using PlatformIO.
Most of the time it works just fine, but I know from experience that it may cost a lot of hours debugging to find not reproducible error reports, which seem to be fixed after a clean build.

Apart from that, I've seen similar issues.
Gratuitous ARP does seem to help a bit, but it isn't the fix for all.

What I'm seeing is that the node does reduce power somehow (you can measure its power consumption) and then starts to miss packets until it receives some ping requests (or other repeated network requests)
To answer these requests, the current usage increases for a while and all requests are answered well.

Even when setting the wifi to none sleep, the power consumption may drop after a while and then it starts to miss packets.
Strange thing is, it will never miss ICMP packets. It may take up-to a few-100 msec to reply the first one, but all ping packets will get a reply.

Now the really strange part....
Some builds run fine for weeks and some can hardly stay up for a few hours to days.
So it somewhat looks to me like some uninitialized variable or some array being addressed out of bound, or an alignment issue. Behavior of these can all be different by some changes in totally unrelated code.

@lp422003
Copy link

lp422003 commented May 8, 2019

When do you call the function Gratuitous ARP, during the loop correct?

@arihantdaga
Copy link

@TD-er How can we use Gratuitous ARP. Is there any temporay solution to this problem. I went through few threads related to this on this repo as well as EspEasy's repo, i saw that you have worked on it a lot. Did you find some temporary or permanent solution to this problem ?

@TD-er
Copy link
Contributor

TD-er commented Aug 23, 2019

I do send Gratuitous ARP packets when just connected and when I encounter failed connect attempts (also DNS lookup)
And also periodically I do send them, when it is enabled in the settings.

Another approach can be to send ping packets to the node, since ICMP packets are somehow treated differently. Not sure if it is only on the ESP, or also in the AP what makes it act different.
You can see its power consumption remain constant (high) when it is receiving pings, but also its reaction time improves and that must be something in the AP I guess.

I am not (yet) using it on the ESP32 and you can clearly see a difference in how well it does react on web requests or the UDP packets sent among ESPeasy nodes.
The ESP32 does only receive a handful of them and thus lists only a fraction of the ESPeasy nodes in the network. Some listed nodes have a "last seen" timestamp of 5 - 10 minutes, while each node does send its presence every minute.

@CRCinAU
Copy link
Author

CRCinAU commented Aug 23, 2019

I fixed it by doing:
WiFi.setSleepMode(WIFI_NONE_SLEEP);

Without that, it still seems to drop out. Of course, you need to be able to tolerate the extra power draw...

@TD-er
Copy link
Contributor

TD-er commented Aug 23, 2019

Not tested on ESP32, but on an ESP8266 I've notice this is no guarantee it will keep the wifi radio on.
I still noticed the power consumption to drop after some time (10+ minutes) and as soon as the power dropped, the packets were missing again.

There is something in the background messing with the power settings.

@arihantdaga
Copy link

@TD-er Thank you for this. I checked usage of sendGratuitousARP in espeasy repo. And i implemented the same in my code.

void sendGratuitousARP() {
  if (!wifiConnected()) {
    return;
  }
  unsigned long start = millis();
  netif *n = netif_list;
  while (n) {
    etharp_gratuitous(n);
    n = n->next;
  }
  DEBUG_MSG_P(PSTR("Sent Gratuitous ARP : Time Took - %d\n"), millis() - start);
}

And i am calling this function as soon as node connects to the wifi. And after that calling it every 5 seconds. However, there is something wrong with this. Device is crashing sometimes when calling this function right after getting connected with wifi. (I tried giving a delay of 100ms also, not helping). I am using Lwip 2 higher bandwidth version.
Are we not supposed to call this right after connecting with WiFi.

This is my exception stack

Exception 0: Illegal instruction
PC: 0x2d2d2d2d
EXCVADDR: 0x00000000

Decoding stack results
0x40100c84: malloc(size_t) at /Users/arihantdaga/Documents/Arduino/hardware/esp8266com/esp8266/cores/esp8266/umm_malloc/umm_malloc.cpp line 1677
0x40237183: new_linkoutput at glue-lwip/lwip-git.c line 235
0x40237574: ethernet_output at netif/ethernet.c line 312
0x4023ec0f: etharp_raw at core/ipv4/etharp.c line 1161
0x4023ee0a: etharp_request at core/ipv4/etharp.c line 1202
0x402042f0: wifiConnected() at /Users/arihantdaga/Documents/Arduino/KIOT_NEW/ESP_FRAMEWORK/kiot/kiot/wifi.ino line 61
0x402046eb: sendGratuitousARP() at /Users/arihantdaga/Documents/Arduino/KIOT_NEW/ESP_FRAMEWORK/kiot/kiot/wifi.ino line 571
0x40205f4e: _wiFiStatusCallback(justwifi_messages_t, char*) at /Users/arihantdaga/Documents/Arduino/KIOT_NEW/ESP_FRAMEWORK/kiot/kiot/wifi.ino line 423
0x4022a666: std::_Function_handler ::_M_invoke(std::_Any_data const&, justwifi_messages_t, char*) at /Users/arihantdaga/Documents/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/xtensa-lx106-elf/include/c++/4.8.2/functional line 2073
0x40100522: millis() at /Users/arihantdaga/Documents/Arduino/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring.cpp line 186
0x402187a5: JustWifi::_doCallback(justwifi_messages_t, char*) at /Users/arihantdaga/Documents/Arduino/libraries/justwifi_ModifiedByArihant/src/JustWifi.cpp line 418
0x40214298: ESP8266WiFiSTAClass::setAutoConnect(bool) at /Users/arihantdaga/Documents/Arduino/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp line 413
0x402189b4: JustWifi::_connect(unsigned char) at /Users/arihantdaga/Documents/Arduino/libraries/justwifi_ModifiedByArihant/src/JustWifi.cpp line 111
0x4021901c: JustWifi::connected() at /Users/arihantdaga/Documents/Arduino/libraries/justwifi_ModifiedByArihant/src/JustWifi.cpp line 603
0x40201e55: loop() at /Users/arihantdaga/Documents/Arduino/KIOT_NEW/ESP_FRAMEWORK/kiot/kiot/kiot.ino line 139
0x402299de: uart_read(uart_t*, char*, size_t) at /Users/arihantdaga/Documents/Arduino/hardware/esp8266com/esp8266/cores/esp8266/uart.cpp line 274
0x402299d4: uart_read(uart_t*, char*, size_t) at /Users/arihantdaga/Documents/Arduino/hardware/esp8266com/esp8266/cores/esp8266/uart.cpp line 249
0x40218d44: JustWifi::_startSTA(bool) at /Users/arihantdaga/Documents/Arduino/libraries/justwifi_ModifiedByArihant/src/JustWifi.cpp line 359
0x402190b1: JustWifi::loop() at /Users/arihantdaga/Documents/Arduino/libraries/justwifi_ModifiedByArihant/src/JustWifi.cpp line 657
0x40100522: millis() at /Users/arihantdaga/Documents/Arduino/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_wiring.cpp line 186
0x4020471f: wifiLoop() at /Users/arihantdaga/Documents/Arduino/KIOT_NEW/ESP_FRAMEWORK/kiot/kiot/wifi.ino line 544
0x40201e58: loop() at /Users/arihantdaga/Documents/Arduino/KIOT_NEW/ESP_FRAMEWORK/kiot/kiot/kiot.ino line 138
0x40228a64: loop_wrapper() at /Users/arihantdaga/Documents/Arduino/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line 132

@TD-er
Copy link
Contributor

TD-er commented Aug 24, 2019

Yep, you have to wait a while after setup of the WiFi.
See also this issue: #6266
Currently I'm changing a lot in the ESPeasy code regarding WiFi, because a lot of checks and local patches crept in the code the past year to find the issues with the WiFi instability.

But in general, if you observe the rules I mention in the last post I linked, you should be fine.
Also add some delays after connecting.
In ESPeasy, the state of WiFi is followed by looking at the events.
If you don't want to do that, just make sure you have both a connection and an IP address before sending data.

@arihantdaga
Copy link

arihantdaga commented Aug 27, 2019

@TD-er I tried delay(200) also. And i am getting IP also, after that only i am starting sendGratuitousARP(). I checked the ESPEasy's code again after your recent updates.
This is triggering hardware watchdog reset.

void sendGratuitousARP() {
  if (!wifiConnected()) {
    return;
  }
  unsigned long start = millis();
  netif *n = netif_list;
  while (n) {
    etharp_gratuitous(n);
    n = n->next;
  }
  DEBUG_MSG_P(PSTR("Sent Gratuitous ARP : Time Took - %d\n"), millis() - start);
}
[011561] [WIFI] Connected Wifi 
[011561] [WIFI] MODE STA -------------------------------------
[011562] [WIFI] SSID D-Link_DIR-600M
[011562] [WIFI] IP   192.168.100.2
[011565] [WIFI] MAC  80:7D:3A:73:E1:F5
[011568] [WIFI] GW   192.168.100.1
[011571] [WIFI] DNS  192.168.100.1
[011574] [WIFI] MASK 255.255.255.0
[011577] [WIFI] HOST sw_1_rel_807d3a73e1f
[011581] [WIFI] ----------------------------------------------
[011687] Point 1 

---------------------------------->> This is where it it'll trigger Hardware Watchdog. << ----------------------------------


 ets Jan  8 2013,rst cause:4, boot mode:(3,6)

wdt reset
load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v0937b076
~ld


I have tried lwip 2 lower memory also, using latest esp core from github. But its same, now its triggering hardware watch dog. I am not sure if its working with ESPEasy. I'll try and verify that also today.

EDIT: Calling sendGratuitousARP() function is triggering wdt reset.

@TD-er
Copy link
Contributor

TD-er commented Aug 27, 2019

It would be great to know if you found what exactly triggers the WDT reboot.

What mode is active when you run the gratuitous ARP?
AP+STA or STA ?

How long is the delay between receiving the IP address and start sending the ARP requests?
What core version do you use?

@arihantdaga
Copy link

@TD-er node is in STA Mode. However the solution given by @mcspr seems to be working and not triggering any wdt reset if we check for netif flag up.

@Spackstor
Copy link

For what it is worth, I have been tinkering with the ESP8266 for years now, and drop out appears to be an ongoing issue.

I agree with TD-er, this (none_sleep) is no guarantee, and frequently advanced users refer to power issues. But I also agree with CRCinAU, that to date, for me, the WiFi.setSleepMode(WIFI_NONE_SLEEP); gives the most reliable/consistent connection.

I think for many less advanced hobbyists, this information is helpful.

If ever, anyone has an Arduino C++ WiFi set up for the ESP8266 that is drop out free, please share.

@devyte
Copy link
Collaborator

devyte commented Nov 2, 2019

@Spackstor My suspicion is that the dropouts were fixed by #6484. I've been running a whole bumch of modules for several weeks now on latest git after that fix without any dropouts, and I don't use sleep none.
Disclaimer: I don't use Wire or SPI or swserial etc. I use the async webserver, and OneWire, gpio, adc, mdns. I suspect a similar fix to #6484 is needed elsewhere, e. g. for SPI (there's an issue and incomplete pr about it).

@Spackstor
Copy link

I'll load the new libraries and see what happens. I'm an MQTT red-node/Raspberry fan. Adding ESP8266 reliability is a boon.

Thanks for the info.

@CRCinAU
Copy link
Author

CRCinAU commented Nov 3, 2019

I've set WiFi.setSleepMode(WIFI_LIGHT_SLEEP); on my of my ESP8266 kit for testing... Currently been connected to the AP for ~28 minutes and seems ok.

Will monitor further, but it'll be great if that fixes the issue. I've had to disable sleep in everything for so long....

@TD-er
Copy link
Contributor

TD-er commented Nov 3, 2019

Currently been connected to the AP for ~28 minutes and seems ok.

Just curious, what was your average connection lost interval with that setup before?

@d-a-v
Copy link
Collaborator

d-a-v commented Nov 7, 2019

What is ESP.getFullVersion() output ? @CRCinAU

@CRCinAU
Copy link
Author

CRCinAU commented Nov 7, 2019

SDK:2.2.1(cfd48f3)/Core:2.5.2=20502000/lwIP:STABLE-2_1_2_RELEASE/glue:1.1-7-g82abda3/BearSSL:a143020

@d-a-v
Copy link
Collaborator

d-a-v commented Nov 7, 2019

Are you able to try with git version ?

There's also an alpha release that I just updated

@CRCinAU
Copy link
Author

CRCinAU commented Nov 7, 2019

I'm using platformio, so I changed the platform to:

platform = https://github.com/platformio/platform-espressif8266.git#feature/stage

New ESP.getFullVersion() is as follows:

SDK:2.2.2-dev(38a443e)/Core:2.6.0-dev=20600000/lwIP:STABLE-2_1_2_RELEASE/glue:1.2-16-ge23a07e/BearSSL:89454af

I enabled LIGHT_SLEEP again as follows:

        //WiFi.setSleepMode(WIFI_NONE_SLEEP);
        WiFi.setSleepMode(WIFI_LIGHT_SLEEP);

Is that the correct version for what you're wanting?

@d-a-v
Copy link
Collaborator

d-a-v commented Nov 7, 2019

It is better, though not ideal, because either:

  • 20600000 is not precise enough (there should be the number of commits since 2.5.2 in the last three digits)
  • (or) there is no date for the last commit.

Do you have P-io instructions on how to update the stage source directory ?
Or can you check for the existence of this macro ETS_INTR_LOCK_NEST_MAX in tools/sdk/core_esp8266_main.cpp (that is to check if #6484 is here)

@CRCinAU
Copy link
Author

CRCinAU commented Nov 7, 2019

I've been using these docs:
https://docs.platformio.org/en/latest/platforms/espressif8266.html#stable-and-upstream-versions

My platformio.ini contains:

[env:esp01_1m]
board_build.f_cpu = 160000000L
;platform = espressif8266
;platform = https://github.com/platformio/platform-espressif8266.git
platform = https://github.com/platformio/platform-espressif8266.git#feature/stage
board = esp01_1m
framework = arduino
build_flags =
  -Wl,-Teagle.flash.1m.ld
  -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
  -DNDEBUG
$ grep ETS_INTR_LOCK_NEST_MAX ./packages/framework-arduinoespressif8266@src-31d658a59f41540201fc3726a1394910/cores/esp8266/core_esp8266_main.cpp
#define ETS_INTR_LOCK_NEST_MAX 7
static uint16_t ets_intr_lock_stack[ETS_INTR_LOCK_NEST_MAX];
  if (ets_intr_lock_stack_ptr < ETS_INTR_LOCK_NEST_MAX)

@d-a-v
Copy link
Collaborator

d-a-v commented Nov 7, 2019

Good! Try with it then

@CRCinAU
Copy link
Author

CRCinAU commented Nov 7, 2019

Ok - have flashed and connected back up... For my records, 23:57 was the reconnect time on the latest compile with the above settings. Will leave it run and check tomorrow so I'll have ~20 hours of data to see what the result is.

@liebman
Copy link
Contributor

liebman commented Nov 7, 2019

@CRCinAU I use this to set the git version:

platform_packages =
  ; use upstream Git version
  framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git

@CRCinAU
Copy link
Author

CRCinAU commented Nov 8, 2019

Given ~15h 45m of uptime, I can report the following:
image

From midnight onwards was with the git version as mentioned above. Still seems to disconnect from wifi over time.

EDIT: Just to explain the graph, the ~1px wide lines are MQTT reconnections - meaning the wifi connection dropped and restarted.

@CRCinAU
Copy link
Author

CRCinAU commented Nov 8, 2019

Full stats for a 24 hour period:
image

Have recompiled & flashed after setting WIFI_NONE_SLEEP. Will post stats to compare in ~24h.

@CRCinAU
Copy link
Author

CRCinAU commented Nov 9, 2019

Results of using WIFI_NONE_SLEEP after ~14 hours shows zero dropouts... Flashed at about 12:20am - solid connection ever since.

For some reason screenshot uploads are failing - will attach later.
https://imgur.com/U77G9xm

Am currently testing with WIFI_MODEM_SLEEP instead of NONE / LIGHT... Will report back later...

EDIT: I've been observing power draw on the D1 mini in different modes...
WIFI_NONE_SLEEP = ~50mA constant
WIFI_MODEM_SLEEP = Too low for my meter with peaks between 0.02-0.05A
WIFI_LIGHT_SLEEP = haven't tested yet.

@CRCinAU
Copy link
Author

CRCinAU commented Nov 10, 2019

After testing with WIFI_MODEM_SLEEP, I haven't had a single drop in 24h.
(For some reason, I can't add images into the comment still)
https://imgur.com/ggf7cbF

There's also a massive power saving using WIFI_MODEM_SLEEP instead of WIFI_NONE_SLEEP - so this may be a good workaround for the moment...

@TD-er
Copy link
Contributor

TD-er commented Nov 10, 2019

(For some reason, I can't add images into the comment still)

What I usually do is have the image (the pixels, not the file) in my clipboard and just paste it in the comment field.

About the sleep handling.
How do you set it to sleep and what do you do when waking the WiFi again?
Can you post a small piece of code to show this?

@Jason2866
Copy link
Contributor

Jason2866 commented Nov 10, 2019

@CRCinAU with which IDE do you compile? If you use PlatformIO you will have wifi disconnects because PlatformIO still uses Xtensa Build chain 2.4. which does not work reliable with latest Arduino Esp versions (wifi disconnects). You have to use build chain 2.5.0.4 which is standard in Arduino IDE.
This issue is already adressed to PlatformIO. The will update and release core 2.6.0 (soon?).

@CRCinAU
Copy link
Author

CRCinAU commented Nov 10, 2019

Yeah - I can't paste or attach a file - no idea why... Oh well...

WIFI_NONE_SLEEP / MODEM_SLEEP / LIGHT_SLEEP are all automatic. The only real action you need to do is turn it on when init'ing wifi. ie:

void setup() {
        WiFi.disconnect() ;
        WiFi.persistent(false);
        WiFi.mode(WIFI_STA);            // Client mode
        //WiFi.setSleepMode(WIFI_NONE_SLEEP);
        //WiFi.setSleepMode(WIFI_LIGHT_SLEEP);
        WiFi.setSleepMode(WIFI_MODEM_SLEEP);
        WiFi.setOutputPower(18);        // 10dBm == 10mW, 14dBm = 25mW, 17dBm = 50mW, 20dBm = 100mW
        WiFi.begin(ssid, password);     // Start WiFi.
}

@CRCinAU
Copy link
Author

CRCinAU commented Nov 10, 2019

@CRCinAU with which IDE do you compile? If you use PlatformIO you will have wifi disconnects because PlatformIO still uses Xtensa Build chain 2.4. which does not work reliable with latest Arduino Esp versions (wifi disconnects). You have to use build chain 2.5.0.4 which is standard in Arduino IDE.
This issue is already adressed to PlatformIO. The will update and release core 2.6.0 (soon?).

Current versioning in PIO:

Platform Manager
================
Platform Espressif 8266 (Stage)
--------
Updating espressif8266                   @ 3500fb2        [Up-to-date]
Updating toolchain-xtensa                @ 2.40802.190218 [Up-to-date]
Updating framework-arduinoespressif8266  @ 739bcd3        [Up-to-date]
Updating tool-esptool                    @ 1.413.0        [Up-to-date]
Updating tool-esptoolpy                  @ 1.20600.0      [Up-to-date]

I'm curious how the MODEM_SLEEP works fine, but LIGHT_SLEEP doesn't based on compiler?

@Jason2866
Copy link
Contributor

Jason2866 commented Nov 10, 2019

Old build channel, you will have always wifi disconnects.
You have to use Arduino-IDE until PlatformIO releases with actual xtensa build chain
Dont ask me why! In project Tasmota that is the (reproducable) experience we made.

@CRCinAU
Copy link
Author

CRCinAU commented Nov 10, 2019

Any chance you can link to the PIO issue # here?

EDIT: Ah, I think you're talking about this?
platformio/platform-espressif8266#167

EDIT2: Ok, I've downloaded 2.5.0-4 manually and set it up using the following script:

cd ~/.platformio/packages/
curl -sL https://github.com/earlephilhower/esp-quick-toolchain/releases/download/2.5.0-4/x86_64-linux-gnu.xtensa-lx106-elf-b40a506.1563313032.tar.gz | tar xvz
mv xtensa-lx106-elf toolchain-xtensa@2.5.0-4
cat <<EOF > toolchain-xtensa@3/package.json
{
    "name": "toolchain-xtensa",
    "system": [
        "linux_x86_64"
    ],
    "url": "https://github.com/earlephilhower/esp-quick-toolchain",
    "version": "2.5.0-4"
}
EOF

I then added platform_packages = toolchain-xtensa@2.5.0-4 to my projects platformio.ini file.

I built, then flashed - lets see what happens over time.

@CRCinAU
Copy link
Author

CRCinAU commented Nov 11, 2019

Building with Xtensa Build chain 2.5.0-4 makes no difference when using WIFI_LIGHT_SLEEP - I still see regular dropouts.

The best results seem to be with using WIFI_MODEM_SLEEP for power consumption. This option gives a rock solid connection with no dropouts and much lower power usage than WIFI_NONE_SLEEP.

dirkmueller added a commit to dirkmueller/sensors-software that referenced this issue Nov 14, 2019
Until we can update the Arduino core 2.6.0 (which is hopefully soon)
with the newer xtensa toolchain, it seems the best bet is to
reduce wifi sleeping. Also high transmit power can interfere with
the flash reading which can cause instability.

esp8266/Arduino#5998 (comment)
esp8266/Arduino#6471
@CRCinAU
Copy link
Author

CRCinAU commented Nov 25, 2019

I never really got back on this one - however using WIFI_MODEM_SLEEP is fine. WIFI_LIGHT_SLEEP is broken and continues to have dropouts. See below picture of using WIFI_MODEM_SLEEP.

image

Idle power draw shows on my meter as 0.01A - it doesn't have a higher resolution than that. As you can see, no dropouts.

@devyte
Copy link
Collaborator

devyte commented Feb 2, 2020

CC @Tech-TX do these dropouts make sense to you?

@Tech-TX
Copy link
Contributor

Tech-TX commented Feb 3, 2020

In WIFI_LIGHT_SLEEP (Automatic Light Sleep), yes. The CPU is usually asleep between TIM beacons, and might miss traffic unless it happens at the DTIM (listen) interval. In WIFI_MODEM_SLEEP (Automatic Modem Sleep), no, it shouldn't miss packets, as the CPU never sleeps. It only turns off the modem between TIM beacons if it can (if there's a delay() it can use). The receiver is still working, it's just the transmitter that it sleeps. If you don't do anything with the power modes, you get Automatic Modem Sleep. There should be no difference between WIFI_NONE_SLEEP and WIFI_MODEM_SLEEP (the default) on packet loss, only on power.

In that last capture (WIFI_LIGHT_SLEEP) I'm running DTIM = 3, so only one listen interval per 3 TIM beacons. There's a delay() loop hitting every 5.5 beacons that also wakes it up. Those two are the 'modem sleep' areas at 18mA where the CPU is fully awake. Any time it's near that bottom division, the CPU isn't responding, and can miss packets unless they happen at the DTIM interval when it's briefly awake. If you look closely, the area where I've marked LIGHT SLEEP there are 4 beacons without a Modem Sleep wake-up, so it would have lost a packet there if the AP was sending during a time it expected the STA to be awake. Espressif doesn't say anywhere that Light Sleep won't miss packets, and looking at that capture I see what looks like potential lost data. It's inside the blob, nothing we can do to fix it.

If you're in a network where you can't afford lost data, then WIFI_MODEM_SLEEP will save ~45mA worth of power if you spend a long time in delay() without data loss. If you can afford to lose packets then WIFI_LIGHT_SLEEP will save an additional ~10mA depending on traffic. In a high-traffic environment, neither of the automatic modes will save any power, as the SDK keeps the modem on almost continuously. It's only during low-traffic and delay() that it sleeps. In high traffic, it looks like WIFI_NONE_SLEEP.

WIFI_NONE_SLEEP
WIFI_NONE_SLEEP

WIFI_MODEM_SLEEP
WIFI_MODEM_SLEEP

WIFI_LIGHT_SLEEP
WIFI_LIGHT_SLEEP

@devyte
Copy link
Collaborator

devyte commented Feb 3, 2020

Closing per previous comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants