《DNESP32S3使用指南-IDF版_V1.6》第五十一章 WiFi一键配网

第五十一章 WiFi一键配网


       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链接糊掉函数
 * @param       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[i]);
            }
 
            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 配网成功


请使用浏览器的分享功能分享到微信等