-
Notifications
You must be signed in to change notification settings - Fork 7.6k
ESP32 AP+STA and scanNetworks fails if STA not connected #8916
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
Comments
@astrogene1000 - I have tested this sketch using Arduino 2.0.14. It works fine. #include "WiFi.h"
const char* ssid = "YOUR_SSID"; // Change this to your WiFi SSID
const char* password = "YOUR_PASSWORD"; // Change this to your WiFi password
const char* host = "google.com"; // This should not be changed
const int httpPort = 80; // This should not be changed
const char *soft_ap_ssid = "MyESP32AP";
const char *soft_ap_password = "12345678";
void readResponse(WiFiClient *client) {
unsigned long timeout = millis();
while (client->available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client->stop();
return;
}
}
// Read all the lines of the reply from server and print them to Serial
while (client->available()) {
String line = client->readStringUntil('\r');
Serial.print(line);
}
Serial.printf("\nClosing connection\n\n");
}
void connectWiFi()
{
// We start by connecting to a WiFi network
Serial.println();
Serial.println("******************************************************");
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println();
Serial.println("******************************************************");
}
void setup()
{
Serial.begin(115200);
delay(100);
// Start mode AP+STA with default IP
// Start mode AP
Serial.println("\n++++++++++++++\nStarting AP Mode\n++++++++++++++\n");
WiFi.mode(WIFI_MODE_APSTA);
WiFi.softAP(soft_ap_ssid, soft_ap_password);
Serial.print("ESP32 IP as soft AP: ");
Serial.println(WiFi.softAPIP());
Serial.println();
// Start Connection using STA mode
Serial.println("\n++++++++++++++\nStarting STA Mode\n++++++++++++++\n");
connectWiFi();
Serial.println("Setup [issue 8916] done");
}
void loop()
{
Serial.println("Scan start");
// WiFi.scanNetworks will return the number of networks found.
int n = WiFi.scanNetworks();
Serial.println("Scan done");
if (n == 0) {
Serial.println("no networks found");
} else {
Serial.print(n);
Serial.println(" networks found");
Serial.println("Nr | SSID | RSSI | CH | Encryption");
for (int i = 0; i < n; ++i) {
// Print SSID and RSSI for each network found
Serial.printf("%2d", i + 1);
Serial.print(" | ");
Serial.printf("%-32.32s", WiFi.SSID(i).c_str());
Serial.print(" | ");
Serial.printf("%4ld", WiFi.RSSI(i));
Serial.print(" | ");
Serial.printf("%2ld", WiFi.channel(i));
Serial.print(" | ");
switch (WiFi.encryptionType(i))
{
case WIFI_AUTH_OPEN:
Serial.print("open");
break;
case WIFI_AUTH_WEP:
Serial.print("WEP");
break;
case WIFI_AUTH_WPA_PSK:
Serial.print("WPA");
break;
case WIFI_AUTH_WPA2_PSK:
Serial.print("WPA2");
break;
case WIFI_AUTH_WPA_WPA2_PSK:
Serial.print("WPA+WPA2");
break;
case WIFI_AUTH_WPA2_ENTERPRISE:
Serial.print("WPA2-EAP");
break;
case WIFI_AUTH_WPA3_PSK:
Serial.print("WPA3");
break;
case WIFI_AUTH_WPA2_WPA3_PSK:
Serial.print("WPA2+WPA3");
break;
case WIFI_AUTH_WAPI_PSK:
Serial.print("WAPI");
break;
default:
Serial.print("unknown");
}
Serial.println();
delay(10);
}
}
Serial.println("");
// Delete the scan result to free memory for code below.
WiFi.scanDelete();
// Connecting to HOST ...
Serial.println();
Serial.println("******************************************************");
if (WiFi.status() == WL_CONNECTED) {
Serial.printf("WiFi still connected to [%s]. Reading Host [%s]\n\n=============\n", ssid, host);
WiFiClient client;
String footer = String(" HTTP/1.1\r\n Connection: close\r\n\r\n");
// WRITE --------------------------------------------------------------------------------------------
if (!client.connect(host, httpPort)) {
return;
}
// READ ---------------------------------------------------------------------------------------------
client.print("GET /" + footer);
readResponse(&client);
Serial.println("=============");
} else {
Serial.printf("WiFi is **disconnected** from [%s]!\n", ssid);
}
Serial.println();
Serial.println("******************************************************");
// Wait a bit before scanning // reading Host again.
delay(5000);
} |
If I comment out the |
@astrogene1000 I'm not surprised that you can't scan while the ESP32 is trying to connect to STA. The connection attempt ties up the radio, so any scan will fail.
That is also expected. As far as I know, the only way to stop the STA connection attempt is to turn off the WiFi radio. As you have noted, that will also stop the AP mode used for setup. In 2.0.9 running an SSID scan while in AP mode also temporarily disrupts the AP connection. I believe this is a limitation of the hardware. Here's the approach I use for my firmware:
These limitations aren't unique to the ESP32. I had the same challenges when using a Zentri AMW106 radio. |
Thanks for the responses! @mrengineer7777 I do have a fallback in my use case because the user can still connect to devices AP and user could configure a known local external AP and reset or could configure as no external AP and reset then execute scan after the reset's. I have had good luck running both AP+STA except for this scan issue and have multiple web interfaces into both device control and business logic, reason I need to keep the devices local AP functional at all times. Thanks again, Gene |
In my testing, or I can connect and that loop exits or it is never called by commenting it out. In other words, when it connects to the AP in STA mode, I can scan the WiFi. |
Let me also test it when failing after a timeout... |
@astrogene1000 - Yes, I could reproduce the issue now. I changed the void connectWiFi()
{
// We start by connecting to a WiFi network
Serial.println();
Serial.println("******************************************************");
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
int tries = 10;
while (WiFi.status() != WL_CONNECTED && tries) {
delay(500);
Serial.print(".");
tries--;
}
if (!tries) {
Serial.printf("\n===>It couldn't connect to the AP using SSID %s\n", ssid);
} else {
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println();
Serial.println("******************************************************");
}
}
` |
@astrogene1000 - I got it to work by adding a void connectWiFi()
{
// We start by connecting to a WiFi network
Serial.println();
Serial.println("******************************************************");
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
int tries = 10;
while (WiFi.status() != WL_CONNECTED && tries) {
delay(500);
Serial.print(".");
tries--;
}
if (!tries) {
Serial.printf("\n===>It couldn't connect to the AP using SSID %s\n", ssid);
WiFi.disconnect(false); // <<<<<<<<<<<<<<================ This allow it to scan WiFi
} else {
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println();
Serial.println("******************************************************");
}
} |
Thanks @SuGlider for confirming the disconnect kicks it out and lets things scan! Gene |
Good to know that the issue is finally solved. |
@astrogene1000 @SuGlider if (WiFi.status() == WL_CONNECTED) { |
Board
PICO-D4 and Devkit 3
Device Description
None
Hardware Configuration
None
Version
v2.0.14
IDE Name
Arduino IDE
Operating System
W11
Flash frequency
80
PSRAM enabled
yes
Upload speed
115200
Description
I have a build that always presents an Access point.
There is a need for also for connecting to a STA whose info the user enters via a web interface.
The issue is if the STA is not connected (which is possible as device may move to another physical area and need to connect to a different network) then while in main application if a scanNetworks is done it -always- returns a -2 (WIFI_SCAN_FAILED) basically immediately.
If a scanNetworks is done and the device is connected to a STA then works as expected.
If a scanNetworks is done prior to attempting to connect to the (non-existent) AP then it works as expected.
This is what I see as far as response time to scan
start_time = esp_timer_get_time();
numnets = WiFi.scanNetworks();
total_time = esp_timer_get_time() - start_time;
Serial.println(total_time);
total_time for scan prints out as 307/255/287 for three subsequent tries when not able to connected to
configured access point.
Here is what I see if successfully connected to an AP
total_time prints out as 7238971/8131168/8779417
For seeing 61, 66 and 59 unique external access points.
I believe the err is kick from this call in WiFiScan.cpp
if(esp_wifi_scan_start(&config, false) == ESP_OK) {
Based on this thread
espressif/esp-idf#11437
ESP_OK: succeed
ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init
ESP_ERR_WIFI_NOT_STARTED: WiFi was not started by esp_wifi_start
ESP_ERR_WIFI_TIMEOUT: blocking scan is timeout
ESP_ERR_WIFI_STATE: wifi still connecting when invoke esp_wifi_scan_start
others: refer to error code in esp_err.h
esp_err_t esp_wifi_scan_start(const wifi_scan_config_t *config, bool block);
Which is getting back a "ESP_ERR_WIFI_STATE: wifi still connecting" and scanNetworks returns it as a generic failure.
Question, how to get around this issue?
Can I shutdown the attempts to connect to the non-existent AP
I cannot stop then restart the whole wifi subsystem as that would drop the connection to the internal AP of the esp32.
Thoughts?
Thanks!
Gene
Sketch
Debug Message
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide
The text was updated successfully, but these errors were encountered: