跳到主要内容

第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(部分型号更高),支持多种省电模式,支持多天线分集(部分型号)等。

ESP32 产品概览

2. Wi-Fi 编程模型

ESP32-S3 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 流程

初始化阶段

  1. 初始化 TCP/IP 协议栈(LwIP)和网络接口管理模块(esp-netif)。
  2. 搭建系统的事件驱动框架,创建默认事件循环(esp_event)。
  3. 创建默认网络接口(如 STA/AP)。
  4. 初始化 Wi-Fi 驱动(esp_wifi_init)。启动相关内部任务,确保无线硬件和协议栈正常运行。

配置阶段

  1. 配置 Wi-Fi 连接参数(如 SSID、密码、认证方式等,使用 wifi_config_t 结构体)。
  2. 设置 Wi-Fi 工作模式(esp_wifi_set_mode)。
  3. 应用配置到接口(esp_wifi_set_config)。

连接与事件处理

  1. 启动 Wi-Fi(esp_wifi_start)。
  2. 发起连接 (STA 模式)(esp_wifi_connect)。
  3. 通过事件回调处理连接、断开、获取 IP 等异步事件。

4. 示例程序

以下示例代码演示了如何将 ESP32 配置为一个简单的 Wi-Fi 接入点(SoftAP)。其他设备可以搜索到名为 esp32_s3_test 的 Wi-Fi 网络并连接。

此示例来源于 ESP-IDF 官方示例 wifi/getting_started/softAP,并做了简化处理。

  1. 创建一个项目。如果不清楚如何操作,请参考 从模板创建项目

  2. 将以下代码复制到 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));
    }
    }
  3. 禁用 NVS

    注意

    这不是推荐的存储凭据的方式,最佳实践请参考 ESP-IDF 官方示例 wifi/getting_started/softAP

    通常 Wi-Fi 应用会将凭据存储在非易失性存储(NVS)中。为简化本示例,我们硬编码了 AP 的凭据。

    NVS 默认是启用的。为了避免警告和错误,我们通过 menuconfig 将其禁用。

    • 点击 VS Code SDK 配置编辑器图标 打开 SDK 配置编辑器。

    • 搜索 NVS,然后禁用图中的选项。

      在 SDK 配置编辑器关闭 NVS

    • 修改完成后,点击 "保存" 按钮。

  4. 配置烧录选项

    首先,在构建和烧录之前,请务必检查并设置正确的目标设备、串口和烧录方式。参考 第 2 节 运行示例 - 1.3 配置项目

    VS Code 工具栏

  5. 点击 VS Code 一键构建烧录监视图标 一键自动依次执行构建、烧录和监视这三个步骤。

  6. 烧录完成后,串口监视器会开始打印信息。你应该能看到一些日志和事件编号。

    示例输出

    • 使用智能手机连接到 ESP32 的热点。此时在终端中应该看到 Event nr: 14!,这对应于 WIFI_EVENT_AP_STACONNECTED(可在 GitHub 上查看枚举值,枚举值从 0 开始。)

5. 下一步

成功连接到网络后,下一步就是实现具体的应用功能。ESP-IDF 提供了丰富的应用层协议支持:

  • HTTP/HTTPS 客户端/服务器:用于与 Web 服务器交换数据,或将 ESP32 用作小型 Web 服务器。
  • MQTT:轻量级发布/订阅消息协议,是物联网设备与云平台通信的首选方案。
  • WebSocket:提供全双工通信通道,适用于实时数据交互场景。
  • SNTP (简单网络时间协议):从互联网时间服务器同步 ESP32 系统时间,对需要精确时间戳的应用至关重要。
  • mDNS (组播 DNS):允许通过主机名(如 my-esp32.local)在本地网络中访问设备,无需知道 IP 地址,简化设备发现过程。

你可以在 ESP-IDF 的 examples/protocols 目录下找到这些协议的示例代码。

6. 参考链接