第8节 Wi-Fi 编程
本教程的核心逻辑适用于所有 ESP32 开发板,但所有操作步骤均以 微雪 ESP32-S3-Zero 迷你开发板 为例进行讲解。如果您使用其他型号的开发板,请根据实际情况修改相应设置。
在本节中,你将学习 ESP32 Wi-Fi 功能的基础知识、核心编程模型,并掌握使用 ESP-IDF 开发 Wi-Fi 应用的通用步骤和关键代码。
1. ESP32 Wi-Fi 功能概述
ESP32 系列芯片内置强大的无线连接功能。大多数 ESP32 芯片集成了 Wi-Fi,非常适合物联网(IoT)项目。部分型号(如 P 系列和 H 系列)为满足高性能处理或特定应用场景,未集成 Wi-Fi 功能。各型号的具体无线支持情况可查阅官方的 ESP32 产品概览 文档。
- 基本介绍:ESP32 系列大部分芯片均内置 2.4 GHz Wi-Fi,部分新型号(如 ESP32-C6)支持 5 GHz 和 Wi-Fi 6。支持 802.11b/g/n/ax 等协议,适用于物联网、智能家居、工业自动化等场景。
- 支持的工作模式:
- Station (STA):客户端模式,连接到已有的 Wi-Fi 网络。
- SoftAP (AP):接入点模式,创建自己的 Wi-Fi 网络,供其他设备连接。
- STA+AP 共存:两种模式同时工作,既连接到路由器,又作为热点。
- Sniffer:监听模式,用于捕获和分析 Wi-Fi 数据包。
- 安全特性:支持 WPA2、WPA3、企业级认证等多种安全协议。
- 主要性能参数:最高速率可达 150 Mbps(部分型号更高),支持多种省电模式,支持多天线分集(部分型号)等。
2. Wi-Fi 编程模型
ESP-IDF 的 Wi-Fi 编程模型是事件驱动的,其核心组件协同工作以实现网络功能。
Wi-Fi 驱动程序可视为黑盒,对上层代码(如 TCP/IP 协议栈、应用任务和事件任务)一无所知。应用程序任务(代码)通常调用 Wi-Fi 驱动程序 API 来初始化 Wi-Fi 并处理相关事件。Wi-Fi 驱动程序接收 API 调用,处理后向应用程序发送事件。
Wi-Fi 事件处理基于 esp_event 库。驱动程序将事件发送到 默认事件循环,应用程序可在通过 esp_event_handler_register()
注册的回调函数中处理这些事件。esp_netif 组件 也会处理 Wi-Fi 事件以提供默认行为,例如当 Wi-Fi Station 连接到 AP 时,自动启动 DHCP 客户端。
3. Wi-Fi 编程通用步骤
无论是配置为 Station 还是 AP 模式,Wi-Fi 编程通常遵循以下三个阶段。更详细的流程图可参考 Wi-Fi Station 流程 和 Wi-Fi AP 流程。
初始化阶段
- 初始化 TCP/IP 协议栈(LwIP)和网络接口管理模块(esp-netif)。
- 搭建系统的事件驱动框架,创建默认事件循环(esp_event)。
- 创建默认网络接口(如 STA/AP)。
- 初始化 Wi-Fi 驱动(esp_wifi_init)。启动相关内部任务,确保无线硬件和协议栈正常运行。
配置阶段
- 配置 Wi-Fi 连接参数(如 SSID、密码、认证方式等,使用
wifi_config_t
结构体)。 - 设置 Wi-Fi 工作模式(
esp_wifi_set_mode
)。 - 应用配置到接口(
esp_wifi_set_config
)。
连接与事件处理
- 启动 Wi-Fi(
esp_wifi_start
)。 - 发起连接 (STA 模式)(
esp_wifi_connect
)。 - 通过事件回调处理连接、断开、获取 IP 等异步事件。
4. 示例程序
以下示例代码演示了如何将 ESP32 配置为一个简单的 Wi-Fi 接入点(SoftAP)。其他设备可以搜索到名为 esp32_s3_test 的 Wi-Fi 网络并连接。
此示例来源于 ESP-IDF 官方示例 wifi/getting_started/softAP,并做了简化处理。
-
创建一个项目。如果不清楚如何操作,请参考 从模板创建项目。
-
将以下代码复制到 main/main.c 中:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "string.h"
static const char *TAG = "wifi example";
// --- AP(接入点)配置 ---
#define ESP_WIFI_SSID "esp32_s3_test"
#define ESP_WIFI_PASS "12345678"
#define ESP_WIFI_CHANNEL 1
#define MAX_STA_CONN 2
static void wifi_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
// 简单的事件处理,只打印事件 ID。
// 在实际应用中,在这里根据不同的事件 ID (如 STA 连接、断开) 执行相应操作。
printf("Event nr: %ld!\n", event_id);
}
void wifi_init_softap()
{
// 1. 初始化阶段
// 初始化底层 TCP/IP 协议栈
esp_netif_init();
// 创建默认的事件循环
esp_event_loop_create_default();
// 创建默认的 Wi-Fi AP 网络接口
esp_netif_create_default_wifi_ap();
// 获取默认的 Wi-Fi 初始化配置
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
// 根据默认配置初始化 Wi-Fi 驱动
esp_wifi_init(&cfg);
// 注册 Wi-Fi 事件处理函数,监听所有 Wi-Fi 事件
esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&wifi_event_handler,
NULL,
NULL);
// 2. 配置阶段
// 定义 Wi-Fi 配置结构体
wifi_config_t wifi_config = {
.ap = {
.ssid = ESP_WIFI_SSID,
.ssid_len = strlen(ESP_WIFI_SSID),
.channel = ESP_WIFI_CHANNEL,
.password = ESP_WIFI_PASS,
.max_connection = MAX_STA_CONN,
.authmode = WIFI_AUTH_WPA2_PSK,
.pmf_cfg = {
.required = true,
},
},
};
// 3. 启动阶段
// 设置 Wi-Fi 工作模式为 AP 模式
esp_wifi_set_mode(WIFI_MODE_AP);
// 将配置应用到 Wi-Fi AP 接口
esp_wifi_set_config(WIFI_IF_AP, &wifi_config);
// 启动 Wi-Fi
esp_wifi_start();
// 打印日志,确认 AP 已启动并显示其 SSID、密码和信道
ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d",
ESP_WIFI_SSID, ESP_WIFI_PASS, ESP_WIFI_CHANNEL);
}
void app_main(void)
{
// 初始化并启动 Wi-Fi AP
wifi_init_softap();
while (1)
{
vTaskDelay(pdMS_TO_TICKS(1000));
}
} -
禁用 NVS
注意这不是推荐的存储凭据的方式,最佳实践请参考 ESP-IDF 官方示例 wifi/getting_started/softAP。
通常 Wi-Fi 应用会将凭据存储在非易失性存储(NVS)中。为简化本示例,我们硬编码了 AP 的凭据。
NVS 默认是启用的。为了避免警告和错误,我们通过 menuconfig 将其禁用。
-
点击
打开 SDK 配置编辑器。
-
搜索 NVS,然后禁用图中的选项。
-
修改完成后,点击 "保存" 按钮。
-
-
配置烧录选项
首先,在构建和烧录之前,请务必检查并设置正确的目标设备、串口和烧录方式。参考 第 2 节 运行示例 - 1.3 配置项目 。
-
点击
一键自动依次执行构建、烧录和监视这三个步骤。
-
烧录完成后,串口监视器会开始打印信息。你应该能看到一些日志和事件编号。
- 使用智能手机连接到 ESP32 的热点。此时在终端中应该看到
Event nr: 14!
,这对应于WIFI_EVENT_AP_STACONNECTED
(可在 GitHub 上查看枚举值,枚举值从 0 开始。)
- 使用智能手机连接到 ESP32 的热点。此时在终端中应该看到
5. 下一步
成功连接到网络后,下一步就是实现具体的应用功能。ESP-IDF 提供了丰富的应用层协议支持:
- HTTP/HTTPS 客户端/服务器:用于与 Web 服务器交换数据,或将 ESP32 用作小型 Web 服务器。
- MQTT:轻量级发布/订阅消息协议,是物联网设备与云平台通信的首选方案。
- WebSocket:提供全双工通信通道,适用于实时数据交互场景。
- SNTP (简单网络时间协议):从互联网时间服务器同步 ESP32 系统时间,对需要精确时间戳的应用至关重要。
- mDNS (组播 DNS):允许通过主机名(如
my-esp32.local
)在本地网络中访问设备,无需知道 IP 地址,简化设备发现过程。
你可以在 ESP-IDF 的 examples/protocols 目录下找到这些协议的示例代码。