Skip to content

WiFi Mode() not working #1306

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

Closed
sticilface opened this issue Apr 10, 2018 · 17 comments
Closed

WiFi Mode() not working #1306

sticilface opened this issue Apr 10, 2018 · 17 comments
Labels
Status: Stale Issue is stale stage (outdated/stuck)

Comments

@sticilface
Copy link
Contributor

Hardware:

Board: ESP32 Dev Module?
Core Installation/update date: @ 29b3a81
IDE name: Platform.io
Flash Frequency: 40Mhz
Upload Speed: 115200

Description:

WiFi.mode() not working. Set it to 0 (WIFI_OFF) and it stays at 3.

Sketch:

#include <Arduino.h>
#include <WiFi.h>

void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true); 
  Serial.println();

  Serial.println("----------   WiFi Info --------");
  WiFi.printDiag(Serial); 
  Serial.println();
  
  WiFi.mode(WIFI_MODE_NULL);

  Serial.println("----------   WiFi Info --------");
  WiFi.printDiag(Serial); 
  Serial.println();
}

void loop() {
}

Debug Messages:

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:956
load:0x40078000,len:0
load:0x40078000,len:13256
entry 0x40078a90

----------   WiFi Info --------
E (61) wifi: esp_wifi_get_mode 799 wifi is not init
E (61) wifi: esp_wifi_get_channel 1214 wifi is not init
E (62) wifi: esp_wifi_get_auto_connect 1391 wifi is not init
Mode: NULL
Channel: 253
Auto connect: 63
E (71) wifi: esp_wifi_get_config 1057 wifi is not init
SSID (68): Ù..@ƒ..@d..@¸..@Ä..@ÿ..@t..@ò..@D..@Ã..@ò..@∞..@§é
Ä..˝?¥<¸?\.@?L..@
Passphrase (36): D..@Ã..@ò..@∞..@§é
Ä..˝?¥<¸?\.@?L..@
BSSID set: 48

----------   WiFi Info --------
Mode: AP
Channel: 0
Auto connect: 1
SSID (0): 
Passphrase (0): 
BSSID set: 1

so it is clear that WiFi.mode(WIFI_MODE_NULL) is not setting the mode to 0, but 3 which is AP.

Any ideas?

@sticilface
Copy link
Contributor Author

A little more digging on this issue. All is not entirely happy with the WiFi modes.

This sketch

void setup()
{
    Serial.begin(115200);
    // delete old config
    WiFi.disconnect(true);
    delay(1000);
    WiFi.begin(ssid, password);
    WiFi.mode(WIFI_MODE_NULL); 
}

That at no point calls any AP functions leads to this debug output

entry 0x40078a90
[D][WiFiGeneric.cpp:303] _eventCallback(): Event: 13 - AP_START
[D][WiFiGeneric.cpp:303] _eventCallback(): Event: 3 - STA_STOP
[D][WiFiGeneric.cpp:303] _eventCallback(): Event: 3 - STA_STOP
[D][WiFiGeneric.cpp:303] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:303] _eventCallback(): Event: 14 - AP_STOP
[D][WiFiGeneric.cpp:303] _eventCallback(): Event: 14 - AP_STOP

so it is curious that there are any AP_START event call backs given that there are no calls to start an AP.

I've also discovered that the underlying bool WiFiGenericClass::mode(wifi_mode_t m) function

bool WiFiGenericClass::mode(wifi_mode_t m)
calls espWiFiStop() when WIFI_MODE_NULL is used. This should then call wifiLowLevelDeinit() but this function does nothing and has the comment that it is not working.
//deinit not working yet!

It would appear that WIFI_MODE_NULL is not working as intended. as err = esp_wifi_set_mode(m) is called but the mode remains at 2.

further more.. if the only line in the sketch is WiFi.getMode() this calls wifiLowLevelInit() first thing which should initialise all the wifi stack as follows:

static bool wifiLowLevelInit(){
    static bool lowLevelInitDone = false;
    if(!lowLevelInitDone){
        tcpipInit();
        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
        esp_err_t err = esp_wifi_init(&cfg);
        if(err){
            log_e("esp_wifi_init %d", err);
            return false;
        }
        esp_wifi_set_storage(WIFI_STORAGE_FLASH);
        esp_wifi_set_mode(WIFI_MODE_NULL);
        lowLevelInitDone = true;
    }
    return true;
}

which should set the mode to WIFI_MODE_NULL but yet the result of a single WiFi.getMode() call is 2! which is AP mode.

I am beginning to think there is a bug in the API!

any thoughts?

@sticilface
Copy link
Contributor Author

sticilface commented Apr 16, 2018

workaround:

WIFI_MODE_NULL does not set the mode to null. I've edited the mode function so that it returns WIFI_MODE_NULL if _esp_wifi_started is false. I've then removed the wifiLowLevelInit() from getMode() and changed the order of mode().

The end result is that is works as expected despite the SDK reporting mode 2 (AP) even when only the low level init had been done and it was not actually in AP mode. At least this way the WiFi class reports the right mode.

example sketch below. Along with 2 debug outputs. Sorry for using my Tasker lib but it simplifies scheduling of things...

#include <WiFi.h>
#include <Tasker.h> //https://github.com/sticilface/Tasker

const char* ssid     = "abc";
const char* password = "def";

Task tasker;
const char * mysystem_event_names[] = { "WIFI_READY", "SCAN_DONE", "STA_START", "STA_STOP", "STA_CONNECTED", "STA_DISCONNECTED", "STA_AUTHMODE_CHANGE", "STA_GOT_IP", "STA_LOST_IP", "STA_WPS_ER_SUCCESS", "STA_WPS_ER_FAILED", "STA_WPS_ER_TIMEOUT", "STA_WPS_ER_PIN", "AP_START", "AP_STOP", "AP_STACONNECTED", "AP_STADISCONNECTED", "AP_PROBEREQRECVED", "GOT_IP6", "ETH_START", "ETH_STOP", "ETH_CONNECTED", "ETH_DISCONNECTED", "ETH_GOT_IP", "MAX"};


void WiFiEvent(WiFiEvent_t event)
{
  Serial.printf("[WiFi-event] event: %d :%s\n", event,mysystem_event_names[event] );
  Serial.printf("WiFi Mode = %d\n", WiFi.getMode());
}

void setup()
{
  Serial.begin(115200);

  delay(1000);

  WiFi.onEvent(WiFiEvent);


  Serial.println("\n\t\t\tStarting STA , mode should be 1");
  WiFi.enableSTA(true);
  WiFi.begin(ssid, password);

  tasker.add([](Task & t) {
    Serial.println("\n\t\t\tStopping WiFi mode should be 0");
    WiFi.mode(WIFI_MODE_NULL);
  }).setTimeout(10000);

  tasker.add([](Task & t) {
    Serial.println("\n\t\t\tStarting STA_AP, mode should be 3");
    WiFi.mode(WIFI_MODE_APSTA);
    WiFi.reconnect();
    WiFi.softAP("test_AP");
  }).setTimeout(20000);


  tasker.add([](Task & t) {
    Serial.println("\n\t\t\tContiniue AP only, mode should be 2");
    WiFi.enableSTA(false);
  }).setTimeout(25000);


  tasker.add([](Task & t) {
    Serial.println("\n\t\t\tStop all, mode should be 0");
    WiFi.enableAP(false);
  }).setTimeout(30000);


}


void loop()
{
  tasker.run();
}

NORMAL result from git head

...Starting STA , mode should be 1
[WiFi-event] event: 13 :AP_START
WiFi Mode = 3
[WiFi-event] event: 13 :AP_START
WiFi Mode = 3
[WiFi-event] event: 4 :STA_CONNECTED
WiFi Mode = 3
[WiFi-event] event: 7 :STA_GOT_IP
WiFi Mode = 3

...Stopping WiFi mode should be 0
[WiFi-event] event: 3 :STA_STOP
WiFi Mode = 3
[WiFi-event] event: 14 :AP_STOP
WiFi Mode = 3
[WiFi-event] event: 14 :AP_STOP
WiFi Mode = 3

...Starting STA_AP, mode should be 3
E (22160) wifi: esp_wifi_disconnect 877 wifi not start
[WiFi-event] event: 13 :AP_START
WiFi Mode = 3
[WiFi-event] event: 14 :AP_STOP
WiFi Mode = 3
[WiFi-event] event: 13 :AP_START
WiFi Mode = 3
[WiFi-event] event: 13 :AP_START
WiFi Mode = 3

...Continiue AP only, mode should be 2
[WiFi-event] event: 3 :STA_STOP
WiFi Mode = 2

...Stop all, mode should be 0
[WiFi-event] event: 14 :AP_STOP
WiFi Mode = 2
[WiFi-event] event: 14 :AP_STOP
WiFi Mode = 2

with above mentioned changes

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:956
load:0x40078000,len:0
load:0x40078000,len:13256
entry 0x40078a90

...Starting STA , mode should be 1
[WiFi-event] event: 14 :AP_STOP
WiFi Mode = 1
[WiFi-event] event: 2 :STA_START
WiFi Mode = 1
[WiFi-event] event: 2 :STA_START
WiFi Mode = 1
[WiFi-event] event: 4 :STA_CONNECTED
WiFi Mode = 1
[WiFi-event] event: 7 :STA_GOT_IP
WiFi Mode = 1

...Stopping WiFi mode should be 0
[WiFi-event] event: 3 :STA_STOP
WiFi Mode = 0
[WiFi-event] event: 3 :STA_STOP
WiFi Mode = 0

...Starting STA_AP, mode should be 3
[WiFi-event] event: 13 :AP_START
WiFi Mode = 3
[WiFi-event] event: 13 :AP_START
WiFi Mode = 3
[WiFi-event] event: 4 :STA_CONNECTED
WiFi Mode = 3
[WiFi-event] event: 7 :STA_GOT_IP
WiFi Mode = 3

...Continiue AP only, mode should be 2
[WiFi-event] event: 3 :STA_STOP
WiFi Mode = 2
[WiFi-event] event: 3 :STA_STOP
WiFi Mode = 2

...Stop all, mode should be 0
[WiFi-event] event: 14 :AP_STOP
WiFi Mode = 2
[WiFi-event] event: 14 :AP_STOP
WiFi Mode = 0
[WiFi-event] event: 8 :STA_LOST_IP
WiFi Mode = 0

so in conclusion, it looks like my changes work well. the mode changes as it should whereas currently it reports random modes!. I'd appreciate some other testing of this please. so far no one has identified it as an issue...

sticilface added a commit to sticilface/arduino-esp32 that referenced this issue Apr 16, 2018
sticilface added a commit to sticilface/arduino-esp32 that referenced this issue Apr 16, 2018
…lows you to hook in, as the sdk does not generate this event for you.

As it stands the SDK does not appear to set `WIFI_MODE_NULL` correctly.  if the wifi is initialised and set to `WIFI_MODE_NULL` it actually defaults to AP mode.  This fix keeps `WIFI_MODE_NULL` within the ESP class if the wifi has not been init yet, and works in my testing.  albeit a one sided conversation.
espressif#1306
@tablatronix
Copy link
Contributor

I do not see this behavior at all, with either the 2 sketches provided.

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11584
entry 0x40078a60
[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:298] _eventCallback(): Reason: 201 - NO_AP_FOUND
----------   WiFi Info --------
Mode: NULL
Channel: 0
Auto connect: 1
SSID (6): <
BSSID set: 0


----------   WiFi Info --------
Mode: STA
Channel: 1
Auto connect: 1
SSID (6): 
BSSID set: 0

----------   WiFi Info --------
Mode: NULL
Channel: 1
Auto connect: 1
SSID (6): 
BSSID set: 0

@tablatronix
Copy link
Contributor

oh btw that garbage when calling printdiag before init is a pita #1088

@tablatronix
Copy link
Contributor

Oh ok now I see the issue, wonder what changed... let me erase and see

@tablatronix
Copy link
Contributor

tablatronix commented Apr 23, 2018

which should set the mode to WIFI_MODE_NULL but yet the result of a single WiFi.getMode() call is 2! which is AP mode.

Actually it appears to be the persistent mode saved in flash, if you set mode and reset, and wifiinit via getmode it will be what you last had it as.

for example you can setup sta and ap configs
and setMode(WIFI_AP_STA);

remove them from your code

do

WiFi.getMode(); ( for wifilowelevelinit ) 
esp_wifi_start();
esp_wifi_connect();

and it will connect to both sta and softap saved prior.

If you set mode to something else, then it will only start those.

@tablatronix
Copy link
Contributor

I did one time catch this
notice the 4 ap_start events, and the wifi init failed, not really sure what happeend there, and I cannot reproduce it, maybe some race condition

[D][WiFiGeneric.cpp:297] _eventCallback(): Event: 13 - AP_START
[D][WiFiGeneric.cpp:297] _eventCallback(): Event: 13 - AP_START
[D][WiFiGeneric.cpp:297] _eventCallback(): Event: 13 - AP_START
[D][WiFiGeneric.cpp:297] _eventCallback(): Event: 13 - AP_START

E (1022) wifi: esp_wifi_get_mode 799 wifi is not init
0
mode:
0
E (1023) wifi: esp_wifi_start 810 wifi is not init
E (1023) wifi: esp_wifi_connect 868 wifi is not init
----------   WiFi Info --------
E (1029) wifi: esp_wifi_get_mode 799 wifi is not init
E (1034) wifi: esp_wifi_get_channel 1214 wifi is not init
E (1039) wifi: esp_wifi_get_auto_connect 1391 wifi is not init
Mode: NULL
Channel: 0
Auto connect: 0
E (1048) wifi: esp_wifi_get_config 1057 wifi is not init
SSID (5):  ��?
Passphrase (4): ��?�
BSSID set: 31

@sticilface
Copy link
Contributor Author

sticilface commented Apr 23, 2018

In my opinion there should be no resetting at all to get it to work.
the issue i've identified is that getMode() does not report the right value back to the WiFi lib when wifi is not initialised. Fixing that then allows the WiFi lib to make the required changes as it has


as checks to see if it needs to do anything.

making getMode() a passive function that does not by itself initialise the WiFi stack seems more sensible to me, than initialising it and having it in the wrong mode.

I have not yet experimented with saving the wifi settings to flash. so i cannot comment on those.

@tablatronix
Copy link
Contributor

Yeah I was just noting the mode is not random its the esp stored mode that was last set.

@tablatronix
Copy link
Contributor

tablatronix commented Apr 24, 2018

So it appears that WIFI_MODE_NULL is not an sdk mode , its a pseudo mode, this is what was confusing me. But wifiLowLevelInit does esp_wifi_set_mode(WIFI_MODE_NULL); which probably doesn't do anything

I also found another issue with this, see here
21ff3d0

@tablatronix
Copy link
Contributor

tablatronix commented Apr 24, 2018

When I revert to 3a4ec66 esp_wifi_set_mode(WIFI_MODE_NULL) actually saves...
esp_wifi_get_mode is 0

That is why this was working for me at first, then I pulled

@everslick
Copy link
Contributor

what i experienced is, that as @tablatronix pointed out, WIFI_MODE_NULL is not a valid mode as far as the IDF is concerned. Unfortunately IDF will silently fall back to the mode that it once stored in NVS (so I think), and there is no sane way to clear the config in NVS.

IMHO, we simply should not call wifiLowLevelInit() until mode has been set by the user to something other then WIFI_MODE_NULL.

@sticilface

making getMode() a passive function that does not by itself initialise the WiFi stack seems more sensible to me, than initialising it and having it in the wrong mode.

i agree.

I have not yet experimented with saving the wifi settings to flash. so i cannot comment on those.

persistent NVS config saving was the default before #1406 got merged an hour ago. so your settings ALWAYS got saved in flash.

me-no-dev pushed a commit that referenced this issue May 23, 2018
* Add `SYSTEM_EVENT_WIFI_READY` call back once wifi service is init.  allows you to hook in, as the sdk does not generate this event for you.
As it stands the SDK does not appear to set `WIFI_MODE_NULL` correctly.  if the wifi is initialised and set to `WIFI_MODE_NULL` it actually defaults to AP mode.  This fix keeps `WIFI_MODE_NULL` within the ESP class if the wifi has not been init yet, and works in my testing.  albeit a one sided conversation.
#1306

* make changes compatible with new _persistent behaviour.
Curclamas pushed a commit to Curclamas/arduino-esp32 that referenced this issue Aug 21, 2018
)

* Add `SYSTEM_EVENT_WIFI_READY` call back once wifi service is init.  allows you to hook in, as the sdk does not generate this event for you.
As it stands the SDK does not appear to set `WIFI_MODE_NULL` correctly.  if the wifi is initialised and set to `WIFI_MODE_NULL` it actually defaults to AP mode.  This fix keeps `WIFI_MODE_NULL` within the ESP class if the wifi has not been init yet, and works in my testing.  albeit a one sided conversation.
espressif#1306

* make changes compatible with new _persistent behaviour.
@stale
Copy link

stale bot commented Aug 1, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Status: Stale Issue is stale stage (outdated/stuck) label Aug 1, 2019
@stale
Copy link

stale bot commented Aug 15, 2019

This stale issue has been automatically closed. Thank you for your contributions.

@daald
Copy link

daald commented Dec 28, 2019

In my project, I successfully fixed the reconnect issue with the following hack:

diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp
index e562921..aab5805 100644
--- a/libraries/WiFi/src/WiFiGeneric.cpp
+++ b/libraries/WiFi/src/WiFiGeneric.cpp
@@ -483,8 +483,10 @@ void WiFiGenericClass::enableLongRange(bool enable)
 bool WiFiGenericClass::mode(wifi_mode_t m)
 {
     wifi_mode_t cm = getMode();
+    log_d("mode() cm=%d, m=%d", cm, m);
     if(cm == m) {
-        return true;
+        log_d("HACK: skip return true");
+        //return true;
     }
     if(!cm && m){
         if(!wifiLowLevelInit(_persistent)){

But I think the real issue is how getMode is implemented

@philbowles
Copy link

Not sure what version was in use when this problem was noted, but it's happening again in 1.0.4:

#include<WiFi.h>
void setup() {
  Serial.begin(115200);
  WiFi.begin();
  WiFi.disconnect(true,true);
  Serial.printf("STA mode? %s AP mode? %s [%d]\n",WiFi.getMode() & WIFI_STA ? "true":"false",WiFi.getMode() & WIFI_AP ? "true":"false",WiFi.getMode());
  WiFi.printDiag(Serial);
  WiFi.mode(WIFI_OFF);
  Serial.printf("STA mode? %s AP mode? %s [%d]\n",WiFi.getMode() & WIFI_STA ? "true":"false",WiFi.getMode() & WIFI_AP ? "true":"false",WiFi.getMode());
  WiFi.printDiag(Serial);
}

void loop() {
}
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 0 - WIFI_READY
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 2 - STA_START
[E][WiFiSTA.cpp:219] begin(): connect failed!
STA mode? false AP mode? false [0]
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 3 - STA_STOP
Mode: STA
Channel: 1
SSID (0): 
Passphrase (0): 
BSSID set: 0
STA mode? false AP mode? false [0]
Mode: STA
Channel: 1
SSID (0): 
Passphrase (0): 
BSSID set: 0

getMode() returns 0, yet printDiag reports STA - this is just plain WRONG! Do getMode and printDiag retrieve the REAL value of mode from different places? What is going on here and why has it not been fixed?

@atanisoft
Copy link
Collaborator

WiFi.getMode() and WiFi.printDiag() both are working as designed and expected on 1.0.4. Your code is incorrectly testing for bit mask rather than equality as it should be.

blue-2357 pushed a commit to blue-2357/arduino-esp32 that referenced this issue Jul 17, 2024
* Add `SYSTEM_EVENT_WIFI_READY` call back once wifi service is init.  allows you to hook in, as the sdk does not generate this event for you.
As it stands the SDK does not appear to set `WIFI_MODE_NULL` correctly.  if the wifi is initialised and set to `WIFI_MODE_NULL` it actually defaults to AP mode.  This fix keeps `WIFI_MODE_NULL` within the ESP class if the wifi has not been init yet, and works in my testing.  albeit a one sided conversation.
espressif/arduino-esp32#1306

* make changes compatible with new _persistent behaviour.
dash0820 added a commit to dash0820/arduino-esp32-stripped that referenced this issue Mar 10, 2025
* Add `SYSTEM_EVENT_WIFI_READY` call back once wifi service is init.  allows you to hook in, as the sdk does not generate this event for you.
As it stands the SDK does not appear to set `WIFI_MODE_NULL` correctly.  if the wifi is initialised and set to `WIFI_MODE_NULL` it actually defaults to AP mode.  This fix keeps `WIFI_MODE_NULL` within the ESP class if the wifi has not been init yet, and works in my testing.  albeit a one sided conversation.
espressif/arduino-esp32#1306

* make changes compatible with new _persistent behaviour.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Stale Issue is stale stage (outdated/stuck)
Projects
None yet
Development

No branches or pull requests

6 participants