基于ESP32的桌面小屏幕实战[15]:开启WiFi AP模式

1. 基本概念

AP mode 和 STA mode 是无线网络中的两种主要工作模式,分别对应于设备作为接入点(Access Point)和客户端(Station)的角色。

设备工作在 AP 模式时,充当无线网络的接入点,允许其他设备连接到它并通过它访问网络。设备工作在 STA 模式 时,充当无线客户端,连接到一个现有的 Wi-Fi 网络(AP)。

2. 源码

打开 ~/esp/DesktopScreenV4.0.3 文件夹,执行命令:

git checkout dev9

多出 main/src/net/ds_wifi_ap.c 文件。

工作流程

(1)调用 ds_wifi_ap_start() 启动 AP。
(2)ESP32 开始广播配置的 SSID,设备可以使用密码连接到该 Wi-Fi。
(3)在设备连接或断开时,会触发 wifi_event_handler 记录事件。
(4)调用 ds_wifi_ap_stop() 停止 AP 模式并释放资源。

2.1 宏定义与配置

/*  WiFi softAP Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "lwip/err.h"
#include "lwip/sys.h"

/* The examples use WiFi configuration that you can set via project configuration menu.

   If you'd rather not, just change the below entries to strings with
   the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_ESP_WIFI_SSID      CONFIG_ESP_AP_WIFI_SSID
#define EXAMPLE_ESP_WIFI_PASS      CONFIG_ESP_AP_WIFI_PASSWORD
#define EXAMPLE_ESP_WIFI_CHANNEL   CONFIG_ESP_AP_WIFI_CHANNEL
#define EXAMPLE_MAX_STA_CONN       CONFIG_ESP_AP_MAX_STA_CONN

static const char *TAG = "wifi softAP";

static uint8_t start_status = 0;

2.2 Wi-Fi 事件处理

函数 wifi_event_handler 注册为 Wi-Fi 事件回调,监听连接和断开事件:
当设备连接到热点时,记录连接设备的 MAC 地址和 AID。
当设备断开连接时,记录离开的设备信息。

static void wifi_event_handler(void* arg, esp_event_base_t event_base,
                                    int32_t event_id, void* event_data)
{
    if (event_id == WIFI_EVENT_AP_STACONNECTED) {
        wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
        ESP_LOGI(TAG, "station "MACSTR" join, AID=%d",
                 MAC2STR(event->mac), event->aid);
    } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
        wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
        ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d",
                 MAC2STR(event->mac), event->aid);
    }
}

2.3 AP 初始化

初始化网络接口和 Wi-Fi 驱动程序。
配置 AP 模式,包括 SSID、密码、最大连接数和认证模式。
注册事件处理程序并启动 Wi-Fi。

void wifi_init_softap(void)
{
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_create_default_wifi_ap();

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));

    wifi_config_t wifi_config = {
        .ap = {
            .ssid = EXAMPLE_ESP_WIFI_SSID,
            .ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID),
            .channel = EXAMPLE_ESP_WIFI_CHANNEL,
            .password = EXAMPLE_ESP_WIFI_PASS,
            .max_connection = EXAMPLE_MAX_STA_CONN,
            .authmode = WIFI_AUTH_WPA_WPA2_PSK
        },
    };
    if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
        wifi_config.ap.authmode = WIFI_AUTH_OPEN;
    }

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());

    ESP_LOGI(TAG, "wifi_init_softap finished. SSID:%s password:%s channel:%d",
             EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS, EXAMPLE_ESP_WIFI_CHANNEL);
}

2.4 AP 管理接口

ds_wifi_ap_start:

  • 启动 AP 模式,调用 wifi_init_softap 初始化 AP。
  • 防止重复启动,使用变量 start_status 管理状态。

ds_wifi_ap_stop:

  • 停止 AP 模式,调用 esp_wifi_stop 和 esp_wifi_deinit 释放资源。
  • 防止重复停止,通过 start_status 管理。
void ds_wifi_ap_start(void)
{
    if(start_status == 0){
        start_status = 1;
        ESP_LOGI(TAG, "ESP_WIFI_MODE_AP");
        wifi_init_softap();
    }else{
        ESP_LOGI(TAG, "ESP_WIFI_MODE_AP IS STARTING");
    }
}

void ds_wifi_ap_stop(){
    if(start_status == 1){
        start_status = 0;
        ESP_LOGI(TAG, "ESP_WIFI_MODE_AP STOP");
        ESP_ERROR_CHECK(esp_wifi_stop() );
        ESP_ERROR_CHECK(esp_wifi_deinit() );
    }else{
        ESP_LOGI(TAG, "ESP_WIFI_MODE_AP IS STOPING");
    }
}

3. 编译工程

使用 idf.py menuconfig 命令可以设置WiFi名和密码。
img

执行命令

idf.py -p /dev/ttyUSB0 flash monitor

从日志可以看到AP已经启动
img

打开手机,连接screen,输入密码123456789
img

日志提示有设备接入
img

断开时提示有设备离开
img

posted @ 2025-11-19 09:45  茴香豆的茴  阅读(79)  评论(0)    收藏  举报