ESP32 AP模式获取WiFi凭证时出现Association超时错误求助
问题
我正在制作一个用于获取WiFi凭证的AP服务器,若等待约2分钟才连接AP或输入SSID与密码,会触发如下错误:
E (168130) wifi:Association refused temporarily, comeback time 268435 mSec
E (168130) wifi:Association comeback time (268435) mSec too long. max allowed 5000 mSec
E (168738) wifi:Association refused temporarily, comeback time 268435 mSec
E (168738) wifi:Association comeback time (268435) mSec too long. max allowed 5000 mSec
我输入的SSID与密码正确,但仍会出现该错误,再次输入相同信息却能成功连接。请问这是什么原因?
以下是我的完整代码(HTML部分过长已省略):
#include <WiFi.h> #include <WiFiClient.h> #include <WebServer.h> WebServer server(80); const char PAGE_MAIN[] PROGMEM = R"=====( html codes )====="; String page = PAGE_MAIN; // Convert const char[] to String boolean tryToConnect = true; const char* accessPointName = "accespoint"; const char* accessPointPassword = "accespointpassword"; char ssid[50]; char password[50]; String ssidlist = ""; void handleRoot() { server.send(200, "text/html", page); // Send the modified page } void handleSave() { String newSSID = server.arg("security"); String newPassword = server.arg("password"); tryToConnect = true; newSSID.toCharArray(ssid, sizeof(ssid)); newPassword.toCharArray(password, sizeof(password)); WiFi.disconnect(true); // Disconnect from the current network, forgetting it delay(100); Serial.println(ssid); Serial.println(password); WiFi.begin(ssid, password); Serial.print("Connecting..."); unsigned long startTime = millis(); while (WiFi.status() != WL_CONNECTED && tryToConnect) { delay(1000); Serial.print("."); if (millis() - startTime > 10000) { tryToConnect = false; Serial.println(""); String response = "<html><head><meta http-equiv='Content-Type' content='text/html;charset=utf-8'></head>"; response += "<body><h1>Wrong password, please try again</h1>"; response += "<a href='/'>Go back</a></body></html>"; server.send(200, "text/html", response); server.sendHeader("Location", "/", true); server.send(302, "text/plain", ""); } } if (WiFi.status() == WL_CONNECTED) { Serial.print("Connect, new IP address: "); Serial.println(WiFi.localIP()); String response = "<html><head><meta http-equiv='Content-Type' content='text/html;charset=utf-8'></head>"; response = "<body><h1>Password correct.</h1>"; server.send(200, "text/html", response); delay(5000); server.stop(); WiFi.softAPdisconnect(true); } } void wifiInit(){ WiFi.softAP(accessPointName, accessPointPassword); Serial.println("Access point started."); // 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"); for (int i = 0; i < n; ++i) { // Print SSID and RSSI for each network found //Serial.print(i + 1); //Serial.print(": "); //Serial.print(WiFi.SSID(i)); //Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*"); delay(10); ssidlist += WiFi.SSID(i) + ","; } } page.replace("--ssidlist--", ssidlist); // Perform the replace operation Serial.println(ssidlist); Serial.println(""); delay(2000); server.on("/", handleRoot); server.on("/save", handleSave); server.begin(); Serial.print("Access point ip adress "); Serial.println(WiFi.softAPIP()); } void setup() { Serial.begin(115200); while (!Serial) { ; } wifiInit(); } void loop() { server.handleClient(); }
原因分析
这个错误由ESP32 WiFi驱动的临时关联拒绝机制导致:
- 当设备长时间(如你这里的2分钟)处于AP模式未发起WiFi连接时,WiFi驱动内部会缓存无效的关联状态,或者目标AP可能因设备长时间无响应将其MAC地址临时加入黑名单。
- 首次尝试连接时,驱动读取到缓存的过长重试间隔(268435ms,远超允许的5000ms上限),直接拒绝连接请求。
- 再次输入信息时,
WiFi.disconnect(true)强制清除了部分缓存状态,重置了重试计时器,因此能正常连接。
解决方案
修改handleSave函数,在发起连接前彻底重置WiFi驱动状态,清除所有缓存的重试信息:
void handleSave() { String newSSID = server.arg("security"); String newPassword = server.arg("password"); tryToConnect = true; newSSID.toCharArray(ssid, sizeof(ssid)); newPassword.toCharArray(password, sizeof(password)); // 彻底重置WiFi状态:先关闭WiFi,再重新启用Station模式 WiFi.mode(WIFI_OFF); delay(100); WiFi.mode(WIFI_STA); delay(100); Serial.println(ssid); Serial.println(password); WiFi.begin(ssid, password); // 后续连接逻辑保持不变... }
另外,原代码中连续调用server.send(200)和server.send(302)会导致HTTP响应异常,建议保留302跳转即可:
if (millis() - startTime > 10000) { tryToConnect = false; Serial.println(""); server.sendHeader("Location", "/", true); server.send(302, "text/plain", "连接超时,请重试"); }
内容的提问来源于stack exchange,提问作者Tryingtogetsome
相关产品推荐
相关产品推荐

