3. ESP8266 Station模式实战:连接路由器、获取IP地址、TCP客户端通信、HTTP GET请求
好,咱们今天来点真格的。上一章我们把ESP8266的三种模式理清了,这一章直接上手Station模式——说白了,就是让你的ESP8266像手机一样,连上家里的Wi-Fi路由器,然后上网。
我个人习惯,做物联网项目90%以上的场景都用Station模式。为什么?因为设备需要跟云平台通信,需要获取数据,总不能老拿根串口线拖着吧?
本章核心目标:让ESP8266以Station模式接入路由器 → 获取IP地址 → 建立TCP连接 → 发送HTTP GET请求。一条龙走通。
3.1 Station模式初始化流程
先看整体流程,心里有个地图。我画了张图,你跟着走一遍就清楚了。
嗯,这张图你得记住。后面所有Station模式的项目,都是这个骨架。
3.2 连接路由器:代码实战
直接上代码。我用的是Arduino框架,ESP8266的Wi-Fi库封装得很好,几行就能搞定。
#include <ESP8266WiFi.h>
// 替换成你自己的Wi-Fi信息
const char* ssid = "YourWiFiName";
const char* password = "YourWiFiPassword";
void setup() {
Serial.begin(115200);
delay(100);
Serial.println();
Serial.print("正在连接: ");
Serial.println(ssid);
// 设置为Station模式
WiFi.mode(WIFI_STA);
// 发起连接
WiFi.begin(ssid, password);
// 等待连接成功
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("连接成功!");
Serial.print("IP地址: ");
Serial.println(WiFi.localIP());
}
void loop() {
// 主循环暂时留空
}
我的小经验:while循环里加个超时判断,别让设备死等。我曾经有个项目,路由器临时断电,设备就在那一直打点,最后看门狗复位了。加个10秒超时,连不上就重启,稳得多。
3.3 获取IP地址:DHCP与静态IP
连接成功后,ESP8266默认通过DHCP自动获取IP。大部分场景够用了。但有些时候——比如你要做TCP服务器,或者设备需要固定地址方便调试——就得用静态IP。
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| DHCP | 自动分配,无需配置 | IP可能变化 | 大多数物联网项目 |
| 静态IP | 地址固定,方便管理 | 需手动配置,可能冲突 | TCP服务器、调试环境 |
静态IP怎么配?看下面这段:
IPAddress local_IP(192, 168, 1, 100);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
void setup() {
// 在连接前配置静态IP
if (!WiFi.config(local_IP, gateway, subnet)) {
Serial.println("静态IP配置失败");
}
WiFi.begin(ssid, password);
// 后续代码同上
}
注意:静态IP必须跟路由器在同一网段,网关地址也得对。我见过有人把子网掩码写成255.255.255.255,结果设备连上了但哪也去不了——说白了,自己把自己关门外了。
3.4 TCP客户端通信
有了IP,就能玩TCP了。ESP8266作为TCP客户端,连接远程服务器,收发数据。这是物联网设备跟云端通信的基础。
先看一个简单的TCP客户端例子:
#include <ESP8266WiFi.h>
const char* host = "192.168.1.50"; // 服务器IP
const int port = 8080;
WiFiClient client;
void setup() {
Serial.begin(115200);
WiFi.begin("YourWiFi", "YourPassword");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Wi-Fi已连接");
// 连接TCP服务器
Serial.print("连接到: ");
Serial.print(host);
Serial.print(":");
Serial.println(port);
if (client.connect(host, port)) {
Serial.println("TCP连接成功");
client.println("Hello from ESP8266!");
} else {
Serial.println("TCP连接失败");
}
}
void loop() {
if (client.connected()) {
if (client.available()) {
String line = client.readStringUntil('\n');
Serial.println("收到: " + line);
}
}
}
这里有个关键点:client.connect()是非阻塞的,但内部有超时机制。默认大约5秒。如果连不上,别死等,加个重试逻辑。
避坑指南:我曾经在做一个环境监测项目时,TCP连接总是断断续续。查了半天,发现是服务器端设置了空闲超时,ESP8266这边没做心跳。后来每30秒发一个空包保活,问题解决。记住:TCP连接不是永久有效的,网络环境复杂,一定要做重连机制。
3.5 HTTP GET请求实战
TCP是底层,HTTP是应用层。物联网设备最常用的就是GET请求——从服务器获取数据,比如天气信息、传感器阈值、控制指令。
ESP8266的Wi-Fi库自带HTTP客户端,但更灵活的方式是用WiFiClient自己拼HTTP报文。你想想看,理解了HTTP协议本身,以后换什么平台都不怕。
#include <ESP8266WiFi.h>
const char* host = "api.example.com";
const int port = 80;
void httpGet() {
WiFiClient client;
if (!client.connect(host, port)) {
Serial.println("连接失败");
return;
}
// 拼HTTP GET请求
String request = "GET /data?device=esp01 HTTP/1.1\r\n";
request += "Host: " + String(host) + "\r\n";
request += "Connection: close\r\n";
request += "\r\n";
client.print(request);
// 读取响应
while (client.connected() || client.available()) {
if (client.available()) {
String line = client.readStringUntil('\n');
Serial.println(line);
}
}
client.stop();
}
void setup() {
Serial.begin(115200);
WiFi.begin("YourWiFi", "YourPassword");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Wi-Fi已连接");
httpGet();
}
void loop() {}
这段代码干了三件事:建立TCP连接、发送HTTP GET请求、解析响应。注意HTTP协议格式——请求行、请求头、空行,一个都不能少。少了空行,服务器就不知道请求结束了。
我的习惯:调试HTTP请求时,先用电脑上的curl或者Postman试通,再把同样的请求格式搬到ESP8266上。这样能快速定位问题是出在设备端还是服务器端。
3.6 常见问题与排查
写代码总会遇到坑。我列几个最常见的,你遇到了直接对照排查:
- 连接不上路由器:检查SSID和密码,注意大小写。ESP8266只支持2.4G频段,5G不行。
- 获取不到IP:路由器DHCP池满了?换个设备试试。或者手动配静态IP。
- TCP连接失败:服务器IP/端口对不对?防火墙有没有拦截?先用电脑ping一下。
- HTTP请求无响应:检查请求格式,特别是\r\n。服务器返回301跳转?需要处理重定向。
- 连接不稳定:Wi-Fi信号弱?加天线或者换位置。代码里加重连逻辑。
重要提醒:ESP8266的Wi-Fi栈在连接过程中会阻塞其他任务。如果你的项目有实时性要求(比如PWM输出),建议用异步方式或者RTOS。我有个项目因为Wi-Fi重连导致电机控制卡顿,后来加了任务调度才解决。
好了,这一章的内容就到这。代码你都试过了吗?建议先连上路由器,打印出IP地址,再一步步玩TCP和HTTP。每一步都验证通过,再往下走。别一口气全写完再调试——那样出了问题,你都不知道是哪一步的锅。