4、ESP32连接Wi-Fi:Wi-Fi库使用、连接路由器、获取IP地址、串口打印调试信息

好,咱们进入正题。这一章要解决的是ESP32的“上网”问题。说白了,就是让ESP32连上你家的路由器,拿到一个IP地址,然后才能跟Blynk服务器说话。

我刚开始玩ESP32的时候,觉得连Wi-Fi不就是调个库吗?结果发现坑还真不少。比如连不上、反复重启、IP地址拿不到……嗯,咱们今天就把这些事一次性说清楚。

4.1 Wi-Fi库的引入与初始化

ESP32的Wi-Fi功能,靠的是Arduino框架下的 WiFi.h 库。这个库封装了底层的网络协议,你不需要懂TCP/IP栈的细节,直接调用函数就行。

我个人习惯,在代码开头就把Wi-Fi相关的头文件包含进来:

#include <WiFi.h>

就这么一行。别小看它,这个库提供了连接、断开、扫描、获取IP等所有核心功能。

接下来,我们要定义两个全局变量:Wi-Fi的名称(SSID)和密码。我建议你直接写在代码里,方便调试。但注意,正式产品里别硬编码,不然换网络就得改代码。

const char* ssid = "你的路由器名称";
const char* password = "你的路由器密码";

这里有个小细节:SSID和密码都是字符串,用 const char* 类型。为什么不用 String?因为 String 在ESP32上容易造成内存碎片,我踩过这个坑,后来全改成C风格字符串了。

4.2 连接路由器:三步走

连接Wi-Fi其实就三步:设置模式、开始连接、等待成功。咱们一步步来。

4.2.1 设置Wi-Fi模式

ESP32的Wi-Fi可以工作在三种模式:

模式 宏定义 说明
Station(客户端) WIFI_STA 连接路由器,上网用
Access Point(热点) WIFI_AP 自己当路由器,其他设备连它
Station + AP WIFI_AP_STA 同时当客户端和热点

咱们做远程控制,ESP32需要连到家里的路由器,所以用 WIFI_STA 模式:

WiFi.mode(WIFI_STA);

这一行放在 setup() 函数里。我见过有人不写这行也能连上,因为默认就是STA模式。但为了代码清晰,我建议显式设置。

4.2.2 开始连接

调用 WiFi.begin() 函数,传入SSID和密码:

WiFi.begin(ssid, password);

这个函数是异步的。什么意思?它发出连接请求后立刻返回,不会等连接完成。所以我们需要一个循环来检查状态。

4.2.3 等待连接成功

WiFi.status() 函数检查连接状态。它返回一个枚举值:

状态值 含义
WL_CONNECTED 连接成功
WL_DISCONNECTED 断开连接
WL_CONNECT_FAILED 连接失败(密码错误等)
WL_NO_SSID_AVAIL 找不到该Wi-Fi

我通常这样写等待逻辑:

while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
}

这里有个坑:如果Wi-Fi一直连不上,程序就会卡死在这个循环里。我曾经在项目里遇到路由器突然重启,ESP32就永远卡住了。后来我加了超时机制:

int timeout = 0;
while (WiFi.status() != WL_CONNECTED && timeout < 20) {
    delay(500);
    Serial.print(".");
    timeout++;
}
if (WiFi.status() != WL_CONNECTED) {
    Serial.println("连接失败,请检查Wi-Fi名称和密码");
}

这样最多等10秒(20次×500毫秒),连不上就报错,不会死循环。

4.3 获取IP地址

连接成功后,ESP32会自动从路由器获取一个IP地址。用 WiFi.localIP() 函数就能拿到:

Serial.print("IP地址: ");
Serial.println(WiFi.localIP());

这个函数返回一个 IPAddress 对象,直接打印就能看到类似 192.168.1.100 这样的地址。

你想想看,有了IP地址,ESP32在网络里就有了身份。Blynk服务器就是通过这个IP地址(其实是经过路由器转发)跟ESP32通信的。

除了IP地址,有时候我还打印子网掩码和网关:

Serial.print("子网掩码: ");
Serial.println(WiFi.subnetMask());
Serial.print("网关: ");
Serial.println(WiFi.gatewayIP());

这些信息在调试网络问题时特别有用。比如你发现ESP32能连上Wi-Fi但收不到Blynk数据,可能就是网关设置不对。

4.4 串口打印调试信息

串口是嵌入式开发的“眼睛”。没有串口打印,你根本不知道ESP32在干什么。

setup() 开头,先初始化串口:

Serial.begin(115200);

波特率115200是ESP32的常用值。注意,串口监视器也要设置成同样的波特率,不然看到的是乱码。

我习惯把Wi-Fi连接的全过程都打印出来,方便定位问题:

void setup() {
    Serial.begin(115200);
    Serial.println();

    // 连接Wi-Fi
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    Serial.print("正在连接Wi-Fi");

    int timeout = 0;
    while (WiFi.status() != WL_CONNECTED && timeout < 20) {
        delay(500);
        Serial.print(".");
        timeout++;
    }

    Serial.println();
    if (WiFi.status() == WL_CONNECTED) {
        Serial.println("Wi-Fi连接成功!");
        Serial.print("IP地址: ");
        Serial.println(WiFi.localIP());
    } else {
        Serial.println("Wi-Fi连接失败!");
    }
}

你看,每一行打印都有明确的目的。连接过程中打印点号,让用户知道程序在运行。连接成功后打印IP地址,方便后续调试。

我的小技巧: 在串口打印中加入时间戳。比如用 millis() 函数打印当前毫秒数,这样能看出每个步骤花了多长时间。对排查性能问题很有帮助。

4.5 完整代码示例

把上面所有内容整合起来,就是一个完整的Wi-Fi连接程序:

#include <WiFi.h>

const char* ssid = "你的Wi-Fi名称";
const char* password = "你的Wi-Fi密码";

void setup() {
    Serial.begin(115200);
    delay(10);
    Serial.println();
    Serial.println("ESP32 Wi-Fi连接示例");

    // 设置Wi-Fi模式
    WiFi.mode(WIFI_STA);
    // 开始连接
    WiFi.begin(ssid, password);
    Serial.print("正在连接");

    // 等待连接,带超时
    int timeout = 0;
    while (WiFi.status() != WL_CONNECTED && timeout < 20) {
        delay(500);
        Serial.print(".");
        timeout++;
    }

    Serial.println();
    if (WiFi.status() == WL_CONNECTED) {
        Serial.println("连接成功!");
        Serial.print("IP地址: ");
        Serial.println(WiFi.localIP());
        Serial.print("子网掩码: ");
        Serial.println(WiFi.subnetMask());
        Serial.print("网关: ");
        Serial.println(WiFi.gatewayIP());
    } else {
        Serial.println("连接失败!");
        Serial.print("状态码: ");
        Serial.println(WiFi.status());
    }
}

void loop() {
    // 定期检查Wi-Fi状态
    if (WiFi.status() != WL_CONNECTED) {
        Serial.println("Wi-Fi断开,尝试重连...");
        WiFi.reconnect();
    }
    delay(5000);
}

这个代码里,我在 loop() 里加了Wi-Fi状态检查。为什么要加?因为Wi-Fi连接不是永久的。路由器重启、信号干扰都可能导致断开。加上自动重连,设备才能稳定运行。

注意: WiFi.reconnect() 不是万能的。如果密码错误或者路由器关了,它只会反复尝试,浪费电量。更稳妥的做法是:重连几次失败后,进入低功耗模式或者重启设备。

4.6 常见问题与避坑

我整理了几个新手容易遇到的问题,都是我在项目里真实碰到的:

  • 连不上Wi-Fi:先检查SSID和密码对不对。注意大小写,注意特殊字符。我曾经因为密码里有个空格,查了半天。
  • 串口打印乱码:波特率不匹配。ESP32设115200,串口监视器也要设115200。
  • IP地址是169.254.x.x:这是自动私有IP地址,说明DHCP分配失败。检查路由器是否开启了DHCP服务。
  • Wi-Fi反复断开重连:可能是信号太弱,或者路由器负载过高。试试把ESP32靠近路由器。

嗯,这一章的内容就到这里。你学会了Wi-Fi库的使用、连接路由器、获取IP地址,还有串口打印调试。下一章,咱们就要让ESP32真正连上Blynk平台了。