- 一、前言
- 二、WiFi配网方式
- 三、快速运行
- 四、运行效果
- 五、ESP32-C3程序流程
- 5.1 主程序
- 5.2 回调函数
- 5.3 SmartConfig线程
- 六、关键函数
- 6.1 设置SmartConfig的协议类型
- 6.2 启动SmartConfig
- 6.3 停止SmartConfig
- 七、参考
二、WiFi配网方式本文基于VS Code IDE进行编程、编译、下载、运行等操作
基础知识点请查阅:ESP32-C3入门教程 基础篇①——基于VS Code构建Hello World
WiFi配网即:用户通过App/小程序/网页等途径将WiFi的SSID和密码等信息发送给ESP32,方式有很多种:
- SoftAP,ESP32开启热点,App连接到该热点AP,并将WiFi的信息发送给ESP32
- SmartConfig,App将WiFi信息通过UDP广播组播出去,ESP32监听网络中所有报文,得到App广播出来的WiFi信息
- SmartConfig有很多种,EspTouch、AirKiss、EspTouchV2等
- BluFi,App通过蓝牙的方式将WiFi信息发送给ESP32
本博文描述ESP32-C3通过SmartConfig EspTouch方式进行智能配网。
三、快速运行- 示例项目中,选择protocols—>wifi->smart_config
- menuconfig配置ESP32C3-Specific—>Rec 0
- 芯片选择ESP32-C3(Built-in USB JTAG)
- 快速运行ESP-IDF Build, Flash and Monitor(左下角)
- 下载、安装、打开EspTouchForAndroid App
- 输入WiFi密码,确认即可
- 注意:ESP32只支持2.4GHz WiFi,还不支持5GHz WiFi
- nvs_flash_init,初始化默认 NVS 分区
- esp_netif_init,初始化底层TCP/IP堆栈
- esp_event_loop_create_default,创建默认事件循环
- esp_netif_create_default_wifi_sta,使用默认WiFi Station配置创建esp_netif对象,将netif连接到WiFi并注册默认WiFi处理程序
- esp_wifi_init,为 WiFi 驱动初始化 WiFi 分配资源,如 WiFi 控制结构、RX/TX 缓冲区、WiFi NVS 结构等,这个 WiFi 也启动 WiFi 任务。必须先调用此API,然后才能调用所有其他WiFi API
- esp_event_handler_instance_register,监听WIFI_EVENTWiFi 任意事件,触发事件后,进入回调函数
- esp_event_handler_instance_register,监听IP_EVENT从连接的AP获得IP的事件,触发事件后,进入回调函数
- esp_event_handler_instance_register,监听SC_EVENT从SmartConfig任意事件,触发事件后,进入回调函数
- esp_wifi_set_mode,设置WiFi工作模式为station、soft-AP或station+soft-AP,默认模式为soft-AP模式。本程序设置为station
- esp_wifi_start,根据配置,启动WiFi
- WIFI_EVENT_STA_START,WiFi station 模式启动时:
- 创建smartconfig_example_task线程,开始SmartConfig
- WIFI_EVENT_STA_DISCONNECTED,WiFi station 模式失去连接
- 清除CONNECTED_BIT标志位
- IP_EVENT_STA_GOT_IP,WiFi station 模式从连接的AP那获得IP
- 设置CONNECTED_BIT标志位
- SC_EVENT_SCAN_DONE,SmartConfig 扫描AP列表结束
- SC_EVENT_FOUND_CHANNEL,SmartConfig 从目标AP找到频道
- SC_EVENT_GOT_SSID_PSWD,SmartConfig 获得WiFi信息(SSID和密码)时:
- 解析出WiFi的SSID和密码
- esp_wifi_disconnect断开当前WiFi连接
- esp_wifi_set_configWiFI配置,设置WIFI_IF_STA模式,设置WiFi的SSID和密码
- esp_wifi_connectWiFi连接
- SC_EVENT_SEND_ACK_DONE,SmartConfig 给App发送完成ACK
- 设置ESPTOUCH_DONE_BIT标志位
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_example_task, "smartconfig_example_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");
} else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL) {
ESP_LOGI(TAG, "Found channel");
} 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);
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);
}
}
5.3 SmartConfig线程
- esp_smartconfig_set_type设置SmartConfig的协议类型为SC_TYPE_ESPTOUCH。协议类型有:SC_TYPE_ESPTOUCH、SC_TYPE_AIRKISS、SC_TYPE_ESPTOUCH_AIRKISS、SC_TYPE_ESPTOUCH_V2等
- esp_smartconfig_start启动SmartConfig
- 等待ESPTOUCH_DONE_BIT标志位
- esp_smartconfig_stop停止SmartConfig
static void smartconfig_example_task(void * 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_LOGI(TAG, "smartconfig over");
esp_smartconfig_stop();
vTaskDelete(NULL);
}
}
}
六、关键函数
6.1 设置SmartConfig的协议类型
- type:SmartConfig的协议类型,包含:ESPTouch、AirKiss、ESPTOUCH_AIRKISS、ESPTOUCH_V2等
typedef enum {
SC_TYPE_ESPTOUCH = 0,
SC_TYPE_AIRKISS,
SC_TYPE_ESPTOUCH_AIRKISS,
SC_TYPE_ESPTOUCH_V2,
} smartconfig_type_t;
esp_err_t esp_smartconfig_set_type(smartconfig_type_t type);
6.2 启动SmartConfig
- config:配置
typedef struct {
bool enable_log;
bool esp_touch_v2_enable_crypt;
char *esp_touch_v2_key;
} smartconfig_start_config_t;
esp_err_t esp_smartconfig_start(const smartconfig_start_config_t *config)
6.3 停止SmartConfig
esp_err_t esp_smartconfig_stop(void)七、参考
SmartConfig - ESP32-C3 - —ESP-IDF 编程指南 latest 文档
觉得好,就一键三连呗(点赞+收藏+关注)



