-
Notifications
You must be signed in to change notification settings - Fork 13.3k
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
[BREAKING] Disable WiFi at boot by default #7902
Conversation
@d-a-v Can you please clarify, whether |
|
AP mode with or without STA properly wakes WiFi up too. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks good to me now, but I really think this needs an entry in the docs somewhere.
A fix is needed about the xref from the faq (I'm playing a local sphinx build to Edit: entry point to the doc changes: last entry in this link |
@d-a-v Could you please correct the opening comments to this PR, it appears that now it's
:-) |
Starting from version 3 of this core, **persistence is disabled by default | ||
and WiFi does not anymore automatically fires up at boot** (see PR `#7902 <https://github.com/esp8266/Arduino/pull/7902>`__). | ||
|
||
Previously, SDK was automatically starting WiFi at boot. This was probably |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest highlighting here that the prior to v3 persistent was defaulted to true, and so the wifi creds were always stored to flash when the WiFi was configured, which could lead to a reduced life of the wifi config flash sector, and hence the entire ESP. Starting with v3, persistent defaults to false, so creds aren't stored by the SDK in the flash sector and hence don't survive across reboots.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@devyte I think this is not precisely correct. Settings that were once persisted, remain that way, so thereafter, WiFi.begin()
, with no WiFi.persistent(true)
in the sketch, as long as enableWiFiAtBootTime()
is somewhere in the sketch, will suffice to auto-connect to the AP.
doc/esp8266wifi/generic-class.rst
Outdated
enable radio as usual. It also smooths current spikes at boot and decreases | ||
DHCP stress. | ||
|
||
Legacy behavior can be restored by calling ``enableWiFiAtBoot()`` from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To restore legacy behavior, in addition to calling enableWiFiAtBoot() the user has to call WiFi.persitent(true). This should be used with care, because use could lead to early wear of the wifi config flash sector and hence device failure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment about, WiFi.persistent(true)
is only needed to change the flash credentials cache, not in a sketch that just wants to use whatever was persisted at any time prior to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the user has to call WiFi.persitent(true).
True !
I will add it in enableWiFiAtBootTime()
(edit: added)
could lead to early wear of the wifi config flash sector
Given the fact that when persistence is enabled, user config is compared to stored config, I think that's OK.
What do you both think ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I always thought this mode was very important !!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the wifi is active there is a consumption of energy that it would be good to keep in case of not use, especially if you use batteries for their power supply. In case of sending data, as sometimes I do, it is good to write to the internal memory and then make only one connection per day and send all the data recorded in the preset intervals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Bighoneypot The two WiFi / low power examples should work as before:
https://github.com/esp8266/Arduino/tree/master/libraries/esp8266/examples/LowPowerDemo
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiShutdown/WiFiShutdown.ino
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also good to test with a number of different ESP modules (ESP12E/F/S for example) to see if this also has an effect on deep sleep power consumption.
There have been a number of reports on deep sleep power consumption not being close to 60 uA on some nodes, with some reporting success with the most unclear assembly blobs possible and others claiming you need to do a short deep sleep first and then again call deep sleep to get true low power deep sleep and others reporting the WiFi will not start after deep sleep until you go into deep sleep again.
So I would not be surprised to see such topics pop up again if this is changed. (or this may be the final fix for it.... who knows ;) )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you need deep sleep and low power, you need to set up a series of special things, such as early wifi init, persistent wifi creds, static IP, etc, and then your app will usually have something in setup() and an empty loop. Then you need to check power and optimize more. That's an entirely different and very specific use case compared to the basic "start wifi, connect to some router, wiggle some pins" sketch that newer users usually start with.
In other words, deep sleep needs a special kind of sketch unlike the typical Arduino style setup - loop case addressed by this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Bighoneypot The two WiFi / low power examples should work as before:
https://github.com/esp8266/Arduino/tree/master/libraries/esp8266/examples/LowPowerDemo
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiShutdown/WiFiShutdown.ino
Thanks i watch this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also good to test with a number of different ESP modules (ESP12E/F/S for example) to see if this also has an effect on deep sleep power consumption.
There have been a number of reports on deep sleep power consumption not being close to 60 uA on some nodes, with some reporting success with the most unclear assembly blobs possible and others claiming you need to do a short deep sleep first and then again call deep sleep to get true low power deep sleep and others reporting the WiFi will not start after deep sleep until you go into deep sleep again.So I would not be surprised to see such topics pop up again if this is changed. (or this may be the final fix for it.... who knows ;) )
I didn't measure any difference in the Deep Sleep current. I looked at startup current and different types of Sleep. The only expected difference with other boards/modules would be due to extra chips on the boards (LDO, USB chip, battery charger, etc.), You can get several uA of difference if your GPIO outputs go the opposite direction from the pullup/pulldown resistors on those pins, ~2uA per pin in that case or 6-8uA higher total, but you pretty much have to have the pullup/pulldown resistors either on the module or in your circuit or it won't boot to Flash. The only time I've seen people reporting WAY high Deep Sleep numbers was 'cos they had a power LED on their board. Oops. Yeah, that's your circuit, not the ESP's Deep Sleep you're seeing.
The people that needed to reset across Deep Sleep a second time to re-enable WiFi after ESP.deepSleep(uS, WAKE_RF_DISABLED) have a fix here. The only wart is that it ALWAYS does a full RF_CAL when you wake the modem that way. I guess it blanks out the stored values for the modem parameters when you do WAKE_RF_DISABLED, so it has to rebuild everything from scratch when it brings the modem up next.
As far as variable current during Deep Sleep, I've never seen it mentioned. Most likely they weren't in Deep Sleep, for whatever reason. The SDK stops WiFi and all timers before entering Sleep, and once it's asleep the CPU PLL screeches to a complete halt and the power drops to around 20uA, which is solely the RTC timer running. I get closer to 16uA since I'm frequently running at 3.0V instead of 3.3V. If someone has an MCVE that demonstrates variable Deep Sleep currents I can figure out what's going on. I have a decent set of tools built or bought now.
I have seen numerous threads about Deep Sleep Zombie mode where it never wakes properly, but the jury is still out on the actual cause(s). I vote for cheap Chinese Flash that doesn't always come up in full drive mode after the Flash has been slept prior to Deep Sleep, but Erriez thinks it's the NodeMCU reset circuit interfering. We could both be right: two different causes or more. Until I get one here I can dissect, my tools are useless at troubleshooting across the Internet.
@@ -419,7 +419,7 @@ bool ESP8266WiFiGenericClass::mode(WiFiMode_t m, WiFiState* state) { | |||
} | |||
|
|||
if (wifi_fpm_get_sleep_type() != NONE_SLEEP_T) { | |||
// wifi may have been put asleep by ESP8266WiFiGenericClass::preinitWiFiOff | |||
// wifi starts asleep by default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at esp32's ::mode:
https://github.com/espressif/arduino-esp32/blob/46d5afb17fb91965632dc5fef237117e1fe947fc/libraries/WiFi/src/WiFiGeneric.cpp#L532-L542
Should this be more in-line with that?
i.e.
- remove this forced modem up, it happens even if we don't change the mode
- getMode() checks for fpm -> returns null-mode when sleeping
- mode() consecutively turns off the wifi when WIFI_OFF without an additional call to force sleep and turns it back on as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 thanks !
I added 1) and 3).
I'm reticent about 2) because WiFi.mode(WIFI_OFF)
will not put the modem to sleep, or puting modem to sleep does not necessarily switches the mode to WIFI_OFF
. 2) should come with that no ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant exactly that, to do forcesleep with WiFi.mode(WIFI_OFF) and resume with any real mode.
Not noticed the special shutdown and resume modes though, I wonder if those should be separate methods instead and not a 'mode'?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are indeed "fake" modes and described as such somewhere. There are two examples making use of them.
They are designed to import the deep sleep procedure into the core and allow users to not use random fw-snippets to put the chip to sleep (and wake-up fast)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aaah, both are already implemented as methods. So examples could use those directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for adding documentation and comments. I made 2 suggested edits to the wording, up to you if you want to adjust or not.
@@ -432,6 +426,12 @@ bool ESP8266WiFiGenericClass::mode(WiFiMode_t m, WiFiState* state) { | |||
return true; | |||
} | |||
|
|||
if (m != WIFI_OFF && wifi_fpm_get_sleep_type() != NONE_SLEEP_T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small side note / question, will test some time later today
wifi_fpm_get_sleep_type() is MODEM_SLEEP_T by default (in the previous version, or when wifi-off preinit is disabled by user currently) since this is a setting, not the actual mode that is active. is it ok do wakeup & close without fpm active?
SDK automatically starts WiFi at boot. This was probably intended for the Espressif AT FW that is interactive and preserves state accross reboots. This behavior is generally irrelevant with the Arduino API. Sketches usually start with
WiFi.begin()
or softAP...This PR will change the default: WiFi does not anymore automatically fires up at boot.
This will not change anything to standard sketches
Standard calls to
WiFi.mode()
+WiFi.begin/WiFi.softAP(...)
will continue to enable WiFi as usual.It may smooth current spikes at boot and also decrease DHCP stress.
Legacy behavior can be restored by calling
enableWiFiAtBootTime()
anywhere in the code (this is a weak void function intended to play with the linker). It may be necessary for WiFi Managers that rely on this SDK feature.This is a proposal as discussed on gitter, here and there, and with maintainers.
Fixes #7303