ESP32 连不上 WiFi?按这张表逐项排查
- 系统排查 ESP32 连不上/频繁掉线 WiFi 的常见原因
- 学会用串口日志和状态码定位问题
- 掌握稳定联网的几个最佳实践
代码是照着教程一个字一个字抄的,WiFi.begin(ssid, password) 写得明明白白,串口里却永远卡在那一行 Connecting to WiFi...,后面跟着没完没了的点。你换了密码、重启了路由器、把板子搬到路由器旁边,折腾一晚上还是连不上。这几乎是每个做 ESP32 联网项目的人都会撞上的第一堵墙。
好消息是,连不上 WiFi 的原因虽然多,但每一种都有明确的特征和排查办法。这篇不讲玄学,把十几种常见原因列成一张「现象→原因→排查」的表,你照着一行行查就行。如果你还没把开发环境跑起来,先去看 搭好你的 AI 硬件开发环境,确认串口监视器能正常打印日志,再回来排查。本篇承接 让设备连上 WiFi,是它的故障排查篇。
先记住两个最高频的坑
把十几种原因摊开之前,先单独拎出两个。我敢说,新手卡 WiFi 的案例里,七成以上是这两个里的一个。把它们排除掉,问题往往就解决了一大半。
第一坑:ESP32 只支持 2.4GHz,不支持 5GHz。 这是绝对的头号杀手。现在的路由器几乎都是双频的,很多人家里的 WiFi 名字只有一个(比如 MyHome),手机连的其实是 5GHz 那个频段,体验好、速度快。但 ESP32 的射频只认 2.4GHz,你把那个 5GHz 的 SSID 和密码填进去,它会扫不到这个网络,于是无限重试。
排查办法:登录路由器后台,把 2.4GHz 和 5GHz 拆成两个独立的名字(比如 MyHome-2.4G 和 MyHome-5G),ESP32 连前者。如果你的路由器开了「双频合一」,关掉它,或者单独建一个 2.4GHz 的访客网络给设备用。手机连上 2.4GHz 那个名字能上网,再把同样的名字给 ESP32,基本就通了。
第二坑:供电不足导致 Brownout 重启。 ESP32 平时电流不大,但 WiFi 模块发射数据的那一瞬间,峰值电流能冲到 300~500mA。如果你用的是劣质 USB 线、或者插在电脑 USB 口(很多口只能稳定供 500mA 还带余量不足),瞬间电压被拉低,芯片触发欠压保护(Brownout),直接重启。
它的典型症状很有迷惑性:串口里能看到 WiFi 正要连上的那一刻板子突然重启,刷出一行 Brownout detector was triggered,然后从头再来,永远连不上。新手很容易误以为是代码问题,反复改代码却没用。
排查办法:换一根粗的、短的优质数据线;换一个能稳定输出 1A 以上的电源适配器,别用电脑 USB 口直插;电源进 ESP32 的地方并一个 470μF~1000μF 的电解电容,给瞬间放电「打底」。想搞懂供电为什么这么关键,看 电源稳压电路是怎么回事。
全部原因:现象→原因→排查大表
把两大坑记牢之后,剩下的原因按你看到的「现象」分类,对号入座查表。
| 现象 | 可能原因 | 怎么排查 |
|---|---|---|
| 完全连不上,无限重试 | 连了 5GHz 频段 | 路由器拆双频,ESP32 连 2.4GHz |
| 完全连不上 | SSID 或密码错 | 逐字核对,注意大小写;密码别有空格 |
| 完全连不上 | SSID/密码含中文或特殊字符 | 改成纯英文数字的网络名和密码 |
| 完全连不上 | 信号太弱/隔墙太远 | 搬到路由器旁边测,确认是不是距离问题 |
| 完全连不上 | 路由器开了 MAC 地址过滤 | 后台把 ESP32 的 MAC 加进白名单 |
| 完全连不上 | 连的是隐藏 SSID | 代码里用 WiFi.begin() 时确认支持隐藏网络,或先关隐藏 |
| 连上一瞬间就重启 | 供电不足 Brownout | 换电源/换线/并电容 |
串口刷 Brownout detector was triggered |
供电不足 | 同上,这是供电问题的铁证 |
拿不到 IP,卡在 WL_CONNECTED 后 |
路由器 DHCP 地址池满了 | 重启路由器,或扩大 DHCP 范围 |
| 连上又频繁掉线 | 信号弱/路由器负载高 | 加重连逻辑;换信道避开干扰 |
| 时连时不连,玄学 | 供电临界/天线被金属遮挡 | 板子别压在金属上;加强供电 |
| 同一网络多台设备只有它连不上 | 路由器开了 AP 隔离 | 关掉「AP 隔离/客户端隔离」 |
| 代码里连上了,但一调用网络就崩 | 没等连接成功就发请求 | 加等待连接的循环(见下文) |
| 偶尔编译/运行行为诡异 | 库或 Arduino-ESP32 内核版本过旧 | 升级到较新的稳定版内核 |
这张表里,ADC2 引脚和 WiFi 冲突 是个容易被漏掉的硬坑:ESP32 在 WiFi 开启时,ADC2 的那一组引脚(GPIO 0/2/4/12/13/14/15/25/26/27)无法做模拟读取,analogRead 会返回错误值或卡住。如果你的项目一边连 WiFi 一边读模拟传感器,务必把传感器接到 ADC1 的引脚(GPIO 32~39)。这不是 WiFi 连不上,而是连上之后读数全乱,但根子在同一处。
读懂 WiFi.status():别再盲猜
排查 WiFi 最有用的工具,是让代码自己告诉你它卡在哪一步。WiFi.status() 会返回一个状态码,把它打印出来,你立刻知道是「扫不到网络」还是「密码错」还是「正在连」。
void printWiFiStatus() {
switch (WiFi.status()) {
case WL_IDLE_STATUS: Serial.println("空闲,还没开始连"); break;
case WL_NO_SSID_AVAIL: Serial.println("扫不到这个 SSID(多半是 5GHz 或名字打错)"); break;
case WL_CONNECT_FAILED: Serial.println("连接失败(密码错的可能性大)"); break;
case WL_CONNECTION_LOST: Serial.println("连上后又掉了(信号/供电)"); break;
case WL_DISCONNECTED: Serial.println("已断开/正在重试"); break;
case WL_CONNECTED: Serial.println("已连上!"); break;
default: Serial.printf("其他状态码: %d\n", WiFi.status());
}
}
把这个函数放进 loop 里每秒调一次,连接过程中盯着串口看:
- 一直打印
WL_NO_SSID_AVAIL,几乎可以断定是 5GHz 问题或 SSID 写错——回头看第一坑。 - 打印
WL_CONNECT_FAILED,重点查密码,逐字核对,留意有没有多打的空格或全角字符。 - 在
WL_CONNECTED和WL_CONNECTION_LOST之间反复横跳,是信号或供电不稳,往掉线那一类排查。
有了状态码,你就从「玄学调试」升级成了「看证据破案」,效率天差地别。
稳定联网的最佳实践代码
很多人的连 WiFi 代码是教程里抄来的最简版,能在理想环境下跑通,一遇到现实就崩。一段健壮的连接代码至少要做到四件事:等连接成功、带超时不死等、连上失败能重试、运行中掉线能自动重连。
#include <WiFi.h>
const char* ssid = "MyHome-2.4G"; // 注意是 2.4GHz
const char* password = "your_password";
void connectWiFi() {
WiFi.mode(WIFI_STA); // 明确设为station模式
WiFi.begin(ssid, password);
Serial.print("连接中");
unsigned long start = millis();
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
if (millis() - start > 15000) { // 15秒超时,别无限死等
Serial.println("\n超时,重启WiFi重试");
WiFi.disconnect();
WiFi.begin(ssid, password);
start = millis();
}
}
Serial.printf("\n连上了,IP: %s\n", WiFi.localIP().toString().c_str());
}
void setup() {
Serial.begin(115200);
connectWiFi();
}
void loop() {
// 运行中掉线自动重连
if (WiFi.status() != WL_CONNECTED) {
Serial.println("掉线了,重连...");
connectWiFi();
}
// 你的业务逻辑放这里,确认在线后再发网络请求
}
这段代码的关键点:第一,while 循环里等到 WL_CONNECTED 才往下走,绝不在没连上时就发 HTTP 请求;第二,15 秒超时后主动 disconnect 再重连,避免卡死在某个坏状态;第三,loop 里持续检查连接,掉了立刻重连,这对要 7×24 运行的 IoT 设备是刚需。再叠加上前面说的独立优质供电,稳定性能上一个台阶。如果你的网络环境复杂、不想把密码写死在代码里,可以用配网方案,详见 SmartConfig 一键配网。
实在查不出,把日志喂给 AI
如果你照着表查了一圈还是没头绪,别一个人死磕。把串口监视器里从上电到卡住的完整日志全选复制,连同你的连接代码、板型、Arduino-ESP32 内核版本,一起喂给 AI。日志里那些你看不懂的十六进制地址、rst:0x... 复位原因码、Brownout 字样,AI 见过几百万条同类输出,往往一眼就能指出方向。
提问时把现场说全:用的什么板子、什么电源、路由器是不是双频、WiFi.status() 打印出来是哪个码。信息越完整,AI 缩小范围越准。具体怎么向 AI 描述硬件 bug、该喂哪些证据,看 用 AI 调试硬件 bug。一点提醒:AI 给的方向要自己动手验证,它对你这块具体板子的物理状态一无所知,把它当帮你列怀疑清单的侦探,最后拍板的还是你和万用表。
动手挑战
给你手上的任意一个 ESP32 联网项目,把那段最简的连 WiFi 代码换成上面这段健壮版。做完这三件事就算过关:
- 加上 15 秒超时和自动重连,确认拔掉路由器电源再插回,板子能自己重新连上(看串口有没有打印「掉线了,重连」)。
- 把
printWiFiStatus()加进去,故意把密码写错一位,看串口是不是真打印出WL_CONNECT_FAILED,体会状态码怎么帮你定位。 - 故意用电脑 USB 口供电跑一遍,再换 1A 适配器跑一遍,对比有没有
Brownout现象——亲手感受供电这个坑。
做完这一轮,你对 WiFi 故障的直觉会比看十篇教程都强。
小结
ESP32 连不上 WiFi 的原因虽多,但九成集中在两处:连错了 5GHz 频段、供电带不动发射峰值电流。先排这两个,再用 WiFi.status() 状态码看证据,最后用带超时和自动重连的健壮代码兜底,绝大多数问题都能在十分钟内定位。配网相关的进阶玩法看 SmartConfig 一键配网,联网基础回顾看 让设备连上 WiFi。更多动手教程见 教程总览 和 学习路线。