超级版主
 
- 积分
- 5115
- 金钱
- 5115
- 注册时间
- 2019-5-8
- 在线时间
- 1277 小时
|
本帖最后由 正点原子运营 于 2025-11-18 10:22 编辑
第五十一章 WiFi一键配网
1)实验平台:正点原子DNESP32S3开发板
2)章节摘自【正点原子】ESP32-S3使用指南—IDF版 V1.6
3)购买链接:https://detail.tmall.com/item.htm?&id=768499342659
4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/esp32/ATK-DNESP32S3.html
5)正点原子官方B站:https://space.bilibili.com/394620890
6)正点原子DNESP32S3开发板技术交流群:132780729
ESP32-S3的一键配网模式是一种方便快捷的WiFi配置方式。在这种模式下,用户无需手动输入WiFi的SSID和密码等信息,只需要通过一键操作,即可完成WiFi的配置和连接。本章节,作者使用乐鑫官方提供的SmartConfig软件一键配置WiFi账号与密码。
本章分为如下几个小节:
51.1 主流WIFI 配网方式简介
51.2 硬件设计
51.3 软件设计
51.4 下载验证
51.1 主流WIFI 配网方式简介
目前主流的WIFI配网方式主要有以下三种:
一、SoftAP配网
ESP32-S3会建立一个WiFi热点(AP模式),用户将手机连接到这个热点后,将要连接的WiFi信息发送给ESP32-S3,ESP32-S3得到SSID和密码。
①:优点:很可靠,成功率基本达到100%,设备端的代码简单。
②:缺点:需要手动切换手机WiFi连接的网络,先连接到ESP32的AP网络,配置完成后再恢复连接正常WiFi网络,操作上存在复杂性,可能给用户带来困扰。
③:官方支持:没有提供Demo。
二、Smartconfig配网
ESP32-S3处于混杂模式下,监听网络中的所有报文,手机APP将当前连接的SSID和密码编码到UDP报文中,通过广播或组播的方式发送报文,ESP32-S3接收到UDP报文后解码,得到SSID和密码,然后使用该组SSID和密码去连接网络。
①:优缺点:简洁,用户容易操作,但配网成功率受环境影响较大。
②:官方支持:提供Demo和smart_config例程。
三、Airkiss配网
AirKiss是微信硬件平台提供的一种WIFI设备快速入网配置技术。要使用微信客户端的方式配置设备入网,需要设备支持AirKiss技术。Airkiss的原理和Smartconfig很类似,设备工作在混杂模式下,微信客户端发送包含SSID和密码的广播包,设备收到广播包解码得到SSID和密码。详细的可以参考微信官方的介绍。
①:优缺点:简洁,用户容易操作,但配网成功率受环境影响较大。
②:官方支持:提供Demo和smart_config例程。
本实验以Smartconfig软件对ESP32-S3设备进行一键配网,该软件的安装包可在乐鑫官方网站的相关下载网页找到,如下图所示。
图51.1.1 Smartconfig软件下载
下载成功后,需把安装包转移到安卓手机或者苹果手机上安装。
51.2 硬件设计
1. 例程功能
本章实验功能简介:设备进入初始化状态,开启混监听所有网络数据包,此时LCD显示"In the distribution network......",表示设备已进入混监听模式。手机连上自己的WiFi,开启APP(EspTouch)软件,输入手机所在WiFi密码,请求配网,发送UDP广播包。ESP32 -S3通过UDP包(长度)获取配置信息捕捉到路由SSID和PASSWD,连接路由器,此时LCD显示路由的账号与密码,表示连接路由成功。
2. 硬件资源
1)LED灯
LED-IO1
2)XL9555
IIC_INT-IO0(需在P5连接IO0)
IIC_SDA-IO41
IIC_SCL-IO42
3)SPILCD
CS-IO21
SCK-IO12
SDA-IO11
DC-IO40(在P5端口,使用跳线帽将IO_SET和LCD_DC相连)
PWR- IO1_3(XL9555)
RST- IO1_2(XL9555)
4)ESP32-S3内部WiFi
3. 原理图
本章实验使用的WiFi为ESP32-S3的片上资源,因此并没有相应的连接原理图。
51.3 软件设计
51.3.1 程序流程图
程序流程图能帮助我们更好的理解一个工程的功能和实现的过程,对学习和设计工程有很好的主导作用。下面看看本实验的程序流程图:
图51.3.1.1 程序流程图
51.3.2 程序解析
在本章节实验中,我们只关心main.c文件内容即可,该文件内容如下:
- i2c_obj_t i2c0_master;
- /* 定义事件 */
- static EventGroupHandle_t s_wifi_event_group;
- static const int CONNECTED_BIT = BIT0;
- static const int ESPTOUCH_DONE_BIT = BIT1;
- static const char *TAG = "smartconfig_example";
- static void smartconfig_task(void * parm);
- static char lcd_buff[100] = {0};
- /**
- * @brief WIFI链接糊掉函数
- * [url=home.php?mod=space&uid=271674]@param[/url] arg:传入网卡控制块
- * @param event_base:WIFI事件
- * @param event_id:事件ID
- * @param event_data:事件数据
- * @retval 无
- */
- static void event_handler(void* arg, esp_event_base_t event_base,
- int32_t event_id, void* event_data)
- {
- if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
- {
- xTaskCreate(smartconfig_task, "smartconfig_task", 4096, NULL, 3, NULL);
- }
- else if (event_base == WIFI_EVENT &&
- event_id == WIFI_EVENT_STA_DISCONNECTED)
- {
- esp_wifi_connect();
- xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT);
- }
- else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
- {
- xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
- }
- else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE)
- {
- ESP_LOGI(TAG, "Scan done");
- lcd_show_string(0,90,320,16,16,"In the distribution network", BLUE);
- }
- else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL)
- {
- ESP_LOGI(TAG, "Found channel");
- }
- /* 已获取SSID和密码,表示配网成功 */
- else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD)
- {
- ESP_LOGI(TAG, "Got SSID and password");
- smartconfig_event_got_ssid_pswd_t *evt =
- (smartconfig_event_got_ssid_pswd_t *)event_data;
- wifi_config_t wifi_config;
- uint8_t ssid[33] = { 0 };
- uint8_t password[65] = { 0 };
- uint8_t rvd_data[33] = { 0 };
- bzero(&wifi_config, sizeof(wifi_config_t));
- memcpy(wifi_config.sta.ssid, evt->ssid, sizeof(wifi_config.sta.ssid));
- memcpy(wifi_config.sta.password, evt->password,
- sizeof(wifi_config.sta.password));
- wifi_config.sta.bssid_set = evt->bssid_set;
- if (wifi_config.sta.bssid_set == true)
- {
- memcpy(wifi_config.sta.bssid, evt->bssid,
- sizeof(wifi_config.sta.bssid));
- }
- memcpy(ssid, evt->ssid, sizeof(evt->ssid));
- memcpy(password, evt->password, sizeof(evt->password));
- ESP_LOGI(TAG, "SSID:%s", ssid);
- ESP_LOGI(TAG, "PASSWORD:%s", password);
- lcd_fill(0,90,320,240,WHITE);
- sprintf(lcd_buff, "%s",ssid);
- lcd_show_string(0, 90, 320, 16, 16, lcd_buff, BLUE);
- sprintf(lcd_buff, "%s",password);
- lcd_show_string(0, 110, 320, 16, 16, lcd_buff, BLUE);
- lcd_show_string(0,130,320,16,16,"distribution network", BLUE);
- /* 手机APPEspTouch软件使用ESPTOUCH V2模式,会执行以下代码 */
- if (evt->type == SC_TYPE_ESPTOUCH_V2)
- {
- ESP_ERROR_CHECK( esp_smartconfig_get_rvd_data(rvd_data,
- sizeof(rvd_data)) );
- ESP_LOGI(TAG, "RVD_DATA:");
- for (int i = 0; i < 33; i++)
- {
- printf("%02x ", rvd_data);
- }
- printf("\n");
- }
- ESP_ERROR_CHECK( esp_wifi_disconnect() );
- ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
- esp_wifi_connect();
- }
- else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE)
- {
- xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT);
- }
- }
- /**
- * @brief WiFi一键配网
- * @param 无
- * @retval 无
- */
- static void wifi_smartconfig_sta(void)
- {
- /* 初始化网卡 */
- ESP_ERROR_CHECK(esp_netif_init());
- /* 创建事件 */
- s_wifi_event_group = xEventGroupCreate();
- /* 使用默认配置初始化包括netif的Wi-Fi */
- ESP_ERROR_CHECK(esp_event_loop_create_default());
- /* 把WIFI网卡设置为STA模式 */
- esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
- assert(sta_netif);
- wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
- /* WIFI初始化 */
- ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
- /* 注册WIFI事件 */
- ESP_ERROR_CHECK( esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID,
- &event_handler, NULL) );
- ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP,
- &event_handler, NULL) );
- ESP_ERROR_CHECK( esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID,
- &event_handler, NULL) );
- ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
- ESP_ERROR_CHECK( esp_wifi_start() );
- }
- /**
- * @brief 一键配网回调函数
- * @param parm:传入的形参(未使用)
- * @retval 无
- */
- static void smartconfig_task(void * parm)
- {
- parm = parm;
- EventBits_t uxBits;
- /* 设置配网协议 */
- ESP_ERROR_CHECK( esp_smartconfig_set_type(SC_TYPE_ESPTOUCH) );
- /* 设置配网参数 */
- smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT();
- /* 开始配网 */
- ESP_ERROR_CHECK( esp_smartconfig_start(&cfg) );
- while (1)
- {
- /* 获取事件 */
- uxBits = xEventGroupWaitBits(s_wifi_event_group, CONNECTED_BIT
- | ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);
-
- /* 配网成功 */
- if(uxBits & CONNECTED_BIT)
- {
- ESP_LOGI(TAG, "WiFi Connected to ap");
- }
- /* 智能配置结束 */
- if(uxBits & ESPTOUCH_DONE_BIT)
- {
- /* 配网结束,删除任务 */
- esp_smartconfig_stop();
- vTaskDelete(NULL);
- }
- }
- }
- /**
- * @brief 程序入口
- * @param 无
- * @retval 无
- */
- void app_main(void)
- {
- /* 省略部分代码..... */
- wifi_smartconfig_sta();
- while (1)
- {
- LED_TOGGLE();
- vTaskDelay(500);
- }
- }
复制代码 上述源码是把ESP32-S3设备配置为STA模式,然后开启配网任务并启动配网,此时,ESP32-S3处于混杂模式下,监听网络中的所有报文,当手机APP将当前连接的SSID和密码编码到UDP报文中,通过广播或组播的方式发送报文,ESP32-S3接收到UDP报文后解码,得到SSID和密码,然后使用该组SSID和密码去连接当前网络。
51.4 下载验证
程序下载成功后,我们打开“EspTouch”软件,在此软件下点击 “EspTouch”选项,注意:手机必须连接WiFi,才能一键配网,如下图所示。
图51.4.1 手机配置要连接的WiFi账号与密码
此时,我们填写好“ALIENTEK-YF_5G”WiFi密码和传输方式,可按下确定按键发送UDP报文。当ESP32-S3设备接收到这个报文时,系统会提取该报文的SSID和密码去连接该网络。下图是ESP32-S3配网成功效果图。
图51.4.2 配网成功 |
|