WiFi 实验
从这一个实验开始,逐渐开始讲解 ESP32 的 wifi 无线通信相关知识。
请参考 3.1.2 节,我们的演示的工作目录位于“G:\ESP32”,在这个目录下创建有文件夹“examples”, 接着把开发板带的 wifi 实验教程“.\配套的例程\2wifi 部分.rar”解压到文件夹“examples”下,如图:
我们新增加了 10 个工程,第 4 章的实验围绕着这些工程讲解。
4.1. WiFi-AP 模式创建 wifi 热点
本实验通过 ESP32 模块创建一个 wifi 热点,手机或者电脑可以连接到这个热点上。 这个实验的代码为工程“4_1_wifi_AP”目录。
4.1.1. 实验内容
(1) 学习 AP 创建方法
(2) 学习 AP 网关的 IP 设置方法
(3) 掌握 wifi 状态机机制
4.1.2. AP 简介
AP 是 (Wireless) AccessPoint 的缩写,即 (无线) 访问接入点。简单来讲就像是无线路由器一样, 设备打开后进入 AP 模式,在手机的网络列表里面,可以搜索到类似 TPLINK_XXX 的名字(SSID)。
ESP32 创建的 AP 热点,最多可以被 4 个 STA 设备连接,我们的手机和笔记本电脑均可连接到创建的 AP 热点。
4.1.3. ESP32 wifi 编程相关
(1) wifi 设计流程图 流程图来源于网络:https://blog.csdn.net/fengfeng0328/article/details/82824499 启动 wifi 流程图:
Wifi 状态机流程图:
(2) 相关函数介绍
初始化 TCP/IP 协议栈
使用 wifi、有线、网络编程前必须先调用这个函数进行初始化。
函数定义:
void tcpip_adapter_init(void); 参数说明:无
返回值:无
初始化事件回调函数
函数定义:
esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx); 参数说明:
system_event_cb_t cb:回调函数,通过回调函数,可以知道当前 wifi 处于什么状态 void *ctx:保留,无实际用途
返回值:ESP_OK(成功)。
回调函数状态机解析
这个回调函数状态机,包括 AP、STA 和有线网络,程序会根据他们的实时状态,在回调函数中给 出状态返回。
函数定义:
esp_err_t event_handler(void *ctx, system_event_t *event); 参数说明:
system_event_t *event:wifi 事件,这是一个枚举,具体定义在后面有说明 void *ctx:保留,无实际用途
返回值:无
typedef struct {
system_event_id_t system_event_info_t
} system_event_t;
//事件 ID
SYSTEM_EVENT_WIFI_READY = 0, //WiFi 准备好
SYSTEM_EVENT_SCAN_DONE, //扫描 AP 完成
SYSTEM_EVENT_STA_START, //作为 STA 开始工作 SYSTEM_EVENT_STA_STOP, //作为 STA 结束工作 SYSTEM_EVENT_STA_CONNECTED, //作为 STA 连接上 AP SYSTEM_EVENT_STA_DISCONNECTED, //作为 STA 断开 AP SYSTEM_EVENT_STA_AUTHMODE_CHANGE, //作为 STA 连接的 AP 改变了
SYSTEM_EVENT_STA_GOT_IP, //作为 STA 从 AP 获取了 IP SYSTEM_EVENT_STA_LOST_IP, //作为 STA 丢掉了 IP,也就是错了 SYSTEM_EVENT_STA_WPS_ER_SUCCESS, //wps succeeds in enrollee mode SYSTEM_EVENT_STA_WPS_ER_FAILED, // wps fails in enrollee mode SYSTEM_EVENT_STA_WPS_ER_TIMEOUT, // wps timeout in enrollee mode SYSTEM_EVENT_STA_WPS_ER_PIN, //wps pin code in enrollee mode SYSTEM_EVENT_AP_START,//AP 开始
SYSTEM_EVENT_AP_STOP, //AP 结束 SYSTEM_EVENT_AP_STACONNECTED, //有 STA 连上 SP32 的 AP SYSTEM_EVENT_AP_STADISCONNECTED, //有 STA 断开 ESP32 的 AP SYSTEM_EVENT_AP_PROBEREQRECVED, //从 AP 中接收包 SYSTEM_EVENT_GOT_IP6, //获取 IPv6
SYSTEM_EVENT_ETH_START, //有线开始 SYSTEM_EVENT_ETH_STOP, //有线停止 SYSTEM_EVENT_ETH_CONNECTED, //有线上线 SYSTEM_EVENT_ETH_DISCONNECTED, //有线掉线
SYSTEM_EVENT_ETH_GOT_IP, //有线获取了 IP SYSTEM_EVENT_MAX
} system_event_id_t;
初始化 wifi 驱动
函数定义:
esp_err_t esp_wifi_init(const wifi_init_config_t *config); 参数说明:
wifi_init_config_t *config:wifi 参数,通过宏 WIFI_INIT_CONFIG_DEFAULT()可以取得默认的参数 返回值:ESP_OK(成功)。
设置 wifi 模式
函数定义:
esp_err_t esp_wifi_set_mode(wifi_mode_t mode); 参数说明:
wifi_mode_t mode:wifi 模式,这是一个枚举,具体定义在后面有说明 返回值:ESP_OK(成功)。
typedef enum {
WIFI_MODE_NULL = 0, //不启动 wifi WIFI_MODE_STA, //STA 模式
WIFI_MODE_AP, //AP 模式 WIFI_MODE_APSTA, //AP+STA 模式 WIFI_MODE_MAX
} wifi_mode_t;
配置 wifi 参数
通过这个函数设置 AP 或者 STA 的 SSID 和密码,函数定义:
esp_err_t esp_wifi_set_config(wifi_interface_t interface, wifi_config_t *conf); 参数说明:
wifi_interface_t interface:接口选择,这是一个枚举,具体定义在后面有说明 wifi_config_t *conf:需要配置的参数,包括 AP 和 STA 的参数
返回值:ESP_OK(成功)。
typedef enum {
ESP_IF_WIFI_STA = 0, //STA 接口
ESP_IF_WIFI_AP, //AP 接口
ESP_IF_ETH, //有线以太网接口 ESP_IF_MAX
} esp_interface_t;
启动 wifi
启动 wifi 函数调用之后,wifi 的状态机就开始运行起来,回调函数就会返回 wifi 当前的各种状态,定义:
esp_err_t esp_wifi_start(void); 参数说明:无
返回值:ESP_OK(成功)。
设置 IP
通过这个函数可以设置接口的(STA 接口、AP 接口和以太网接口)IP 信息、网关和掩码,函数定义如:
esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if,
const tcpip_adapter_ip_info_t *ip_info);
参数说明:
tcpip_adapter_if_t tcpip_if:接口选择,这是一个枚举,具体定义在后面有说明 tcpip_adapter_ip_info_t *ip_info:需要配置的参数,包括 AP 和 STA 的参数
返回值:ESP_OK(成功)。
typedef enum {
TCPIP_ADAPTER_IF_STA = 0, TCPIP_ADAPTER_IF_AP, TCPIP_ADAPTER_IF_ETH, TCPIP_ADAPTER_IF_MAX
} tcpip_adapter_if_t; typedef struct {
ip4_addr_t ip; //IP ip4_addr_t netmask;//掩码 ip4_addr_t gw;//网关
}
4.1.4. 代码讲解
使用 vs code 展开本实验的工程目录,如下图:
我们的这个实验,启动 AP 热点的代码是写在源文件 app_main.c 里,components 文件夹是关于 LCD 的 驱动代码,LCD 显示屏在 3.4 章有比较详情的讲解。
(1) Wifi AP 初始化
//启动 WIFI 的 AP void wifi_init_ap()
{
tcpip_adapter_init();//tcp/IP 配置
#ifdef ESP32_STATIC_IP
ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP)); tcpip_adapter_ip_info_t ipInfo;
inet_pton(AF_INET,DEVICE_IP,&ipInfo.ip); inet_pton(AF_INET,DEVICE_GW,&ipInfo.gw); inet_pton(AF_INET,DEVICE_NETMASK,&ipInfo.netmask); ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP,&ipInfo)); tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP);
#endif
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));//设置 wifi 事件回调函数
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg));//wifi 默认初始化 wifi_config_t wifi_config = {
.ap = {
.ssid = DEFAULT_SSID,
.password = DEFAULT_PWD,
.ssid_len = 0,
.max_connection = 1,//最多只能被 4 个 station 同时连接
.authmode = WIFI_AUTH_WPA_WPA2_PSK,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));//设置 wifi 工作模式为 AP ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));//配置 AP 参数 ESP_ERROR_CHECK(esp_wifi_start()); //wifi 启动
代码里的 DEFAULT_SSID 和 DEFAULT_PWD 是 wifi 的用户名和密码,在 app_main.c 最开头有定义:
#define DEFAULT_SSID "sz-
#define DEFAULT_PWD
代码里的宏定义 ESP32_STATIC_IP,如果定义这个宏表示使用静态 IP,在 app_main.c 最开头有定义:
#define
#ifdef ESP32_STATIC_IP
//IP 地址。
#define DEVICE_IP
//网关
#define DEVICE_GW "192.168.10.1"
DEVICE_NETMASK
(2) Wifi 回调函数状态机处理
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch (event->event_id)
{
case SYSTEM_EVENT_AP_START://AP 启动
{
tcpip_adapter_ip_info_t ipInfo; printf("\nwifi_softap_start\n");
//修改设备名字,可以不写 ESP_ERROR_CHECK(tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_AP, "sz-yy.taobao.com")); ESP_ERROR_CHECK(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP,&ipInfo));
//取出设备的 IP,网关和掩码 s_ip_addr=ipInfo.ip; s_gw_addr=ipInfo.gw; s_netmask_addr=ipInfo.netmask;
//显示 lcd_display(2);
}
break;
case SYSTEM_EVENT_AP_STACONNECTED://有设备连接 printf("station:"MACSTR" join, AID=%d.\r\n",
MAC2STR(event->event_info.sta_connected.mac), event->event_info.sta_connected.aid);
break;
case SYSTEM_EVENT_AP_STADISCONNECTED://连接的设备断开 printf("station:"MACSTR"leave, AID=%d.\r\n",
MAC2STR(event->event_info.sta_disconnected.mac), event->event_info.sta_disconnected.aid);
break;
default:
4.1.5. 实验过程
配置下载串口、波特率、编绎和程序下载的详细过程请往回看 3.1.4,在这个实验里都是一笔带过。 (1) 把开发板通过 USB 线接到电脑上,通过设备管理器查看生成的串口。开发板在我们演示电脑上生成的是 COM3。
(2) 在 menuconfig 菜单里配置下载程序串口。提供的例程配置的串口是 COM3,波特率为 921600。
(3) 通过 make all 编绎工程。
(4) 当编绎通过之后,使用命令 make flash 把程序下载到开发板上。或者参考 2.3.2 节,使用工具 下载。
(5) 按下开发板的复位键,让程序运行起来,观察显示屏可以看到相关的 AP 信息。
(6) 使用串口工具打开开发板生成的串口,默认的波特率是 115200,观察串口工具的输出(拨码开关 一定要打开)。串口工具在目录:.\开发软件\串口工具-sscom32.rar。
(7) 通过手机或者笔记本电脑,可以查找到生成的 AP 热点ESP32WIFI并连接上。连接和断开热点后,串口会输 出不同的 LOG。
最后推荐一款开发套件,可以手淘扫码查看。