ESP8266 AP配网模式下如何从configAP函数返回主循环loop
修复方案
核心问题定位
configAP()内部的while(true)是死循环,配网成功后无退出逻辑,永远无法返回主流程configAP()内重复定义了局部的configWebServer变量,覆盖了全局实例,导致配网完成后全局WebServer未初始化- 配网成功后未启动全局WebServer,和已有WiFi直连的逻辑不一致
具体修改点
1. 删去configAP内的局部WebServer定义
找到void configAP()开头的WiFiServer configWebServer(80);,直接删除这行,使用全局定义的WebServer实例即可。
2. 配网成功后添加退出逻辑
找到配网成功的分支代码,在分支末尾添加启动全局WebServer和退出函数的逻辑即可。
修改后完整的configAP函数参考
void configAP() { // 已删除重复定义的局部configWebServer,直接用全局实例 WiFi.mode(WIFI_AP_STA); WiFi.softAP(ssidh, password); Serial.print("Connect your computer to the WiFi network "); Serial.print(WiFi.softAPSSID()); Serial.println(); IPAddress ip = WiFi.softAPIP(); Serial.print("and enter http://"); Serial.print(ip); Serial.println(" in a Web browser"); configWebServer.begin(); while (true) { WiFiClient client = configWebServer.available(); if (client) { char line[64]; int l = client.readBytesUntil('\n', line, sizeof(line)); line[l] = 0; client.find((char*) "\r\n\r\n"); if (strncmp_P(line, PSTR("POST"), strlen("POST")) == 0) { l = client.readBytes(line, sizeof(line)); line[l] = 0; // 解析表单提交的WiFi参数 const char* delims = "=&"; strtok(line, delims); const char* ssid = strtok(NULL, delims); strtok(NULL, delims); const char* pass = strtok(NULL, delims); // 连接WiFi前先返回响应,避免SoftAP重置导致客户端断连无提示 client.println(F("HTTP/1.1 200 OK")); client.println(F("Connection: close")); client.println(F("Refresh: 10")); client.println(); client.println(F("<html><body><h3>Configuration AP</h3><br>connecting...</body></html>")); client.stop(); Serial.println(); Serial.print("Attempting to connect to WPA SSID: "); Serial.println(ssid); WiFi.persistent(true); WiFi.setAutoConnect(true); WiFi.begin(ssid, pass); WiFi.waitForConnectResult(); } else { client.println(F("HTTP/1.1 200 OK")); client.println(F("Connection: close")); client.println(); client.println(F("<html><body><h3>Configuration AP</h3><br>")); client.println(F("<h3>IP Adresse:</h3><br>")); client.println(F("<h3>WiFi.localIP()</h3><br>")); int status = WiFi.status(); if (status == WL_CONNECTED) { client.println(F("Connection successful. Ending AP.")); client.println(F("</body></html>")); client.stop(); delay(1000); // 等待通信完成 Serial.println("Connection successful. Ending AP."); configWebServer.stop(); WiFi.mode(WIFI_STA); configWebServer.begin(); // 启动全局WebServer,和直连WiFi逻辑对齐 return; // 退出配网函数,返回setup后进入loop主循环 } else { client.println(F("<form action='/' method='POST'>WiFi connection failed. Enter valid parameters, please.<br><br>")); client.println(F("SSID:<br><input type='text' name='i'><br>")); client.println(F("Password:<br><input type='password' name='p'><br><br>")); client.println(F("<input type='submit' value='Submit'></form>")); client.println(F("Funktion 2 <a href=\"?pin=FUNCTION2ON\"><button>einschalten</button>")); } client.println(F("</body></html>")); client.stop(); } } } }
测试方法
注释掉setup()中开头的WiFi.begin();语句,烧录程序后设备会启动配网AP,配网成功后会自动关闭AP,进入loop()运行主逻辑,和已保存WiFi密码直接连接的行为完全一致。
内容的提问来源于stack exchange,提问作者user16897767
相关产品推荐
相关产品推荐

