tzapu / WiFiManager

ESP8266 WiFi Connection manager with web captive portal
http://tzapu.com/esp8266-wifi-connection-manager-library-arduino-ide/
MIT License
6.64k stars 1.98k forks source link

configportal - softAPdisconnect FAILED and AsyncTCP.cpp:1268] begin(): bind error: -8 #1266

Open bmoniey opened 3 years ago

bmoniey commented 3 years ago

Basic Infos

Hardware

WiFimanager Branch/Release: Master

Esp32:

Hardware: esp32doit-devkit-v1

Core Version: Espressif 32 (3.2.1) > DOIT ESP32 DEVKIT V1

Description

Problem description

I am trying to us wifi manager and ESPAsyncWebServer I would like to start the AsyncWebServer after exiting from AP portal.

The AsyncWebServer works OK if there are saved credentials which allow a connection without using a portal.

When a portal is needed the WiFi Manager seems to leave its server behind without unbinding from port 80.

When my AsyncWebServer tries to bind to port 80 it fails.

I see that the shutdownConfigPortal() is not succesful.

Settings in IDE

Module: DOIT ESP32 DEVKIT V1

Additional libraries:

using platform io

[env:esp32doit-devkit-v1] platform = espressif32 board = esp32doit-devkit-v1 framework = arduino

lib_deps = https://github.com/tzapu/WiFiManager.git https://github.com/me-no-dev/ESPAsyncWebServer.git https://github.com/lorol/LITTLEFS.git ESPmDNS

extra_scripts = replace_fs.py upload_port = COM24 monitor_port = COM24 monitor_speed = 115200 debug_tool = esp-prog debug_init_break = tbreak setup

Sketch

include

include // https://github.com/tzapu/WiFiManager

include

include

include

include

include

AsyncWebServer server(80);

void setup_fs(); void setup_wifi(); void setup_server();

void setup(){ // put your setup code here, to run once: Serial.begin(115200); delay(200); setup_fs(); setup_wifi(); setup_server(); }

void loop() { // put your main code here, to run repeatedly:

}

void setup_wifi() { // WiFi.mode(WiFi_STA); // it is a good practice to make sure your code sets wifi mode how you want it. WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP

//WiFiManager, Local intialization. Once its business is done, there is no need to keep it around WiFiManager wm;

//reset settings - wipe credentials for testing
wm.resetSettings();

// Automatically connect using saved credentials,
// if connection fails, it starts an access point with the specified name ( "AutoConnectAP"),
// if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect())
// then goes into a blocking loop awaiting configuration and will return success result

bool res;
// res = wm.autoConnect(); // auto generated AP name from chipid
// res = wm.autoConnect("AutoConnectAP"); // anonymous ap
res = wm.autoConnect("AutoConnectAP","password"); // password protected ap

if(!res) {
    Serial.println("Failed to connect");
    // ESP.restart();
} 
else {
    //if you get here you have connected to the WiFi    
    Serial.println("connected...yeey :)");
}

//setup mdns Serial.println("Starting mDNS"); if(!MDNS.begin("esp32")) { Serial.println("Error starting mDNS"); } }

void notFound(AsyncWebServerRequest *request) { request->send(404, "text/plain", "Not found"); }

void setup_server(){ Serial.println("Starting web server..."); server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ //readFile(LITTLEFS,"/index.html"); request->send(LITTLEFS, "/index.html", String(), false); });

server.on("/mango.png", HTTP_GET, [](AsyncWebServerRequest request){ request->send(LITTLEFS, "/mango.png", "image/png"); }); server.on("/apple.png", HTTP_GET, [](AsyncWebServerRequest request){ request->send(LITTLEFS, "/apple.png", "image/png"); }); server.on("/banana.png", HTTP_GET, [](AsyncWebServerRequest request){ request->send(LITTLEFS, "/banana.png", "image/png"); }); server.on("/grape.png", HTTP_GET, [](AsyncWebServerRequest request){ request->send(LITTLEFS, "/grape.png", "image/png"); }); server.on("/strawberry.png", HTTP_GET, [](AsyncWebServerRequest request){ request->send(LITTLEFS, "/strawberry.png", "image/png"); }); server.on("/orange.png", HTTP_GET, [](AsyncWebServerRequest request){ request->send(LITTLEFS, "/orange.png", "image/png"); });

// Route to load style.css file

server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(LITTLEFS, "/style.css", "text/css"); });

 // Route to load scripts.js file

server.on("/scripts.js", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(LITTLEFS, "/scripts.js", "text/js"); });

server.onNotFound(notFound); server.begin(); }

void setup_fs(){ Serial.println("Mounting file system\n"); if(!LITTLEFS.begin()){ Serial.println("An Error has occurred while mounting LITTLEFS"); return; } }

Debug Messages

Mounting file system

wm:[1] resetSettings wm:[1] SETTINGS ERASED wm:[1] AutoConnect wm:[1] No Credentials are Saved, skipping connect wm:[2] Starting Config Portal wm:[2] AccessPoint set password is VALID wm:[2] Disabling STA wm:[2] Enabling AP wm:[1] StartAP with SSID: AutoConnectAP wm:[1] AP IP address: 192.168.4.1 wm:[1] Starting Web Portal wm:[2] HTTP server started wm:[2] Config Portal Running, blocking, waiting for clients... wm:[2] NUM CLIENTS: 1 wm:[2] <- HTTP Root wm:[2] <- HTTP Wifi wm:[2] WiFi Scan SYNC started wm:[2] WiFi Scan completed in 5320 ms wm:[1] 9 networks found wm:[2] DUP AP: Eisenmont wm:[2] DUP AP: Eisenmont wm:[2] DUP AP: Dankushome wm:[2] AP: -78 Eisenmont wm:[2] AP: -80 SINGLE_SPEED24 wm:[2] AP: -85 MORAN-Network wm:[2] AP: -86 Dankushome wm:[2] AP: -88 SETUP-D5A7 wm:[2] AP: -92 Asher wm:[2] <- HTTP Root wm:[2] <- Request redirected to captive portal [E][WebServer.cpp:633] _handleRequest(): request handler not found wm:[2] <- Request redirected to captive portal wm:[2] <- HTTP Root wm:[2] <- HTTP Root [E][WebServer.cpp:633] _handleRequest(): request handler not found wm:[2] <- Request redirected to captive portal [E][WebServer.cpp:633] _handleRequest(): request handler not found wm:[2] <- Request redirected to captive portal wm:[2] <- HTTP Root wm:[2] <- HTTP Root wm:[2] NUM CLIENTS: 1 wm:[2] <- HTTP Root wm:[2] <- Request redirected to captive portal wm:[2] <- HTTP Root [E][WebServer.cpp:633] _handleRequest(): request handler not found wm:[2] <- Request redirected to captive portal wm:[2] <- HTTP Root wm:[2] <- HTTP WiFi save wm:[2] processing save wm:[2] Connecting as wifi client... wm:[2] setSTAConfig static ip not set, skipping wm:[1] Connecting to NEW AP: MORAN-Network wm:[1] connectTimeout not set, ESP waitForConnectResult... wm:[2] Connection result: WL_CONNECTED wm:[1] Connect to new AP [SUCCESS] wm:[1] Got IP Address: wm:[1] 192.168.1.111 wm:[2] shutdownConfigPortal wm:[0] [ERROR] disconnect configportal - softAPdisconnect FAILED wm:[2] restoring usermode STA wm:[2] wifi status: WL_CONNECTED wm:[2] wifi mode: STA wm:[2] configportal closed wm:[1] config portal exiting connected...yeey :) Starting mDNS Starting web server... [E][AsyncTCP.cpp:1268] begin(): bind error: -8

Zimbu98 commented 3 years ago

This is the only thing that I could do to solve the problem. (bmoniey helped me but I think we are both not happy with this workaround):

Sketch:

include // https://github.com/tzapu/WiFiManager

include

ifdef ESP32

include

include

elif defined(ESP8266)

include

include

endif

include

//AsyncWebServer server(80); AsyncWebServer server1(81);

const char* PARAM_MESSAGE = "message";

void notFound(AsyncWebServerRequest *request) { request->send(404, "text/plain", "Not found"); }

void setup() { WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP

// put your setup code here, to run once: Serial.begin(115200);

// WiFi.mode(WiFi_STA); // it is a good practice to make sure your code sets wifi mode how you want it.

//WiFiManager, Local intialization. Once its business is done, there is no need to keep it around WiFiManager wm;

//reset settings - wipe credentials for testing wm.resetSettings();

wm.setBreakAfterConfig(true); wm.setCleanConnect(true); // disconnect before connect, clean connect wm.setCountry("US");

// Automatically connect using saved credentials, // if connection fails, it starts an access point with the specified name ( "AutoConnectAP"), // if empty will auto generate SSID, if password is blank it will be anonymous AP (wm.autoConnect()) // then goes into a blocking loop awaiting configuration and will return success result

bool res; // res = wm.autoConnect(); // auto generated AP name from chipid // res = wm.autoConnect("AutoConnectAP"); // anonymous ap res = wm.autoConnect("AutoConnectAP","password"); // password protected ap

if(!res) { Serial.println("Failed to connect"); // ESP.restart(); } else { //if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");

}

Serial.print("IP Address: "); Serial.println(WiFi.localIP());

server1.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(200, "text/plain", "Hello, world"); });

// Send a GET request to /get?message= server1.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) { String message; if (request->hasParam(PARAM_MESSAGE)) { message = request->getParam(PARAM_MESSAGE)->value(); } else { message = "No message sent"; } request->send(200, "text/plain", "Hello, GET: " + message); });

// Send a POST request to /post with a form field message set to server1.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){ String message; if (request->hasParam(PARAM_MESSAGE, true)) { message = request->getParam(PARAM_MESSAGE, true)->value(); } else { message = "No message sent"; } request->send(200, "text/plain", "Hello, POST: " + message); });

server1.onNotFound(notFound);

server1.begin();

}

void loop() { // put your main code here, to run repeatedly:

}

This allows me to access the second webserver at http://192.168.0.30:81 while WifiManager still seems to hold onto port 80. Of course, a restart of the ESP will force WiFiManager to release port 80, but I did not want to require user to do that (because the user will forget this instruction then freak out when webserver doesn't work).