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

Problematic WiFi connection to certain types of AP's #8950

Open
4 tasks done
wibbit opened this issue Jul 1, 2023 · 22 comments
Open
4 tasks done

Problematic WiFi connection to certain types of AP's #8950

wibbit opened this issue Jul 1, 2023 · 22 comments

Comments

@wibbit
Copy link

wibbit commented Jul 1, 2023

Basic Infos

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

Platform

  • Hardware: [ESP826EX - Lolin D1 Mini v4 (and v3)]
  • Core Version: [3.1.2 release, not sure how to update to latest]
  • Development Env: [Arduino IDE]
  • Operating System: [Fedora 37]

Settings in IDE

  • Module: [Wemos D1 mini r2]
  • Flash Mode: [Default, not sure]
  • Flash Size: [4MB]
  • lwip Variant: [v2 Lower Memory]
  • Reset Method: [dtr]
  • Flash Frequency: [40MHz]
  • CPU Frequency: [80MHz]
  • Upload Using: [SERIAL]
  • Upload Speed: [115200]

Problem Description

I'm having issues getting the ESP8266EX to connect to one of my WiFi AP's, this is an Asus RT-AX86U Pro, it has no issues connecting to an older Asus model that is also providing WiFi for the same SSID.

I've put together a minimal sketch to try and help debug this issue, and the output that I get is as at the end.

FYI, I did try going to the esp8266 forum, however, there appears to be a problem with my registration (no email was received).

I see several other tickets raised relating to something similar #7965 #8299 and I've tried both fixes and changes that appear to have helped them, most notably.

WiFi.setPhyMode(WIFI_PHY_MODE_11G); <- Added both before and after WiFi.begin, which no change

And changing the board to esp8266 generic, and changing to nonos-sdk2.2.1+61 (190313)

MCVE Sketch

#include <ESP8266WiFi.h>

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

WiFi.begin("HumptyDumpty", "Not_A_Real_SSID_for_me_at_least");

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

Serial.print("Connected, IP address: ");
Serial.println(WiFi.localIP());
Serial.printf("Wi-Fi mode set to WIFI_STA %s\n", WiFi.mode(WIFI_STA) ? "" : "Failed!");
Serial.printf("Connection status: %d\n", WiFi.status());
WiFi.printDiag(Serial);

}

void loop() {}

Debug messages go here

I have the following information from my router, which may be helpful
Stations List

idx MAC Associated Authorized RSSI PHY PSM SGI STBC MUBF NSS BW Tx rate Rx rate Connect Time
7C:87:CE:BE:20:D4 Yes Yes -56dBm g No No No No 1 20M 54M 1M 00:00:03

So, I don't believe signal strength is an issue.

connected with HumptyDumpty, channel 6
dhcp client start...
ip:192.168.1.250,mask:255.255.255.0,gw:192.168.1.1
switch to channel 1
bcn_timout,ap_probe_send_start
ap_probe_send over, rest wifi status to disassoc
state: 5 -> 0 (1)
rm 0
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 33
cnt

connected with HumptyDumpty, channel 6
dhcp client start...
ip:192.168.1.250,mask:255.255.255.0,gw:192.168.1.1
switch to channel 1
bcn_timout,ap_probe_send_start
ap_probe_send over, rest wifi status to disassoc
state: 5 -> 0 (1)
rm 0
scandone
no HumptyDumpty found, reconnect after 1s
reconnect
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 26
cnt

connected with HumptyDumpty, channel 6
dhcp client start...
ip:192.168.1.250,mask:255.255.255.0,gw:192.168.1.1
switch to channel 1
bcn_timout,ap_probe_send_start
pm open,type:2 0
ap_probe_send over, rest wifi status to disassoc
state: 5 -> 0 (1)
rm 0
pm close 7
scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 25
cnt

@castrofernando
Copy link

I'd like to see this response too. I'm also facing same problem. There are routers that it connect perfectly and other simply never connect.

@TD-er
Copy link
Contributor

TD-er commented Jul 18, 2023

Try forcing the ESP to only use 802.11g

Make sure the router/access point allows clients to connect in "g" mode and thus not set to be "N-only".

@asturcon3
Copy link

Same here. 321 esp's in 50 locations country-wide, each with a random ISP provided router and well, that makes live interesting. Usually a random NONOSDK version makes the trick. On some sites it was impossible, I had to send them a cheap 2.4 AP to make it work.
Of course, every of those routers have exactly 0 issues with any random smartphone or wifi camera my customer has.
BTW, my code cycles phy-mode. That's not the problem.

@TD-er
Copy link
Contributor

TD-er commented Jul 18, 2023

There are other tricks you can try:

  • Add delay(1000); right after a call to WiFi.begin()
  • Enable WiFi.setAutoConnect(...) and/or WiFi.setAutoReconnect(...)
  • Add delay(100); right after each WiFi command you call which might do something to the WiFi radio (e.g. set mode, etc)
  • Explicitly call WiFi.disconnect(); before WiFi.begin();
  • Force 802.11g as I mentioned.

@wibbit
Copy link
Author

wibbit commented Aug 11, 2023

So, for me, updating the code to include the delay(1000) right after WiFi.begin() appears to result in a reliable connection each time.

@wibbit
Copy link
Author

wibbit commented Aug 14, 2023

This may not be the right place, but could anyone perhaps point me in the right direction of adding the delay when using WifiManager?

@php4fan
Copy link

php4fan commented Dec 27, 2023

So, for me, updating the code to include the delay(1000)
right after WiFi.begin() appears to result in a reliable connection each time.

@wibbit can you confirm (now that some time has passed) that this workaround actually worked for you?

I mean, that it wasn't just a coincidence and then the issue reappeared later?

@TD-er what is the rationale behind such a workaround? I mean, in the original code without the workaround, there's a loop with many delays anyway, so it's hard to understand how an additional initial delay can make a difference. Does it have to do with not calling status() immediately after begin()?

@TD-er
Copy link
Contributor

TD-er commented Dec 27, 2023

I've noticed that whenever you make a call to a function in the WiFi class which actually does something to the hardware, it may not be done yet when the function returns.
Either the WiFi radio isn't actually stable yet or immediately doing something else may demand too much from the (often poorly designed) power supply on most boards.
Also a lot of stuff is done when calling delay() like processing incoming data, maintaining WiFi connections, processing events, etc.
To illustrate this last claim, you can try running some blocking code which takes > 100 msec which isn't somehow calling delay() or yield() and you will see your WiFi connection is much less reliable.

Anyway, by adding some delay() calls after each WiFi call that actually does interact with the hardware, you will see things go a lot more smoothly.

On some access points you may even need to have automatic reconnect enabled and do like a delay(1000) right after WiFi.begin() to make sure the SDK code has ample opportunity to act on quick disconnects and do a quick reconnect.
I've mainly seen this on Fritzbox, but I doubt it is limited to those.

If I'm not mistaken, MikroTik also uses something similar when using hidden SSID.
At least you should try to connect to those using explicitly the BSSID and channel and cannot try to connect to them the usual way with just the SSID name and password.

Lots of newer APs also try to steer you away to another band or to another access point. But when you force 802.11g on the ESP and don't allow 802.11n (on the ESP), those quick disconnects are no longer attempted by those access points.

@php4fan
Copy link

php4fan commented Dec 27, 2023

@TD-er ok but consider the code without adding the delay(1000):

WiFi.begin("HumptyDumpty", "Not_A_Real_SSID_for_me_at_least");

Serial.print("Connecting");
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}

Note it already has lots of delay()s.

According to your explanation of how delay() helps, how can all those delays in the loop not already do the trick?

The only difference in adding a single delay(1000) immediately after begin() is that the delay goes between begin() and the first call to status().
Even assuming a lack of delay there might negatively affect the first call to status() somehow, things should become the exact same after the first iteration of the loop, right?

@TD-er
Copy link
Contributor

TD-er commented Dec 27, 2023

It is like you're doing this:

WiFi.begin("HumptyDumpty", "Not_A_Real_SSID_for_me_at_least");
Serial.print("Connecting");
do 
{
  delay(500);
  Serial.print(".");
} while (WiFi.status() != WL_CONNECTED);

With the exception that Serial.print() may also cause different behavior.

But I would even go a bit further and do something like this:

WiFi.setMode(WIFI_STA);
delay(100);
WiFi.disconnect();
delay(100);
WiFi.begin("HumptyDumpty", "Not_A_Real_SSID_for_me_at_least");
Serial.print("Connecting");
do 
{
  delay(500);
  Serial.print(".");
} while (WiFi.status() != WL_CONNECTED);

@php4fan
Copy link

php4fan commented Dec 27, 2023

WiFi.disconnect();

I already do:

WiFi.persistent(false);
WiFi.mode(WIFI_OFF);

before WiFi.setMode(WIFI_STA).

If after that, a disconnect() before begin() makes any difference whatsoever, that would certainly be a bug in itself.

@TD-er
Copy link
Contributor

TD-er commented Dec 27, 2023

If after that, a disconnect() before begin() makes any difference whatsoever, that would certainly be a bug in itself.

Well there is one thing you can be sure of and that's that there are bugs in the closed source WiFi code.
So don't make assumptions based on "nah that wouldn't make sense" when thinking about ESP WiFi code.

@sawyersteven
Copy link

I'm not sure I have much to contribute, but I have been having wifi connection problems on my 8266 (wemos d1 mini) that I haven't been able to sort out either. This board will sometimes connect instantly, other times it may take 20-30 seconds, and other times it takes long enough that I give up. It seems that once it connects to my network it is stable enough, though I haven't left this board on for extended periods of time.

No amount of delays seems to make a difference, or any other changes to the basic wifi connection example.

My main router is an Asus AX3000, but I also tried connecting to an old D-Link 820L I had in my closet to no avail.

An interesting note is that I was playing around with MicroPython and found that it reliably connects to my home wifi within several seconds of starting up. I'm not well-versed in c/cpp but a quick look through the micropython source shows a very similar method of starting the wifi connection.

I have tried this on two D1 minis and both show the same wifi inconsistency.

@asturcon3
Copy link

Feedback here...

362 active esp's, 24/7 in 56 locations, random AP's. Much better now after throwing some delays (c) Td-er

But, I didn't notice any change when playing with persistent, setAutoConnect, setAutoReconnect (I'm using true) or disconnect before begin (I'm not using it). It was all delay related.

My guess is that after connecting to the AP and getting a valid IP, WiFi.status reports connected, but it's still doing its things (ie DNS), so it needs a delay AFTER the connection has been set.

@TD-er
Copy link
Contributor

TD-er commented Dec 28, 2023

Yep, adding a delay will make things a lot faster with WiFi :)

@sawyersteven
Copy link

Yep, adding a delay will make things a lot faster with WiFi :)

How much delay do you use? A delay of 3000ms after WiFi.begin() is insufficient to reliably connect to my network. I want to postpone the main loop as little as possible.

@TD-er
Copy link
Contributor

TD-er commented Dec 28, 2023

Yep, adding a delay will make things a lot faster with WiFi :)

How much delay do you use? A delay of 3000ms after WiFi.begin() is insufficient to reliably connect to my network. I want to postpone the main loop as little as possible.

Just waiting 3 sec is absolutely useless.
Like I said before as a rule of thumb, just add 100 msec delay after each WiFi call which actually does something to the hardware and you can set it to 1000 msec right after calling WiFi.begin().
Just as I wrote here: #8950 (comment)

@asturcon3
Copy link

I miss the delay AFTER the while

@sawyersteven
Copy link

Yep, adding a delay will make things a lot faster with WiFi :)

How much delay do you use? A delay of 3000ms after WiFi.begin() is insufficient to reliably connect to my network. I want to postpone the main loop as little as possible.

Just waiting 3 sec is absolutely useless. Like I said before as a rule of thumb, just add 100 msec delay after each WiFi call which actually does something to the hardware and you can set it to 1000 msec right after calling WiFi.begin(). Just as I wrote here: #8950 (comment)

A delay of up to 750ms after any call to the WiFi library does not result in a consistent and timely connection to the network in my testing.

Either all of my hardware has a defect (possible that they were all from the same manufacturing batch), or the 8266 wifi library is inefficient. Unfortunately I don't have enough knowledge of the ecosystem to narrow this down farther.

@TD-er
Copy link
Contributor

TD-er commented Dec 29, 2023

I have seen some boards which have really badly tuned WiFi antennas.
When using a really old Arduino core for ESP8266 (e.g. 2.3.x or older) those boards may sometimes work just fine while newer core lib versions are hardly able to establish a connection.
I think older core versions could allow for a wider range of tuning parameters to adapt for badly tuned antennas.

On such boards you might sometimes get better results when pressing hard with your thumb on the antenna.

Another cause for bad WiFi is the power supply.
Quite a lot of boards have really poor power supplies, or extremely thin copper traces on the PCB or not sufficiently large capacitors.

TL;DR
Bad hardware will never result in good performing boards.

@sawyersteven
Copy link

@wibbit If you haven't gotten this sorted out try reverting to an older version of the 8266 board library in the Arduino ide. I found that 2.5.2 made my wifi connection much more reliable. I had to revert back to 2.4.2 in order to get mDNS to work for me.

Depending on what other libraries you use this might be a problem and cause a cascade of reverting to previous versions, but it made my d1 mini useable again.

@wibbit
Copy link
Author

wibbit commented Jan 3, 2024

So, for me, updating the code to include the delay(1000)
right after WiFi.begin() appears to result in a reliable connection each time.

@wibbit can you confirm (now that some time has passed) that this workaround actually worked for you?

Unfortunately the project I was using was making use of the WifiManager codebase, and though I could get the above to work reliably in isolated testing, for the life of me I couldn't work out how to get the delay passed through to the underlying wifi code.

I ended up using a wired ethernet option that the project I was playing with also supported.

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

6 participants