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

Connection Speed Problem with WIFI_RESUME #7876

Closed
6 tasks done
mpoettgen opened this issue Feb 13, 2021 · 8 comments · Fixed by #7877
Closed
6 tasks done

Connection Speed Problem with WIFI_RESUME #7876

mpoettgen opened this issue Feb 13, 2021 · 8 comments · Fixed by #7877

Comments

@mpoettgen
Copy link
Contributor

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have (tested) verified that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: ESP8285
  • Core Version: 2.6.3
  • Development Env: PlatformIO
  • Operating System: Windows

Settings in IDE

  • Module: WEMOS D1 mini Lite
  • Flash Mode: not sure
  • Flash Size: 1MB
  • lwip Variant: not sure
  • Reset Method: not sure
  • Flash Frequency: not sure
  • CPU Frequency: not sure
  • Upload Using: SERIAL
  • Upload Speed: not sure

Problem Description

With below sketch on my WEMOS D1 mini Lite reconnecting to the WiFi after a deepSleep takes about 3.9 seconds. Changing the following line in ESP8266WiFiGenericClass::resumeFromShutdown to pass in the BSSID reduces the connection time to about 1.2 seconds.

nullptr/*(const uint8_t*)state->state.fwconfig.bssid*/, // <- try with gw's mac address?

I guess the idea here was to avoid connection problems, if there are multiple access points with the same SSID and the original access point is not available or another access point is closer to the station. However, this adds a huge performance penalty on WIFI_RESUME.

If always passing the BSSID to WiFi.begin is not an option, then some kind of API would be great for the user to decide which of the stored parameters should be used.

E.g. something like:

typedef enum {
  WIFI_RESUME_IPS = 0x01,
  WIFI_RESUME_CHANNEL = 0x02,
  WIFI_RESUME_BSSID = 0x04,
  WIFI_RESUME_FAST = WIFI_RESUME_IPS | WIFI_RESUME_CHANNEL | WIFI_RESUME_BSSID,
} wifi_resume_flags;

MCVE Sketch

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <include/WiFiState.h>
#include <PolledTimeout.h>

WiFiState state;

const char* ssid = *** YOUR SSID ***;
const char* password = *** YOUR PASSWORD ***;

void preinit(void)
{
  ESP8266WiFiClass::preinitWiFiOff();
}

void setup() {
  Serial.begin(74880);
  //Serial.setDebugOutput(true);
  Serial.println("Trying to resume WiFi connection...");

  // Necessary after deepSleep to be able to reconnect. Otherwise "error: pll_cal exceeds 2ms!!!"
  delay(1);

  ESP.rtcUserMemoryRead(33, reinterpret_cast<uint32_t *>(&state), sizeof(state));
  unsigned long start = millis();

  if (!WiFi.mode(WIFI_RESUME, &state)
    || (WiFi.waitForConnectResult(10000) != WL_CONNECTED))
  {
    Serial.println("Cannot resume WiFi connection, connecting via begin...");
    WiFi.persistent(false);
    if (!WiFi.mode(WIFI_STA)
      || ! (WiFi.begin(ssid, password))
      || (WiFi.waitForConnectResult(10000) != WL_CONNECTED))
    {
      WiFi.mode(WIFI_OFF);
      Serial.println("Cannot connect!");
      Serial.flush();
      delay(50);
      ESP.deepSleep(10e6, RF_DISABLED);
      return;
    }
  }

  unsigned long duration = millis() - start;
  Serial.printf("Duration: %f", duration * 0.001);
  Serial.println();

  WiFi.mode(WIFI_SHUTDOWN, &state);
  ESP.rtcUserMemoryWrite(33, reinterpret_cast<uint32_t *>(&state), sizeof(state));

  Serial.println("Done.");
  Serial.flush();
  delay(50);
  ESP.deepSleep(10e6, RF_DISABLED);
}

void loop() {
  // Nothing to do.
}

Debug Messages

Before Change

... (boot)
20:20:03.591 > Trying to resume WiFi connection...
20:20:03.595 > Cannot resume WiFi connection, connecting via begin...
20:20:07.420 > Duration: 3.827000
20:20:07.431 > Done.
... (reboot after deepSleep)
20:20:17.220 > Trying to resume WiFi connection...
20:20:21.130 > Duration: 3.908000
20:20:21.141 > Done.
... (reboot after deepSleep)
20:20:31.085 > Trying to resume WiFi connection...
20:20:35.004 > Duration: 3.917000
20:20:35.015 > Done.

After Change

... (boot)
20:22:51.938 > Trying to resume WiFi connection...
20:22:51.942 > Cannot resume WiFi connection, connecting via begin...
20:22:55.752 > Duration: 3.812000
20:22:55.763 > Done.
... (reboot after deepSleep)
20:23:05.627 > Trying to resume WiFi connection...
20:23:06.821 > Duration: 1.191000
20:23:06.831 > Done.
... (reboot after deepSleep)
20:23:16.789 > Trying to resume WiFi connection...
20:23:17.990 > Duration: 1.199000
20:23:18.000 > Done.
...
@d-a-v
Copy link
Collaborator

d-a-v commented Feb 13, 2021

Thanks for investigating this !

Did you achieve this test by replacing the nullptr above by a pointer to your AP's bssid ?

@d-a-v
Copy link
Collaborator

d-a-v commented Feb 13, 2021

I guess the idea here was to avoid connection problems, if there are multiple access points with the same SSID and the original access point is not available or another access point is closer to the station. However, this adds a huge performance penalty on WIFI_RESUME.

No. I think it was simply a lack of time. If it's really working with the AP's bssid, then we should automate this and automatically store it in the structure before deepsleep is called.

@mpoettgen
Copy link
Contributor Author

mpoettgen commented Feb 13, 2021

I just changed

        // state->state.fwconfig.bssid is not real bssid (it's what user may have provided when bssid_set==1)
        auto beginResult = WiFi.begin((const char*)state->state.fwconfig.ssid,
                       (const char*)state->state.fwconfig.password,
                       state->state.channel,
                       nullptr/*(const uint8_t*)state->state.fwconfig.bssid*/,  // <- try with gw's mac address?
                       true);

to

        // state->state.fwconfig.bssid is not real bssid (it's what user may have provided when bssid_set==1)
        auto beginResult = WiFi.begin((const char*)state->state.fwconfig.ssid,
                       (const char*)state->state.fwconfig.password,
                       state->state.channel,
                       state->state.fwconfig.bssid,
                       true);

Even though the comment above states, that state->state.fwconfig.bssid is not a real bssid, I actually believe that it is. As you can see in the sketch I'm not setting it anywhere. Instead it is filled during shutdown in:

memset(state->state.fwconfig.bssid, 0xff, 6);
ret = wifi_station_get_config(&state->state.fwconfig);

As far as I understand, the BSSID can be something other than the mac address of the AP, so trying to fill that in during initial connect may not work. However using the value set by wifi_station_get_config should be possible. What I don't know is what happens, if you have multiple APs with the same SSID and the BSSID does not belong to the best one.

@d-a-v
Copy link
Collaborator

d-a-v commented Feb 14, 2021

I tried your change and your example shows that this API works, nice !
The example WiFiShutdown meant to demonstrate this API is too complex.
I suggest you make a PR with your change, in which you also replace the example with yours.

What I don't know is what happens, if you have multiple APs with the same SSID and the BSSID does not belong to the best one.

I don't think this matters. This API is meant to wake up faster when possible. If the chip has physically moved and another bssid with the same ssid is around, then it will take longer to connect. This API is useful for the general case, where the same AP is always around.

@mpoettgen
Copy link
Contributor Author

Will create a PR.

@mpoettgen
Copy link
Contributor Author

@d-a-v shouldn't the WiFiShutdown expample be in the ESP8266WiFi/examples library folder?

@mpoettgen mpoettgen changed the title Connection Speed Problem / Feature Request for WIFI_RESUME Connection Speed Problem with WIFI_RESUME Feb 14, 2021
@mpoettgen
Copy link
Contributor Author

Should I try to add some documentation for WIFI_SHUTDOWN / WIFI_RESUME?

@d-a-v
Copy link
Collaborator

d-a-v commented Feb 14, 2021

This will be welcome !

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

Successfully merging a pull request may close this issue.

2 participants