1

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() {
 
 }
Rohit Gupta
6122 gold badges5 silver badges18 bronze badges
asked Apr 6 at 16:11
1
  • what is your question? ... please edit your post ... add a question ... do not write a question in a comment Commented Apr 6 at 18:18

2 Answers 2

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.

answered Apr 6 at 20:20
2
  • 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? Commented 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 either WiFi.scanNetworks() or yield() in the callbacks. Restructure your code to not use them. Commented Apr 7 at 1:01
0

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() {
}
answered Apr 7 at 0:57

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.