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

Turn Wifi on/off #644

Closed
raimohanska opened this issue Aug 2, 2015 · 30 comments
Closed

Turn Wifi on/off #644

raimohanska opened this issue Aug 2, 2015 · 30 comments

Comments

@raimohanska
Copy link
Contributor

raimohanska commented Aug 2, 2015

Is there an API for turning the WiFI off when it's not needed, to save power?

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@craigk46
Copy link

craigk46 commented Aug 2, 2015

You can put this line at the end of your Arduino sketch to go to sleep for some number of microseconds. In this case 25 seconds total. The way it wakes from sleep is to have a gpio output pin pulse the reset pin of your module. On the Adafruit ESP8266 Huzzah module you would tie gpio16 to rst so it can wake from sleep. Realize this means a total reset so your module will run from powerup reset every time. The nice thing is the module draws something measured in microamps while sleeping.

Another good reference for understanding this mode is here: https://www.sparkfun.com/news/1842

Below is the line of code that would work at the end of your Arduino sketch to have the module sleep for 25 seconds and wake from a cold reset if you tie the correct pin for your hardware to the RST input.

ESP.deepSleep(25000000, WAKE_RF_DEFAULT);

@raimohanska
Copy link
Contributor Author

Thanks! I'm aware of the deep sleep feature though. I was just wondering if you could just turn off Wifi and have the processor run otherwise normally.

@craigk46
Copy link

craigk46 commented Aug 2, 2015

I don't know. I'm still learning about the ESP8266 myself.

@torntrousers
Copy link
Contributor

There is a thing called modem sleep metioned in the sdk doc which does what you want. The only way i've found to enable it though is by doing a deep sleep, eg ESP.deepSleep(1, WAKE_RF_DISABLED), and to re-enable wifi do another ESP.deepSleep(1, WAKE_RF_DEFAULT). So not terrible convenient and if you need to keep track of the wifi state you need to store it in something like RTC memory. I see about 14 milliamps when running with wifi disabled compared with about 70 ma when its enabled but not sending much.

@raimohanska
Copy link
Contributor Author

Thanks @torntrousers, this is how it seems to me too. Just doesn't make sense that the only way to turn wifi on/off would be to go to deep sleep: ) Could this be something that the chip supports but is just missing from the Arduino API?

@Links2004
Copy link
Collaborator

to disable WiFi use this:

WiFi.mode(WIFI_OFF);

but i not now how many mA its save, would be interesting to know.

@raimohanska
Copy link
Contributor Author

@Links2004 yes there seems to be such an option, thanks! I made a Pull Request (#646) for including it in the docs. I didn't make power consumption measurements (yet) to see if it has any effect.

However, after doing ESP.deepSleep(1000000, WAKE_RF_DISABLED) the chip boots with Wifi disabled and calling WiFi.mode(WIFI_AP_STA) doesn't fix it. Resetting the chip after that will fix it though. But anyway, it doesn't seem possible to enable/disable WiFi on the fly.

@torntrousers
Copy link
Contributor

I hadn't heard of WiFi.mode(WIFI_OFF) either. Gave it a try measuring the change in current but i still get about 70milliamps after WiFi.mode(WIFI_OFF) whereas ESP.deepSleep(1, WAKE_RF_DISABLED) gives about 14milliamps on the wakeup, so it seems like WIFI_OFF does not completly switch off the wifi radio.

@whogarden
Copy link

Hi,
Here is doc about WiFi.mode(WIFI_OFF) : http://esp8266.github.io/Arduino/versions/2.0.0/doc/libraries.html
But it is not working, and In a line in some sketch if you put : WiFi.mode(WIFI_OFF);
WIFI_OFF is not recognized and stays in black color.
wifimode

@Links2004
Copy link
Collaborator

it will work.
the colore stuf comes from the IDE and the Arduino IDE is not intelligent when it comes to this.
add it to the keywords.txt
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/keywords.txt#L68
and it will be colored.
a good IDE do this by itself, for arduino IDE its a manually process....

eclipse (no need for keywords.txt)
image

for more power saving use:

WiFi.forceSleepBegin();

(only work in git or staring)

@whogarden
Copy link

Yes it works,
Thanks a lot.

@hallard
Copy link
Contributor

hallard commented Jan 26, 2016

Guys
I'm enabling WiFi for 5 minutes to be able to set configuration of device, then I turn it off using

WiFi.mode(WIFI_OFF);

But it stop ESP from running and without any manual reset, my sketch is blocked. Looking inside WiFi code, WiFi.mode call SDK wifi_set_op_mode()

void ESP8266WiFiClass::_mode(WiFiMode m)
{
    if(wifi_get_opmode() == (uint8)m) {
        return;
    }

    ETS_UART_INTR_DISABLE();
    if (_persistent)
        wifi_set_opmode(m);
    else
        wifi_set_opmode_current(m);
    ETS_UART_INTR_ENABLE();

}

and SDK 1.5.1 of 2016 page 49 on wifi_set_opmode does absolutely not mention this mode off (0)

Parameters:
uint8 opmode: WiFi operating modes:
 0x01: station mode
 0x02: soft-AP mode
 0x03: station+soft-AP

Maybe calling this on setup() (before Wifi connect) works but in my case it doesn't
Here my code (in loop())

    // Time to Stop Wifi ?
    if (seconds >= MAX_WIFI_SEC ) {
      if (!(config.config & CFG_WIFI)) {
        DebugF(" Stopping Wifi ");
        webSocket.disconnect();
        yield();
        server.close();
        yield();
        WiFi.mode(WIFI_OFF);
        yield();
      }
    }


    DebuglnF("OK!");
    Debugflush();

and serial when it happens

task_1_sec... Stopping Wifi $T07#bb

Then need to push reset on ESP, you can see "OK!" string does not appears

Something I missed or I'm doing wrong ?

@igrr
Copy link
Member

igrr commented Jan 26, 2016

$T07#bb? You seem have GDBStub enabled? If so, perhaps you could fire up GDB and see what's going on?

@chaeplin
Copy link
Contributor

@hallard
user_interface.h has 0 as NULL_MODE / https://github.com/esp8266/Arduino/blob/master/tools/sdk/include/user_interface.h#L146-L149

in SDK

wifi_station_disconnect(); 
wifi_set_opmode(NULL_MODE);

@torntrousers
Copy link
Contributor

I've tried the code from this comment http://www.esp8266.com/viewtopic.php?p=39624#p39624:

WiFi.mode(WIFI_OFF);
WiFi.forceSleepBegin();
delay(1); //Needed, at least in my tests WiFi doesn't power off without this for some reason

and it does switch WiFi off and the current use drops to about 14mA.
I've not though been able to successfully switch it on again. Doing:

  WiFi.forceSleepWake();
  delay(1);
  WiFi.mode(WIFI_STA);  
  WiFi.begin(ssid, password);

the current use goes back up to about 70mA but it never successfully connects again.

Can anyone show working code for how to switch on and connect again?

@chaeplin
Copy link
Contributor

@torntrousers Using example in SDK, I have 15mA, and wifi connection.

https://gist.github.com/chaeplin/be4d9ca41a991aa327bb

Modem sleep : https://youtu.be/ohOLPcs2aY4

@torntrousers
Copy link
Contributor

Thanks @chaeplin, it looks like its the wifi_station_connect() in your code that gets it connected again, so this works for me:

  WiFi.forceSleepWake();
  WiFi.mode(WIFI_STA);  
  wifi_station_connect();
  WiFi.begin(ssid, password);   

I wonder shouldn't the wifi_station_connect call be included within the WiFi.begin or WiFi.forceSleepWake function?

@chaeplin
Copy link
Contributor

@hallard
Copy link
Contributor

hallard commented Jan 26, 2016

@igrr
Yes I enabled GDBStub to resolve some exception, but unfortunately, the file xtensa-lx106-elf-gdb is not present on archive
http://arduino.esp8266.com/win32-xtensa-lx106-elf-gb404fb9-2.tar.gz
So I can' go further, do you have any build of GDB for windows ?
I will try using

WiFi.disconnect(); 
WiFi.mode(WIFI_OFF);
WiFi.forceSleepBegin();
delay(1);

as soon as I solve my GDB problem

@hallard
Copy link
Contributor

hallard commented Jan 26, 2016

I grabbed gdb from gnutoolchains here for those who're interested. I'm wondering If I can replace the whole ESP8266 toolchain bin directory from Arduino with this one from gnutoolchains ?

And following code did the trick (I don't need to enable WiFi back so I didn't tested this part). make sense to call WiFi.disconnect before WIFI_OFF, probably my mistake ;-)

WiFi.disconnect(); 
WiFi.mode(WIFI_OFF);
WiFi.forceSleepBegin();
delay(1);

Thanks to everyone helping me

@torntrousers
Copy link
Contributor

@chaeplin interesting, but I can't get it to connect again without the explicit call to wifi_station_connect in my code. Does it work with/without for anyone else?

@chaeplin
Copy link
Contributor

@torntrousers Without wifi_station_connect, I can't.

@vachhaninimit
Copy link

Hi,

I have used WiFi.mode(WIFI_OFF) which turned off my wifi modem. But after that i am creating Access point with same chip but not able to find the SSID. Is there any way to reset the chip or turn on the radio of wifi ?

@gosewski
Copy link

gosewski commented Mar 3, 2016

For me it works without explicit call to wifi_station_connect.
In my code I initially run an AP to get from user the SSID and PASS needed for STA mode, afterwards I switch mode to STA. As the simple switching mode from WIFI_AP to WIFI_STA doesn't turn off the AP I use WIFI_OFF mode in between. Here is a part of my code to turn off the AP and turn on the STA on the fly:

...
client.stop();
server.stop(); 
WiFi.disconnect();
WiFi.mode(WIFI_OFF);
WiFi.mode(WIFI_STA);
WiFi.begin(chSSID, chPWD);
while (WiFi.status() != WL_CONNECTED) delay(500);
...

@vachhaninimit
Copy link

@gosewski : Thanks for the info. I will give it a try and let you know.

@matthuisman
Copy link

matthuisman commented Apr 17, 2016

So, to confirm

after:
ESP.deepSleep(1000000, WAKE_RF_DISABLED),

The only way to get WiFi working is
ESP.deepSleep(1, WAKE_RF_DEFAULT)

Would doing this have the same affect (just as low current use on next boot):

WiFi.disconnect(); 
WiFi.mode(WIFI_OFF);
WiFi.forceSleepBegin();
delay(1);
ESP.deepSleep(1000000, WAKE_RF_DEFAULT);

@battika
Copy link

battika commented Apr 23, 2016

@matthuisman thanks for sharing this. I had exactly the same problem with Wi-Fi staying disabled after deepSleep and I was looking for an elegant way to turn it back on. Your second suggestion seemed to help. Thanks again.

@drmpf
Copy link

drmpf commented Sep 11, 2016

void stopWiFiAndSleep() {
  WiFi.disconnect();
  WiFi.mode(WIFI_OFF);
  WiFi.forceSleepBegin();
  delay(1);
}

Gives me about 30mA supply current, down from 80-90mA (WiFi running but not connected)
However after turning on an AP and handling the config I find I need to call this a couple of times to get back to 30mA.
(Perhaps a delay in sending last page is holding it up?)

@drmpf
Copy link

drmpf commented Sep 11, 2016

Tried without the delay(1), did not seem to work. Also tried just one call after delay(5000), also did not work. So now I am calling it very loop. i.e.

void loop() {
  if (webserverStarted) {
    dnsServer.processNextRequest();
    webserver.handleClient();
    return;
  }

  stopWiFiAndSleep();
 // ... other normal processing
}

This seems to work (at least for the last few tests)

@devyte
Copy link
Collaborator

devyte commented Oct 20, 2017

The original issue is answered. Closing.
If there is any other issue pending from the discussion, please open a new issue, add the requested info, and reference the relevant comment(s).

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

No branches or pull requests