tzapu / WiFiManager

ESP8266 WiFi Connection manager with web captive portal
http://tzapu.com/esp8266-wifi-connection-manager-library-arduino-ide/
MIT License
6.52k stars 1.96k forks source link

Failed to connect when we have multiple access point with same name #221

Closed jkandasa closed 6 years ago

jkandasa commented 7 years ago

I tried this WiFiManager it is working awesome. When I have more than one ap with same name(I'm using repeater, to extend WiFi Range) it is not connecting. It looks like we are not using bssid to connect a specific access point.

I believe when we connect with bssid, this problem will be resolved.

Thank you!

kentaylor commented 7 years ago

I can see value in that for your scenario. It looks quite doable according to http://www.esp8266.com/viewtopic.php?f=32&t=5604#p29465 .

Just needs someone to put in the effort.

lakidd commented 7 years ago

+1 for bssid as well. I use to to greatly reduce connection times to an existing AP. I roughly know how to do it but struggling with where it should go in the code. Is it a saved value like the previously used SSID and password or does it need to be specified every time we connect ?

kentaylor commented 7 years ago

Are you sure it reduces connection times? I know that specifying a fixed IP reduces connection times from several seconds for DHCP to about 1/3 of a second but a fixed BSSID and channel as a connection time reduction method is new to me. Reduced connection times would be of great value in deep sleep scenarios where a few sensor readings are made and reported. I know that currently most of the time awake is spent establishing the WiFi connection. Power consumption can be greatly reduced if WiFi connection times can be reduced.

You only need to specify it once, then it remembers. The most code changes are in collecting the values through the web interface. You need to display the information on the web page then have variables to collect the information. Where there are multiple access points with the same SSID it currently shows only the one with the strongest signal which is simple and probably what most people want. The duplicates are removed here https://github.com/tzapu/WiFiManager/blob/master/WiFiManager.cpp#L421 . I don't know whether next time it boots it chooses the same one or it chooses the strongest signal but the obvious thing is strongest signal each time it connects. This logic is further down the software stack from WiFiManager.

Most people wouldn't know what BSSID and channel means, and still wouldn't be interested if they did so there would need to be some way to hide the options from the average user.

For a one off application don't use WiFiManager but hard code it as described at http://www.esp8266.com/viewtopic.php?f=32&t=5604#p29465 .

lakidd commented 7 years ago

@kentaylor from my testing, by specifying a BSSID i get connection times down to 250ms coming out of deep sleep by specifying one (and yes i do it for the same reasons as you). I've done it the hard coded way you mention but when using the WiFiManager, what is the right way to retrieve the configured/saved SSID and network as you can't just call WiFi.begin with just the BSSID, you need all 3 parameters ? I'll have a hack around this weekend and see if I can get it working. Does anyone know what this does ?

_ssid = server->arg("s").c_str();
  _pass = server->arg("p").c_str();

My best guess is that it goes looking in the web template file for an id or name field that matches and returns the text in that input box. I'll need to duplicate for BSSID.

kentaylor commented 7 years ago

@lakidd it is not clear what you mean by connection times. Looking at this analysis you see a wake up time before the program launches of 315ms, a program run time that the program can measure of 142ms and a shut down time of 110ms. In the 142ms the program was running it took a temperature measurement and sent it via UDP. Strategies to make it short were UDP rather than TCP/IP, and a fixed IP. You can save about 30ms of high power consumption by not doing a RFCAL.

You are suggesting that specifying a BSSID and channel rather than SSID will speed things up again. I'm curious by how much?

The lines:- _ssid = server->arg("s").c_str(); _pass = server->arg("p").c_str(); mean take the values which you see in the http query in the form ?s=some_value&p=another_value , convert them to a string type and assign them to the variables _ssid and _pass respectively.

Another approach would be, don't modify WiFiManager but use IOT Configurator to set the extra parameters after you have established your initial WiFi connection. Then call the begin function again with the extra parameters. On subsequent reboots there is no need call begin as the the ESP8266 will remember them and reuse them. They are even remembered after reflashing with a new program.

lakidd commented 7 years ago

Thanks, so I profiled my setup by simply tracking millis() from startup() to when the ESP goes back to deep sleep (this is for a reed switch which sends mqtt notifications). The reed switch is connected to a RESET and a state change on that pin triggers the wake up from sleep. It connects to the wifi network, then the MQTT server, sends an MQTT message and goes back to sleep. ~~For me, IIRC by specifying BSSID my measurements went from around 750ms to 250ms for the cycle above~~Scratch this, I've looked at my code again.

It shortened the time from wakeup to connecting to associating to the wifi by around 500ms.

I haven't hooked it up to an oscope to see the whole cycle i.e pre setup() Thanks for the clarification above, i didn't realise it was parsing the URL rather than the webpage, I'm going to have to do some more digging in the code. IOT Configurator looks interesting but I'm a little gun shy of cloud services going bust and breaking systems when they run out of money etc etc

On Thu, Nov 3, 2016 at 5:22 PM, Ken Taylor notifications@github.com wrote:

@lakidd https://github.com/lakidd it is not clear what you mean by connection times. Looking at this analysis https://forum.makehackvoid.com/t/esp8266-deep-sleep-cycle-times-and-power-consumption-with-wifi-on/786/4?u=ken_taylor you see a wake up time before the program launches of 315ms, a program run time that the program can measure of 142ms and a shut down time of 110ms. In the 142ms the program was running it took a temperature measurement and sent it via UDP. Strategies to make it short were UDP rather than TCP/IP, and a fixed IP. You can save about 30ms of high power consumption by not doing a RFCAL https://forum.makehackvoid.com/t/esp8266-deep-sleep-cycle-times-and-power-consumption-with-wifi-on/786/5?u=ken_taylor.

You are suggesting that specifying a BSSID and channel rather than SSID will speed things up again. I'm curious by how much?

The lines:- _ssid = server->arg("s").c_str(); _pass = server->arg("p").c_str(); mean take the values which you see in the http query in the form ?s=some_value&p=another_value , convert them to a string type and assign them to the variables _ssid and _pass respectively.

Another approach would be, don't modify WiFiManager but use IOT Configurator http://configure.urremote.com/ to set the extra parameters after you have established your initial WiFi connection. Then call the begin function again with the extra parameters. On subsequent reboots there is no need call begin as the the ESP8266 will remember them and reuse them. They are even remembered after reflashing with a new program.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/tzapu/WiFiManager/issues/221#issuecomment-258071438, or mute the thread https://github.com/notifications/unsubscribe-auth/AGv8Jcl_esLt1M04NHTQh1kM3jcdKVo1ks5q6X2UgaJpZM4JyOOF .

tzapu commented 7 years ago

a few mentions:

does setting the ip manually not make it fast enough for you? you can just call WiFi.SSID() and WiFi.psk() i think to get the ssid and pass

hope it helps

lakidd commented 7 years ago

thanks @tzapu rather than hack away at your lib, I'll try to use the wifi.ssid and wifi.psk calls and set the bssid e.g wifi.begin(WiFi.SSID(),WIFI.psk(),1,my_bssid); Any time reductions during wifi assocation results in power savings which is good for battery systems. It's also helpful for things which happen quickly like a door opening and closing :-)

kentaylor commented 7 years ago

You've saved 500ms by specifying BSSID but in the case discussed above the total cycle time was 567ms so there isn't 500ms to save. In this case without running the radio at all the cycle time was about 250ms so it is a mystery how the 500ms cycle time reduction was achieved for your situation.

I've got a tipping bucket rain gauge I want to do something similar with. It pulses a reed switch every time it tips. I'd be curious to look at your code and circuitry, perhaps you could post your stuff or a link to https://forum.makehackvoid.com/ .

@tzapu's comment is interesting. If the

esp8266 core does not save bssid anywhere

then I wonder if specifying BSSID in a sketch will always improve things as I think the device starts connecting to WiFi before the sketch is started.

lakidd commented 7 years ago

yeah ignore me, i'm getting confused between what i measured..that said in my head it was better (and significantly so) using BSSID as opposed to not IIRC. I'm toying around using an ATTINY to wake an ESP8266 from sleep via the RESET line vs using an ATTINY to latch a power supply. I've pulled the prototype apart and so can't easily retest.

kentaylor commented 7 years ago

It seemed like

using BSSID as opposed to not

ought to be better as the sequence of steps to connect ought to be less. However after @tzapu 's advice that

esp8266 core does not save bssid anywhere

and given that portion of the WiFi connection sequence is likely to be finished before user code starts I'm wondering whether it is. Perhaps @eyaleb will test it at some stage as he's done a lot of work on reducing power consumption.

This discussion has got me thinking again about

a reed switch which sends mqtt notifications

I wrote up a description of the problem for the tipping bucket rain gauge case and perhaps @lakidd can contribute.

eyaleb commented 7 years ago

I run nodeMCU firmware, so LUA. The way to set ssid/bssid is with

wifi.sta.config(ssid, passphrase, 1, bssid)

Doing this will significantly lengthen the wifi setup time. Not doing a thing is fastest, the saved values are used. Here is what it looks like regardless of having set bssid or not.

one cycle

The pink trace is used to mark actions of the app. The short train of pulses before 400ms is where the app is waiting for the wifi connection. If I execute the wifi.sta.config at the start of my app then this train becomes about 2s long.

The blue trace is the reset/wakeup pin and you see that it was triggered at 50ms from the left. The full cycle (wakeup, read sensor, send UDP packet, sleep) is under 500ms.

My reading of the esp8266 sdk api is that the bssid is saved to flash alongside the ssid and password. I did not find anything to suggest that providing the bssid makes things faster, I actually got the impression that it is used to further check the ap and should normally not be set.

lakidd commented 7 years ago

I'll write something up for you Ken over on your forums.

On Tue, Nov 8, 2016 at 2:13 PM, Ken Taylor notifications@github.com wrote:

It seemed like

using BSSID as opposed to not

ought to be better as the sequence of steps to connect ought to be less. However after @tzapu https://github.com/tzapu 's advice that

esp8266 core does not save bssid anywhere

and given that portion of the WiFi connection sequence is likely to be finished before user code starts I'm wondering whether it is. Perhaps @eyaleb https://github.com/eyaleb will test it at some stage as he's done a lot of work on reducing power consumption.

This discussion has got me thinking again about

a reed switch which sends mqtt notifications

I wrote up a description of the problem https://forum.makehackvoid.com/t/weather-station-wake-up-triggered-by-either-the-rtc-or-a-momentary-switch/972 for the tipping bucket rain gauge case and perhaps @lakidd https://github.com/lakidd can contribute.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/tzapu/WiFiManager/issues/221#issuecomment-259033824, or mute the thread https://github.com/notifications/unsubscribe-auth/AGv8JWqhcrixu6WQ4BnuZRz-n49vjoTtks5q7-jzgaJpZM4JyOOF .

lakidd commented 7 years ago

@kentaylor does this fix the problem ? https://iothacking.wordpress.com/2016/11/08/mqtt-reed-switch/

tablatronix commented 7 years ago

ok so no speed advantage ?

back to posters issue, forcing bssid.

kentaylor commented 7 years ago

ok so no speed advantage ?

The opposite to a speed advantage if it's set in user code according to @eyaleb's testing and @lakidd is unsure of his testing now. If there is no speed advantage why would someone want to specify a BSSID unless it fixes

Failed to connect when we have multiple access point with same name

which I haven't tested but I'd be surprised?

If choosing BSSID is added it may not be necessary to

store bssid somwhere

and

add connection code to check bssid store and handle appropriately.

as @eyaleb tells me the Espressif library stores BSSID in flash alongside SSID and password if specified which raises another question. Specifying BSSID in user code slows things down but could it still speed things up when BSSID is stored in flash?

tablatronix commented 7 years ago

Espressif library stores BSSID in flash alongside SSID and password

anyone have reference for this ? source ?

There are other reasons you might do this, testing specific aps, bypassing a problematic or fake ap ( this happens alot where I am , better signal strength but no internet or flaky dropped connections etc )

eyaleb commented 7 years ago

Reading the doco section 3.5 Wi-Fi Related APIswe see

7. wifi_station_set_config
...
Note:
...
* This configuration will be saved in flash system parameter area if changed.

The configuration, station_config, includes the four fields ssid, password, bssid_set and bssid. Later the configuration is described in 7.2 WiFi Related Structures and we read

1. Station Related
...
Note:
BSSID as MAC address of AP, will be used when several APs have the same SSID.
If station_config.bssid_set==1 , station_config.bssid has to be set, otherwise, the connection will fail.

So, if bssid_set is true then bssid will be used.

Now, I use nodemcu-firmware, and in wifi.c I see in wifi_station_config() doing

    if (lua_isstring(L, 4))
        {
          const char *macaddr = luaL_checklstring( L, 4, &ml );
          luaL_argcheck(L, ml==17, 1, INVALID_MAC_STR);
          c_memset(sta_conf.bssid, 0, 6); 
          ets_str2macaddr(sta_conf.bssid, macaddr);
          sta_conf.bssid_set = 1;
        }

So, short of a bug, this should work.

Someone else, familiar with that code, should check what WiFiManager does. If bssid is not handled properly then it should be trivial to add it.

tablatronix commented 7 years ago

1.6.5 added bssid arg to begin() it looks like.

tablatronix commented 7 years ago

1.6.5 added bssid arg to begin() it looks like. But

struct station_config {
    uint8 ssid[32];
    uint8 password[64];
    uint8 bssid_set;    // Note: If bssid_set is 1, station will just connect to the router
                        // with both ssid[] and bssid[] matched. Please check about this.
    uint8 bssid[6];

So not sure if fully implemented as far as flash goes.

This seems to suggest it at least works manually https://github.com/esp8266/Arduino/issues/1854

kentaylor commented 7 years ago

I'm unsure what is meant by

works manually

Following the hyperlink in the reference provided by @tablatronix BSSID is added to the structure containing SSID and password here and passed to the espressif library in the function call wifi_station_set_config(&conf); or wifi_station_set_config_current(&conf);

Does

works manually

mean the function wifi_station_set_config_current(&conf) works but wifi_station_set_config(&conf) may not?

tablatronix commented 7 years ago

manually as in calling begin() with bssid I am unsure of if it is being set and read from flash, but if it works in espressif sdk then it probably works as it is being set..

    if(bssid) {
        conf.bssid_set = 1;
        memcpy((void *) &conf.bssid[0], (void *) bssid, 6);
    } else {
        conf.bssid_set = 0;
    }

So now to test, since it seems all good

lakidd commented 7 years ago

OK, so I've retested (albeit just by calling millis() vs tracking it on a scope. Without supplying BSSID (and using a hidden SSID and static IP) it takes my ESP8266 2.2 seconds to connect to the access point (just SSID and password).

Serial.println(millis());
    if (WiFi.status() != WL_CONNECTED)
    {
    WiFi.config(ip,gw,subnet, dns);
    WiFi.begin(ssid, password);
    }

    while (WiFi.status() != WL_CONNECTED) {
        delay(5);
        Serial.print(".");
    }
    Serial.println(millis());
MAC Address
5c:cf:7f:1a:8f:be:

Connecting to homegw3
276
...........................................................................
............................................................................
.............................................................................
.............................................................................
...............................................................................
......................................2414

When I add BSSID and channel it connects in 500ms


Serial.println(millis());
    if (WiFi.status() != WL_CONNECTED)
    {
    WiFi.config(ip,gw,subnet, dns);
    WiFi.begin(ssid, password,1,bssid);
    }

    while (WiFi.status() != WL_CONNECTED) {
        delay(5);
        Serial.print(".");
    }
    Serial.println(millis());
Console output
MAC Address
5c:cf:7f:1a:8f:be:

Connecting to homegw3
278
.................................................................................................................
..................................................................778

So my tests lead me to believe that supplying channel and BSSID makes a big difference in connection times.

eyaleb commented 7 years ago

@lakidd I can see the difference, but the question is: why supply ssid/pwd/bssid at all. If the SDK saves this data then one can simply skip this after running your code (as above) once.

    Serial.println(millis());
    while (WiFi.status() != WL_CONNECTED) {
        delay(5);
        Serial.print(".");
    }
    Serial.println(millis());

Can you try this? Does adding the bssid in the first run still make later connections faster? I run this way and get a connection in less than 200ms from program start (as my earlier DSO trace shows).

Or one can include a timeout feature to deal with a failed (or first) connection, maybe like (untested)

    Serial.println(millis());
    uint32_t stop = millis() + 5000;
    while (WiFi.status() != WL_CONNECTED) {
        if (millis() > stop) {
            Serial.println("reset WiFi");
            WiFi.config(ip,gw,subnet, dns);
            WiFi.begin(ssid, password,1,bssid);
            Serial.println(millis());
            stop = millis() + 5000;
        }
        delay(5);
        Serial.print(".");
    }
    Serial.println(millis());
lakidd commented 7 years ago
if (WiFi.status() != WL_CONNECTED)
    {
    WiFi.config(ip,gw,subnet, dns);
    //WiFi.begin(ssid, password,1,bssid);
    //WiFi.begin(ssid, password);
    WiFi.begin();
    }

    while (WiFi.status() != WL_CONNECTED) {
        delay(5);
        Serial.print(".");
    }
    Serial.println(millis());
MAC Address
5c:cf:7f:1a:8f:be:

Connecting to homegw3
274
...................................................................................................
...................................................................................................
...................................................................................................
....................................................................................................
.........................2415

WiFi connected

so it does look like that BSSID is not saved...bummer.

tzapu commented 7 years ago

from some sample code i ve seen, it looked like it was given to the SDK in nodelua, not sure about arduino ide i still don t know what exatly happens with it after...

tablatronix commented 7 years ago

This is a pretty anecdotal test, 2.2 seconds seems like a long time to connect to ap, there might be other stuff going on here, router problems, channel switching, dual band.

tablatronix commented 7 years ago

ok maybe I spoke too soon, I thought I was connecting fast but logging says over 5000 ms hmm

tablatronix commented 7 years ago

my observations, quick testing mutiple reboots

no bssid : 5000ms bssid set : 3100 ms (BSSID_set = 1 on printdiag, so it seems to be saving correctly)

dhcp client seems to take up a bit of time on boot

static ip config & BSSID : 549 ms static ip config & NO BSSID: 2500 ms

**\ all tests timed from boot, with serial begin() included in time, channel not set (0), one AP, I will test with various environments later

So I would guess for battery powered devices it is worth saving all these settings and if a fail occurs, fall back to regular ap connect and send a flag with any data.

Also be sure to set WIFI_STA if you are not using AP.

lakidd commented 7 years ago

@tablatronix yep those times are what I'm seeing too. What I'm confused about is, you say it's being saved (as per BSSID_set=1) and yet when it's not specified in WiFi.begin() it takes much longer. Is it being saved but not used ?

tablatronix commented 7 years ago

Not sure i understand , bssid is not saved unless you provide it afaik. Also note my test are not using begin I am letting sdk persistant do it.

lakidd commented 7 years ago

So, if I provide SSID, password and BSSID...esp8266 connects really fast. If I then modify the code to just call WiFi.begin() it's quite slow. It must be pulling SSID and PW from somewhere but it's not pulling the BSSID. So either it's not being saved or it's not being used by the Arduino core. Or am I misunderstanding ? When you say

I am letting sdk persistant do it

I don't understand...how do you join the wireless network ? How do you trigger the connection process ?

kentaylor commented 7 years ago

@lakidd asks

How do you trigger the connection process ?

You don't trigger the connection process. The connection process starts before your code runs using the parameters stored in flash.

The user code thread is not launched until long after the device boots and lots of other stuff happens.

lakidd commented 7 years ago

ah ok, didn't know this, I'll give it a go tonight

kentaylor commented 7 years ago

Another observation from @eyaleb is that the ESP8266 runs the connection process at startup and, if it fails, thereafter once per second. So if you are running on battery and don't get the first connection the device has to run at least 3 times longer.

He's also found a method for faster than the normal deepsleep shutdown implemented in Lua that I don't think is implemented in Arduino. I'm curious what it does. To quote from @eyaleb:- rtctime.dsleep() which calls rtctime_deep_sleep_us() which calls rtc_time_deep_sleep_us() which calls rtc_time_enter_deep_sleep_us() which fiddles with the SOC registers directly (as we saw tonight).

eyaleb commented 7 years ago

The final function rtc_time_enter_deep_sleep_us() manipulates the SOC registers directly and forces it into immediate deep sleep. I think it was introduced to nodeMCU as part of the new rtctime set of functions which attempt to keep more accurate time.

This is unlike the vanilla deep sleep function which takes some time doing housekeeping before actually entering deep sleep.

My understanding is that if you know that there are no pending actions then the force function should be safe to use.

lakidd commented 7 years ago

@kentaylor ok this is very cool...without wifi.begin() in my code I now get

MAC Address
5c:cf:7f:1a:8f:be:

Connecting to homegw3
274
..........................405

WiFi connected
IP address:
192.168.1.222

Which is 131ms connection time...much better than when i did a wifi.begin(ssid, password, 1, bssid) (500ms) so it does appear that the BSSID is being saved and used as suspected. Now I just need to figure out how to modify WiFiManager to take it as an optional parameter :-)

kentaylor commented 7 years ago

Glad you like it @lakidd but it was @eyaleb that first said

one can simply skip this after running your code (as above) once.

As well, he said BSSID is stored in flash, provided a reference when asked and has also said

I did not find anything to suggest that providing the bssid makes things faster

He's usually pretty thorough so I expect if you test that you'll find he is correct in that statement too.

lakidd commented 7 years ago

ok fair point. I did not understand what @eyaleb was getting at with his earlier comment, which you explained. I'm sure he is correct, but i'm working through this one step at a time. Feel free to rachet the snark down one level

kentaylor commented 7 years ago

This discussion has got me thinking that if Esspressif can be persuaded to change their library there is another opportunity to speed things up.

If you don't specify a fixed IP then DHCP is used and that takes a long time. But IP is not stored in flash so you don't get a chance to specify IP until user codes starts which in the @lakidd example is 274 milliseconds after the clock started and the clock starts some time after boot (hence the requirement to use an oscilloscope for accurate timing).

Another @eyaleb observation was that it mostly takes about the same time after you specify an IP address for a WL_CONNECTED to be achieved regardless of what else you do in the user code. That suggests there is a period before user code starts where WiFi is established and the DHCP process has commenced. If IP could be stored alongside the other connection parameters in flash the IP interaction with the router ought to be able to be started earlier. Does that seem likely?

Even if it can be made faster with a fixed IP address it might not be useful to most people as the requirement to manually manage IP addresses is probably too much to ask of the casual IOT consumer.

Sorry if it seemed snarky, it wasn't intended.

tablatronix commented 7 years ago

Like I said providing the BSSID being faster might be anecdotal , and restricted to specific scenarios. BUT it certainly is faster when I tested it. I now have access to 20 APs with same SSID, so I might do some mixed BSSID testing trying to connect to specific ones and see what I find.

But according to those docs, I fail to see why it should be faster, as it says BSSID is used ( and the code does a comparison SSID && BSSID == ) if there are dup SSIDs , but it was faster for me ( without dups ), sooo, maybe there is ancillary scans or queries running when there are indeed many SSID matches causing further delays in some instances.

My tests also show the dhcp client is extremely slow to start, bypassing it causes me another massive speed increase. set_debug_output(true) or enable the sdk debugging and you can clearly see these things initializing or NOT.

Edit: Maybe I misread that part, you mean store IP config in flash, yeah that would speed things up a bit so it can be done before setup(), but I think the wifi stuff waits a bit, so it does not necessarly startup before setup().

Maybe a reasonable solution here is to optimize the dhcp client a little more.

I was wondering how the esp lib would handle this scenario, a rogue or no network AP with full signal. I assume it will it keep picking it over and over since it does just a signal strength check, in my connection code i always do a ping to confirm actual connectivity, if i have good sta and an ip, but no internet for example, I might want to force BSSID to get around this. It seems this might also popup with repeaters, people being arseholes, or dual band aps with the same ssid ?

lakidd commented 7 years ago

OK, so at the risk of confirming what we already know...

MAC Address
5c:cf:7f:1a:92:69:

Connecting to homegw3
288
..................................................................................................
..................................................................................................
..................................................................................................
..................................................................................................
..............................2432

WiFi connected
IP address:
192.168.1.222

MAC Address
5c:cf:7f:1a:92:69:

Connecting to homegw3
288
.................................................................................................
................................................................................................
...............................................................................................
................................................................................................
......................................2429

MAC Address
5c:cf:7f:1a:92:69:

Connecting to homegw3
290
........................................................................................
........................................................................................
.........................................................................................
.........................................................................................
....................................................................2432

WiFi connected
IP address:
192.168.1.222

These tests are done with a new ESP8266 which has NEVER had the BSSID configured on it. The first test is with wifi.begin(ssid, password) The second two are with no wifi.begin (i.e. using saved credentials from test 1). As can be seen the time is much longer in all cases. BSSID makes a huge difference in my experience (as per @tablatronix )

kentaylor commented 7 years ago

Hmmm. @eyaleb gets a WiFi connection quickly without specifying BSSID. @lakidd and @tablatronix can not, so the question is what is @eyaleb doing different?

Hypothesis: @eyaleb uses Lua, others use Arduino and there is some difference in the way the environments work.

Test: Run this Arduino script and observe connection times.. As for the @lakidd test

These tests are done with a new ESP8266 which has NEVER had the BSSID configured on it.

Results: SDK version:1.5.3(aec24ac9) Start millis = 315 Now millis = 469 Program Time = 154 90:67:1C:53:62:C2

SDK version:1.5.3(aec24ac9) Start millis = 317 Now millis = 473 Program Time = 156 90:67:1C:53:62:C2

SDK version:1.5.3(aec24ac9) Start millis = 322 Now millis = 1597 Program Time = 1275 90:67:1C:53:62:C2

Start millis = 320 Now millis = 474 Program Time = 154 90:67:1C:53:62:C2

These times are similar to those reported by @eyelab without specifying BSSID.

Conclusion: Hypothesis falsified. Similar results to those achievable in Lua without specifying BSSID are attainable in Arduino.

The question of what does @eyaleb, and now myself also, do different from @lakidd and @tablatronix remains unsolved. I am curious and fiddled about a bit but can't figure it out.

Asides: If this line is uncommented, BSSID will be stored in flash without having to ask the user to supply it. Channel is hard coded but that can be fixed.

Also, @tablatronix suggested:

I might want to force BSSID to get around this.

In general that will not stop

people being arseholes

because BSSID can be configured by a malicious actor in an AP (not in all but in general it is possible).

eyaleb commented 7 years ago

I do not know how the arduino wakes up, but using nodeMCU I get a start millis of about 128ms. This is measured at the first instruction of the app. Naturally, this does not count the initial, uncounted time of around 70ms that I can see with the DSO.

tablatronix commented 7 years ago

For starters I am using first boot not deepsleep wakeup for testing, so apparently deep sleep keeps something in memory.

eyaleb commented 7 years ago

I ran a trivial test on nodeMCU.

local start_us = tmr.now()
wifi.sta.setip({ip="192.168.2.58",netmask="255.255.255.0",gateway="192.168.2.7"})
tmr.alarm(1, 1, 1, function()
        if 5 ~= wifi.sta.status() then return end
        local end_us = tmr.now()
        tmr.stop(1)

        print (("  %.6f start"):format(start_us/1000000))
        print (("  %.6f have connection"):format(end_us/1000000))
end)
using node.restart()
  0.113605 start
  2.246002 have connection

using node.dsleep()
  0.106271 start
  0.228739 have connection

using rtctime.dsleep()
  0.107350 start
  0.229817 have connection

without setip()
  0.104691 start
  1.162739 have connection
lakidd commented 7 years ago

As per @tablatronix comment, I'm also starting from power up not deep sleep.

tablatronix commented 7 years ago

my test was looping restarts not sleep cycles, so yeah curious, I guess sleep keeps everything ready , so bssid probably makes no difference there.

kentaylor commented 7 years ago

It has been suggested there is a difference in WiFi connection times between power up and DeepSleep. I modified the previous sketch to this to test WiFi connection times at power up and after reset without BSSID.

At power up and when using the reset pin the results were the same as previously, usually around 155 ms program time.

By commenting this line and uncommenting this line and the following line I entered a BSSID into flash that didn't match the AP. It still connects but takes around 14 seconds. After reverting the code, WiFi connection times go back to around 155ms again. This indicates BSSID is stored in flash and used but will be ignored when an AP with the specified BSSID is not available.

lakidd commented 7 years ago

So I've modified the code to add BSSID and channel in the portal and then use them if supplied. It's here https://github.com/lakidd/WiFiManager/tree/bssid It seems to work for me, but I have not tested this extensively yet so feel free to do so.