【ESP32】ESP-IDF开发 | WiFi开发 | AP模式 + 基站连接例程

1. 简介

        前面一篇讲了WiFi的基站模式,演示了怎么编程连接AP,所以这一篇讲一讲AP模式,ESP32作AP,让其他的设备连接自己。

1.1 DHCP

        这里需要补充一个知识点——DHCP服务器。当基站连接一个AP时,会被分配一个IP,那么这个IP一般就是通过AP中的DHCP服务器来分配的。

        DHCP(Dynamic Host Configuration Protocol),全称动态主机配置协议,其可以实现网络动态合理地分配IP地址给主机使用。它主要的特定是可以统一管理、分配IP地址;同时提出了IP地址租期的概念,使得IP地址能更高效使用。

1.2 信道

        配置AP时,可能会涉及到配置信道,信道通俗讲就是不同的频率段。像2.4G频段,一共有14个信道每个信道的频宽为22MHz,正常来说只有中间的20MHz是能用的,其余的2MHz是保险频段而已。

        AP能配置的信道数是跟它支持的频宽有关的,像ESP32最大频宽是40MHz,所以它可以配置2个信道。一个要注意的点是,相邻的信道其实是有重叠的,所以设置的时候我们最好选择互不重叠的信道;这种信道有4组,1/6/11、2/7/12、3/8/13和4/9/14

        另外一个要注意的点是,每个国家开放给民用的信道是不同的;像中国的话,支持1-13信道

1.3 编程流程

1. 初始化阶段

  • 调用 esp_event_loop_create() 创建一个系统事件任务,并初始化应用程序事件的回调函数;
  • 调用 esp_netif_init() 创建一个 LwIP 核心任务,并初始化 LwIP 相关工作;
  • 调用 esp_netif_create_default_wifi_sta() 创建有TCP/IP堆栈的默认网络接口实例绑定station;
  • 调用函数 esp_wifi_init() 创建 Wi-Fi 驱动程序任务,并初始化 Wi-Fi 驱动程序;

2. 配置阶段

  • 调用函数 esp_wifi_set_mode() 将 Wi-Fi 模式配置为 station 模式;
  • 调用 esp_wifi_set_protocol() 设置 WiFi 支持的协议(可选,默认是全开);
  • 调用 esp_wifi_set_bandwidth() 设置 WiFi 支持的带宽(可选);
  • 调用 esp_wifi_set_country_code() 设置国家代码(可选);
  • 调用函数 esp_wifi_set_config() 配置AP;

3. 启动阶段

  • 调用 esp_wifi_start() 启动 Wi-Fi 驱动程序;
  • 调用 esp_event_handler_instance_register() 注册对应的事件回调到应用当中;

4. 连接阶段

  • WIFI_EVENT_AP_STACONNECTED 事件触发,应用回调作处理;

5. 断开阶段

  • WIFI_EVENT_AP_STADISCONNECTED 事件触发,应用回调作处理。

2. 例程

        这个例程会配置ESP32作为AP,然后使用手机去连接ESP32。

#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_mac.h"
#include "nvs_flash.h"

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

#include <string.h>

#define TAG "app"
#define AP_SSID "ESP32"
#define AP_PASS "12345678"


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, reason=%d", MAC2STR(event->mac), event->aid, event->reason);
    }
}

int app_main()
{
    /* 初始化NVS */
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ESP_ERROR_CHECK(nvs_flash_init());
    }

    /* 初始化WiFi协议栈 */
    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_instance_register(WIFI_EVENT,
                                                        ESP_EVENT_ANY_ID,
                                                        &wifi_event_handler,
                                                        NULL,
                                                        NULL));

    wifi_config_t wifi_config = {
        .ap = {
            .ssid = AP_SSID,
            .ssid_len = strlen(AP_SSID),
            .channel = 1,
            .password = AP_PASS,
            .max_connection = 10,
            .authmode = WIFI_AUTH_WPA_WPA2_PSK,
        },
    };

    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 AP running at SSID: %s, password:%s", AP_SSID, AP_PASS);

    return 0;
}

        总体的编程流程跟前面的介绍是大差不差的,这里主要讲一下配置AP的这个结构体;下面只挑几个常用的讲。

typedef struct {
    uint8_t ssid[32];
    uint8_t password[64];
    uint8_t ssid_len;
    uint8_t channel;
    wifi_auth_mode_t authmode;
    uint8_t ssid_hidden;
    uint8_t max_connection;
    uint16_t beacon_interval;
    uint8_t csa_count;
    uint8_t dtim_period;
    wifi_cipher_type_t pairwise_cipher;
    bool ftm_responder;
    wifi_pmf_config_t pmf_cfg;
    wifi_sae_pwe_method_t sae_pwe_h2e;
} wifi_ap_config_t;
  •  ssid:SSID,就是我们所说的WiFi名;
  • password:WiFi密码;
  • ssid_len:SSID长度;
  • channel:信道,默认为1,设置时最好查询自己国家支持的信道;
  • authmode:授权模式,如果不需要密码就用 WIFI_AUTH_OPEN,一般的话就选 WIFI_AUTH_WPA_WPA2_PSK 可以覆盖常用的几种授权方式;
  • ssid_hidden:是否隐藏SSID,使能之后AP就不会广播自己的SSID,进行AP扫描的时候就扫不出来了;
  • max_connection:最大连接数,默认是10,最大是15;
  • beacon_interval:beacon 间隔,范围为100 ~ 60000ms,默认为100ms;这个就是AP广播SSID的包间隔

        当基站成功连接时,回调函数会接收到对方的MAC地址,及其他基本信息;在基站断开时也会返回前面的信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

马浩同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值