You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 () {}

关键调整说明

  1. 连接失败后调用WiFi.disconnect(true):true参数会彻底断开连接并清除保存的WiFi凭证,重置WiFi模块内部状态,替代原来的模式切换操作。
  2. 扫描前调用WiFi.scanDelete():清除之前可能残留的扫描结果,确保本次扫描是全新的初始化状态。
  3. 增加扫描异常判断:处理扫描中止(返回-2)或错误(返回255)的情况,避免异常值导致逻辑出错。

这样调整后,无需切换WiFi模式就能让扫描正常执行,同时保持代码逻辑清晰、运行稳定。

内容的提问来源于stack exchange,提问作者Eduardo Isla Venegas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 23:43:26