4、WiFi基础与连接:ESP32 WiFi库、Station模式、连接路由器、获取IP地址
好,咱们进入正题。这一章要解决一个最基础的问题——让ESP32连上你家路由器。说白了,就是给它一张“上网门票”。
我刚开始玩ESP32的时候,觉得WiFi连接嘛,不就是调个库、填个SSID和密码?结果第一次调试就翻车了——死活连不上,折腾了半小时才发现是密码里有个特殊字符没转义。嗯,这种坑咱们今天一并填上。
4.1 ESP32 WiFi库概览
ESP32的WiFi功能由官方提供的 WiFi.h 库封装。这个库是Arduino框架下的标准库,你不需要额外安装,直接在代码开头 #include <WiFi.h> 就能用。
我个人习惯把WiFi相关的操作封装成一个独立模块,这样主程序看起来清爽。WiFi库的核心对象就是 WiFi 这个全局实例,它提供了所有操作接口。
| 核心函数 | 功能说明 | 我在项目中踩过的坑 |
|---|---|---|
WiFi.begin(ssid, password) |
启动连接,传入WiFi名称和密码 | 密码含空格或中文时容易失败,建议纯ASCII |
WiFi.status() |
返回当前连接状态 | 轮询时记得加延时,否则CPU跑满 |
WiFi.localIP() |
获取分配给ESP32的IP地址 | 连接成功前调用会返回0.0.0.0 |
WiFi.disconnect() |
断开当前WiFi连接 | 重连前最好先调用一次,清空状态 |
WiFi.mode(mode) |
设置WiFi工作模式 | 默认是Station+AP双模式,耗电高 |
WiFi.begin() 的返回值打印出来。返回 WL_CONNECTED 才算成功,其他状态码都有具体含义,别只看“连没连上”。
4.2 Station模式——让ESP32当客户端
ESP32支持三种WiFi模式:Station(客户端)、AP(热点)、Station+AP(混合)。咱们做远程控制,绝大多数场景只用Station模式——ESP32去连你家里的路由器,而不是自己开热点。
为什么?你想想看,如果ESP32自己开热点,你的手机就得断开家里WiFi去连它,那手机就没法上网了。这显然不现实。所以,Station模式是物联网设备的标准姿势。
设置Station模式的代码就一行:
WiFi.mode(WIFI_STA); // 设置为客户端模式
我曾经见过有人忘了设模式,结果ESP32同时开着AP和Station,信号互相干扰,连接稳定性差得一塌糊涂。所以我的建议是:明确指定模式,别偷懒。
4.3 连接路由器——完整流程
连接路由器不是一句 WiFi.begin() 就完事的。你需要处理超时、重连、状态反馈。下面是我在实际项目中打磨出来的连接流程:
- 设置模式:
WiFi.mode(WIFI_STA) - 发起连接:
WiFi.begin(ssid, password) - 轮询状态:循环检查
WiFi.status() - 超时处理:超过指定时间未连上,重启或进入配网模式
- 获取IP:连接成功后调用
WiFi.localIP()
来看一段完整的代码示例:
#include <WiFi.h>
const char* ssid = "你的WiFi名称";
const char* password = "你的WiFi密码";
void setup() {
Serial.begin(115200);
// 1. 设置Station模式
WiFi.mode(WIFI_STA);
// 2. 开始连接
Serial.print("正在连接 ");
Serial.println(ssid);
WiFi.begin(ssid, password);
// 3. 轮询等待,最多等20秒
int timeout = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
timeout++;
if (timeout > 40) { // 20秒超时
Serial.println("\n连接超时!");
break;
}
}
// 4. 检查结果
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\n连接成功!");
Serial.print("IP地址: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("连接失败,请检查SSID和密码");
}
}
void loop() {
// 定期检查连接状态
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi断开,尝试重连...");
WiFi.reconnect();
}
delay(5000);
}
WiFi.reconnect() 不是万能的。如果路由器重启或信号彻底丢失,建议调用 WiFi.disconnect() 后再 WiFi.begin()。我曾经在项目中遇到过重连10次都失败的情况,最后发现是路由器DHCP租约过期了。
4.4 获取IP地址——你的设备身份证
连接成功后,路由器会通过DHCP给ESP32分配一个IP地址。这个地址就是你在局域网里访问ESP32的门牌号。咱们后面做WebSocket通信,客户端就是通过这个IP找到ESP32的。
获取IP地址很简单:
IPAddress localIP = WiFi.localIP();
Serial.println(localIP);
但这里有个细节——IP地址可能会变。路由器重启、设备重连、DHCP租约到期,都可能导致IP变化。如果你的手机App里写死了IP,一旦变了就连不上了。
我的解决方案有两个:
- 方案一:路由器设置静态DHCP(推荐)。在路由器后台把ESP32的MAC地址绑定一个固定IP。这样既享受DHCP的便利,又保证IP不变。
- 方案二:代码里用mDNS。给ESP32取个名字,比如
esp32-led.local,通过名字访问,不依赖IP。这个咱们后面章节会细讲。
| 获取方式 | 代码 | 返回值示例 |
|---|---|---|
| 本地IP | WiFi.localIP() |
192.168.1.105 |
| 子网掩码 | WiFi.subnetMask() |
255.255.255.0 |
| 网关IP | WiFi.gatewayIP() |
192.168.1.1 |
| DNS服务器 | WiFi.dnsIP() |
192.168.1.1 |
4.5 本章知识结构图
下面这张图把WiFi连接的完整流程和关键节点串起来了。建议你对照着代码看,思路会更清晰。
核心要点回顾:
- Station模式是物联网设备的标准选择,别开AP模式浪费资源
- 连接流程要处理超时和重连,不能只调一次
begin()就完事 - IP地址可能变化,建议用静态DHCP或mDNS解决
- 调试时把
WiFi.status()的返回值打印出来,别猜