ESP32连接WiFi失败后无需重启即可扫描SSID的实现疑问
ESP32 WiFi重连与扫描问题:能否移除
WiFi.mode(WIFI_OFF)和WiFi.mode(WIFI_STA)? 需求与问题
需求:ESP32-DevKit-V1启动后自动重连上次关机前连接的WiFi;若该SSID不在范围内,则扫描并列出可用SSID供选择。
遇到的问题:故意输入错误WiFi凭证触发SSID列表功能,但连接失败后扫描未正常执行。排查发现WiFi.scanNetworks()未将状态设为-1,变量uint8_t n被设为254,只有先关闭再重新开启WiFi后扫描才能正常运行。现在想知道能否移除代码中的WiFi.mode(WIFI_OFF)和WiFi.mode(WIFI_STA)这两行,同时实现需求,精简后的代码如下:
#include <Arduino.h> #include <WiFi.h> const char* ssid = "blehbleh"; const char* password = "blahblah"; uint8_t n; bool connectingToLast() { Serial.printf("Trying to connect to %s\n", ssid); WiFi.begin(ssid, password); int8_t status = WiFi.waitForConnectResult(20000); if (status != WL_CONNECTED) { Serial.printf("Not connected! Err: %i\n", status); return false; } else return true; } void wifiScan() { Serial.print("Scanning networks."); WiFi.scanNetworks(true); while (WiFi.scanComplete() == -1) { delay(500); Serial.print("."); } Serial.println(""); delay(1000); n = WiFi.scanComplete(); Serial.printf("Amount of networks found: %d\n", n); for (uint8_t i = 0; i < n; i++) { Serial.printf("%2d. %s\n", i+1, WiFi.SSID(i)); } Serial.println(""); } void setup() { Serial.begin(115200); WiFi.mode(WIFI_STA); if (connectingToLast()) { Serial.println("Connected!"); } else { WiFi.mode(WIFI_OFF); // 能否移除这两行? WiFi.mode(WIFI_STA); wifiScan(); } } void loop () {}
解决方案:可以移除这两行代码
通过调整连接失败后的状态清理逻辑,替代原来的模式切换重置方式,就能让扫描正常执行,同时保持代码精简。
优化后的代码
#include <Arduino.h> #include <WiFi.h> const char* ssid = "blehbleh"; const char* password = "blahblah"; uint8_t n; bool connectingToLast() { Serial.printf("Trying to connect to %s\n", ssid); WiFi.begin(ssid, password); int8_t status = WiFi.waitForConnectResult(20000); if (status != WL_CONNECTED) { Serial.printf("Not connected! Err: %i\n", status); // 连接失败后彻底断开并清理状态 WiFi.disconnect(true); return false; } else return true; } void wifiScan() { Serial.print("Scanning networks."); // 清除之前残留的扫描结果 WiFi.scanDelete(); // 启动异步扫描 WiFi.scanNetworks(true); // 等待扫描完成 while (WiFi.scanComplete() == -1) { delay(500); Serial.print("."); } Serial.println(""); delay(1000); n = WiFi.scanComplete(); // 处理扫描异常情况 if (n == -2) { Serial.println("Scan was aborted"); return; } else if (n == 255) { Serial.println("Scan error occurred"); return; } Serial.printf("Amount of networks found: %d\n", n); for (uint8_t i = 0; i < n; i++) { Serial.printf("%2d. %s\n", i+1, WiFi.SSID(i)); } Serial.println(""); // 扫描完成后清除结果,避免干扰后续操作 WiFi.scanDelete(); } void setup() { Serial.begin(115200); delay(100); // 给串口初始化留缓冲时间 WiFi.mode(WIFI_STA); if (connectingToLast()) { Serial.println("Connected!"); } else { // 已移除WiFi.mode(WIFI_OFF)和WiFi.mode(WIFI_STA) wifiScan(); } } void loop () {}
关键调整说明
- 连接失败后调用
WiFi.disconnect(true):true参数会彻底断开连接并清除保存的WiFi凭证,重置WiFi模块内部状态,替代原来的模式切换操作。 - 扫描前调用
WiFi.scanDelete():清除之前可能残留的扫描结果,确保本次扫描是全新的初始化状态。 - 增加扫描异常判断:处理扫描中止(返回-2)或错误(返回255)的情况,避免异常值导致逻辑出错。
这样调整后,无需切换WiFi模式就能让扫描正常执行,同时保持代码逻辑清晰、运行稳定。
内容的提问来源于stack exchange,提问作者Eduardo Isla Venegas
相关产品推荐
相关产品推荐

