I'm using Arduino IDE(2.3.5) ESP8266 (3.1.2) and ESPAsyncWebServer (3.7.4), ESPAsyncTCP(2.0.0). I need to wifi scan the network an print the result of my web interface. If I use WiFiScanNetworks(), ESP8266 is Soft WDT reset. The same thing happens when I use yield(). My test code is as follows
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
// Create AsyncWebServer object on port 80
AsyncWebServer web_server(80);
// Replace with your network credentials
const char* ssid = "your SSID";
const char* password = "your Password";
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>ESPAsyncWebServer</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
</head>
<body>
<h2>ESPAsyncWebServer</h2>
<h4>Use 'WiFi.scanNetworks();' or 'yield();' Soft WDT reset</h4>
<input type="button" onclick="location.href='/test_scan';" value="Test Scan" />
<input type="button" onclick="location.href='/test_yield';" value="Test yield" />
<input type="button" onclick="location.href='/test_normal';" value="Test normal" />
</body>
</html>
)rawliteral";
void setup(){
Serial.begin(115200);
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
web_server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html);
});
web_server.on("/test_scan", HTTP_GET, [](AsyncWebServerRequest *request){
int n = WiFi.scanNetworks();
//String value = "Total : " + String(n) + " networks found.";
request->send(200, "text/plain", "Test WiFi Scannetworks() PASS");
});
web_server.on("/test_yield", HTTP_GET, [](AsyncWebServerRequest *request){
yield();
request->send(200, "text/plain", "Test yield() PASS");
});
web_server.on("/test_normal", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "Test normal PASS");
});
web_server.begin();
}
void loop() {
}
-
what is your question? ... please edit your post ... add a question ... do not write a question in a commentjsotola– jsotola04/06/2025 18:18:53Commented Apr 6 at 18:18
2 Answers 2
You're doing too much in one request callback from the web server and you're calling yield()
in another, which is not allowed.
web_server.on("/test_scan", HTTP_GET, [](AsyncWebServerRequest *request){
int n = WiFi.scanNetworks();
//String value = "Total : " + String(n) + " networks found.";
request->send(200, "text/plain", "Test WiFi Scannetworks() PASS");
});
web_server.on("/test_yield", HTTP_GET, [](AsyncWebServerRequest *request){
yield();
request->send(200, "text/plain", "Test yield() PASS");
});
The documentation for ESPAsyncWebServer is clear about yield()
:
You can not use yield or delay or any function that uses them inside the callbacks
The call to yield()
is pointless unless you want to crash your program, so delete it.
You can't know whether WiFi.scanNetworks()
calls yield()
or delay()
. Even if it is safe now, it might not be safe in an update. So you shouldn't be calling it.
Instead use a boolean variable as a flag, set it to indicate that you need to start scanning wifi networks, and then in loop()
inspect it, if it's true, call WiFi.scanNetworks()
and set it to false.
-
Thanks @romkey. When I use WebServer my code works. When I use AsyncWebServer my ESP8266 crashes. yield() is added to the code to show that the crash is not related to the processing time. As you said; it is pointless to use it. I can only do what you said using websocket. I am looking for a way to do this without using websocket. Can you give me an example that does not use websocket?Seafox– Seafox04/06/2025 23:40:30Commented Apr 6 at 23:40
-
I explained why it crashes. I don't understand what you mean by needing web sockets. You don't need to do that. The crash is caused because of the
yield()
call. You can't use eitherWiFi.scanNetworks()
oryield()
in the callbacks. Restructure your code to not use them.romkey– romkey04/07/2025 01:01:21Commented Apr 7 at 1:01
Thanks again @romkey. The documentation for ESPAsyncWebServer shows an example for scanNetworks. As stated in the documentation, scanNetworks cannot find a network in the first scan. Therefore, I did the first scan under Setup. For those who have problems, the working example is as follows.
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
// Create AsyncWebServer object on port 80
AsyncWebServer web_server(80);
// Replace with your network credentials
const char* ssid = "your SSID";
const char* password = "your Password";
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>ESPAsyncWebServer</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
</head>
<body>
<h2>ESPAsyncWebServer</h2>
<h4>Use 'WiFi.scanNetworks();' or 'yield();' Soft WDT reset</h4>
<input type="button" onclick="location.href='/test_scan';" value="Test Scan" />
<input type="button" onclick="location.href='/test_scan2';" value="Test Scan PASS" />
<input type="button" onclick="location.href='/test_yield';" value="Test yield" />
<input type="button" onclick="location.href='/test_normal';" value="Test normal" />
</body>
</html>
)rawliteral";
void setup(){
Serial.begin(115200);
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print ESP Local IP Address
Serial.println(WiFi.localIP());
//First scan
int n = WiFi.scanNetworks();
// Route for root / web page
web_server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html);
});
web_server.on("/test_scan", HTTP_GET, [](AsyncWebServerRequest *request){
int n = WiFi.scanNetworks();
//String value = "Total : " + String(n) + " networks found.";
request->send(200, "text/plain", "Test WiFi Scannetworks() PASS");
});
web_server.on("/test_scan2", HTTP_GET, [](AsyncWebServerRequest *request){
String json = "[";
int n = WiFi.scanComplete();
if(n == -2){
WiFi.scanNetworks(true);
} else if(n){
for (int i = 0; i < n; ++i){
if(i) json += ",";
json += "{";
json += "\"rssi\":"+String(WiFi.RSSI(i));
json += ",\"ssid\":\""+WiFi.SSID(i)+"\"";
json += ",\"bssid\":\""+WiFi.BSSIDstr(i)+"\"";
json += ",\"channel\":"+String(WiFi.channel(i));
json += ",\"secure\":"+String(WiFi.encryptionType(i));
json += ",\"hidden\":"+String(WiFi.isHidden(i)?"true":"false");
json += "}";
}
WiFi.scanDelete();
if(WiFi.scanComplete() == -2){
WiFi.scanNetworks(true);
}
}
json += "]";
request->send(200, "application/json", json);
json = String();
});
web_server.on("/test_yield", HTTP_GET, [](AsyncWebServerRequest *request){
yield();
request->send(200, "text/plain", "Test yield() PASS");
});
web_server.on("/test_normal", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", "Test normal PASS");
});
web_server.begin();
}
void loop() {
}