Environment
- ESP-IDF v5.5.4, target esp32s3
- Board: Waveshare ESP32-S3-Touch-LCD-1.9 (
WS19Touch variant)
- App version 2.0.3.2
What happens
In a network where several access points share one SSID — a mesh, or just two
APs with the same name — the controller regularly ends up on a weak AP while a
much stronger one is in range. It then stays there.
Why
wifi_config.c builds the station config with only the auth mode set:
wifi_config_t wifi_config = {
.sta = {
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
},
};
Every other field is therefore zero, and for scan_method the zero value is
WIFI_FAST_SCAN. From esp_wifi_types_generic.h:
typedef enum {
WIFI_FAST_SCAN = 0, /**< Do fast scan, scan will end after find SSID match AP */
WIFI_ALL_CHANNEL_SCAN, /**< All channel scan, scan will end after scan all the channel */
} wifi_scan_method_t;
The scan stops at the first matching AP, so whichever one answers first
wins, regardless of signal strength.
The sort order is not the problem — sort_method is zero too, and that is
WIFI_CONNECT_AP_BY_SIGNAL, which is exactly what you want. It simply never has
anything left to sort, because the fast scan already stopped.
Suggested fix — one line
wifi_config_t wifi_config = {
.sta = {
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
.scan_method = WIFI_ALL_CHANNEL_SCAN,
},
};
What it costs
An all-channel scan runs at most WIFI_ACTIVE_SCAN_MAX_DEFAULT_TIME (120 ms)
per channel. On 2.4 GHz with 13 channels that is ~1.6 s worst case, once per
connect. With a single AP the result is the same as before, only slower to get
there — that is the trade-off, and it may be worth making it a Kconfig option
rather than the default if boot time matters to you.
A bonus that comes with it
failure_retry_cnt (retries at one AP before moving to the next) is documented
in the same header as only working with WIFI_ALL_CHANNEL_SCAN. It is currently
unusable for that reason.
What this does not fix
Only the choice made while connecting. Once associated, the station stays on
that AP until the link drops, however bad it gets. Steering by the AP would need
802.11k/v (CONFIG_ESP_WIFI_11KV_SUPPORT), which is not enabled in the current
sdkconfigs — that is a separate and much bigger decision.
Verified on hardware
Built and flashed on 2026-08-05 on the board above. Before the change the
controller regularly associated with a weak AP in a mesh; with
WIFI_ALL_CHANNEL_SCAN it picks the strongest one. Connection setup still works
normally, and the image does not grow — scan_method is an initialiser value,
not extra code.
What was not measured is throughput, and it should not be expected to change:
this affects which AP gets chosen at association time, not the speed of a
connection that is already up.
Environment
WS19Touchvariant)What happens
In a network where several access points share one SSID — a mesh, or just two
APs with the same name — the controller regularly ends up on a weak AP while a
much stronger one is in range. It then stays there.
Why
wifi_config.cbuilds the station config with only the auth mode set:Every other field is therefore zero, and for
scan_methodthe zero value isWIFI_FAST_SCAN. Fromesp_wifi_types_generic.h:The scan stops at the first matching AP, so whichever one answers first
wins, regardless of signal strength.
The sort order is not the problem —
sort_methodis zero too, and that isWIFI_CONNECT_AP_BY_SIGNAL, which is exactly what you want. It simply never hasanything left to sort, because the fast scan already stopped.
Suggested fix — one line
What it costs
An all-channel scan runs at most
WIFI_ACTIVE_SCAN_MAX_DEFAULT_TIME(120 ms)per channel. On 2.4 GHz with 13 channels that is ~1.6 s worst case, once per
connect. With a single AP the result is the same as before, only slower to get
there — that is the trade-off, and it may be worth making it a Kconfig option
rather than the default if boot time matters to you.
A bonus that comes with it
failure_retry_cnt(retries at one AP before moving to the next) is documentedin the same header as only working with
WIFI_ALL_CHANNEL_SCAN. It is currentlyunusable for that reason.
What this does not fix
Only the choice made while connecting. Once associated, the station stays on
that AP until the link drops, however bad it gets. Steering by the AP would need
802.11k/v (
CONFIG_ESP_WIFI_11KV_SUPPORT), which is not enabled in the currentsdkconfigs — that is a separate and much bigger decision.
Verified on hardware
Built and flashed on 2026-08-05 on the board above. Before the change the
controller regularly associated with a weak AP in a mesh; with
WIFI_ALL_CHANNEL_SCANit picks the strongest one. Connection setup still worksnormally, and the image does not grow —
scan_methodis an initialiser value,not extra code.
What was not measured is throughput, and it should not be expected to change:
this affects which AP gets chosen at association time, not the speed of a
connection that is already up.