3. Wi-Fi联网基础:ESP32连接路由器,获取IP地址,实现基础TCP通信
好,咱们进入实战环节了。前面两章我们把硬件搭好、开发环境配通,现在该让灯“上网”了。这一章的核心就三件事:连上Wi-Fi、拿到IP、用TCP说上话。
说实话,我最早做物联网项目时,觉得联网不就是调个库函数嘛。结果第一次在现场部署,20个设备死活连不上公司路由器……后来才发现是Wi-Fi信道和DHCP租期的问题。嗯,这些坑咱们今天一并填上。
3.1 ESP32的Wi-Fi工作模式
ESP32的Wi-Fi模块挺灵活,支持三种模式:
| 模式 | 角色 | 典型场景 |
|---|---|---|
| Station (STA) | 客户端 | 连接家中路由器,上网 |
| Access Point (AP) | 热点 | 手机直连ESP32,做配置 |
| STA + AP | 双模式 | 一边上网,一边提供配置页面 |
咱们做灯光系统,设备肯定要连家里的路由器。所以今天只用Station模式。AP模式后面讲配网时会用到,先不急。
3.2 连接Wi-Fi路由器
代码其实不长。但你别小看这几行,我见过有人在这上面折腾一整天。
#include <WiFi.h>
const char* ssid = "你的WiFi名称";
const char* password = "你的WiFi密码";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.print("正在连接Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\n连接成功!");
Serial.print("IP地址: ");
Serial.println(WiFi.localIP());
}
void loop() {
// 后面再填内容
}
这段代码一跑,串口监视器里就会看到一连串的点在跳动。直到打印出IP地址,说明连上了。
3.3 获取IP地址——DHCP的秘密
连上路由器后,ESP32会自动通过DHCP拿到IP地址。你什么都不用做,WiFi.localIP()就能拿到。
但这里有个坑:IP地址可能会变。
为什么?因为DHCP分配的IP是有租期的。默认一般是24小时。租期到了,设备如果还连着,通常会续租同一个IP。但如果设备重启了、或者网络断了重连,路由器可能给你一个新IP。
这对灯光系统来说很要命。你想想看,手机App里存的是旧IP,设备IP变了,App就找不到灯了。
解决办法有三种:
- 路由器设置静态DHCP——在路由器后台,把ESP32的MAC地址绑定一个固定IP。这是最推荐的做法。
- 代码里设置静态IP——绕过DHCP,直接写死IP。但要注意IP不能和别的设备冲突。
- 用mDNS或广播发现——不依赖IP,通过设备名称找。这个后面章节会讲。
静态IP配置示例:
IPAddress local_IP(192, 168, 1, 100);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
if (!WiFi.config(local_IP, gateway, subnet)) {
Serial.println("静态IP配置失败");
}
WiFi.begin(ssid, password);
我个人习惯是开发阶段用DHCP,部署时用静态IP或路由器绑定。这样调试方便,上线稳定。
3.4 基础TCP通信——让灯听你的话
有了IP地址,设备就在网络里有了“门牌号”。接下来要做的,就是在这个门牌号上开一个“窗口”,让别人能往里递纸条。
这个“窗口”就是TCP Server。手机或电脑作为客户端,连上这个Server,发送指令来控制灯光。
#include <WiFi.h>
WiFiServer server(8888); // 端口号,随便选,别用已知端口就行
void setup() {
Serial.begin(115200);
WiFi.begin("你的WiFi", "你的密码");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
server.begin();
Serial.println("TCP服务器已启动,端口: 8888");
Serial.print("设备IP: ");
Serial.println(WiFi.localIP());
}
void loop() {
WiFiClient client = server.available();
if (client) {
Serial.println("有客户端连接了");
while (client.connected()) {
if (client.available()) {
String cmd = client.readStringUntil('\n');
cmd.trim();
Serial.print("收到指令: ");
Serial.println(cmd);
// 解析指令,控制灯光
if (cmd == "ON") {
// 开灯代码
client.println("灯已打开");
} else if (cmd == "OFF") {
// 关灯代码
client.println("灯已关闭");
} else {
client.println("未知指令");
}
}
}
client.stop();
Serial.println("客户端断开");
}
}
这段代码启动了一个TCP Server,监听8888端口。手机用TCP调试工具连上来,发"ON"就开灯,发"OFF"就关灯。
3.5 测试TCP通信
怎么测试?你不需要写一个App。手机上下载一个“TCP调试助手”或者“网络调试助手”就行。
测试步骤:
- ESP32上电,串口打印出IP地址,比如192.168.1.100
- 手机连同一个Wi-Fi(必须在同一个局域网)
- 打开TCP调试助手,选择TCP Client模式
- 输入IP: 192.168.1.100,端口: 8888
- 点击连接,发送"ON"
- 看串口是否打印"收到指令: ON"
如果连不上,先ping一下ESP32的IP。ping不通说明网络没通,检查Wi-Fi连接。ping通了连不上,检查防火墙或者端口号是否被占用。
3.6 本章小结
这一章我们做了三件事:
- ESP32以Station模式连上Wi-Fi
- 通过DHCP或静态配置拿到IP地址
- 启动TCP Server,实现基础的指令收发
说白了,现在你的灯已经“上网”了。虽然还只是最原始的TCP通信,但这是后面所有场景联动的基础。下一章我们会把TCP指令和PWM调光结合起来,让灯真正听话地亮起来、暗下去。
嗯,先别急着往下走。我建议你把今天的代码跑通,用手机发几条指令试试。那种“自己写的代码控制了一盏灯”的感觉,真的很爽。