ESP32存储配网信息+LED显示配网状态+按键清除配网信息(附源码)
文章目录
本文参考了多个网友的大作,
1.荻夜 《ESP32存储配网信息,上电重启均可自动重连之前配置的无线网络》,详细讲述非易失性存储 (NVS)的操作流程。
2.Mr_VitaminC 《ESP32-C3 wifi 微信配网+按键清除+LED状态》
本文的完整代码:
链接:https://pan.baidu.com/s/1AoM0qvQTV_527_pJ9oNNXg?pwd=mafo
提取码:mafo
码云:https://gitee.com/huangweide001/esp32_test/tree/master/smart_config
csdn下载
1.非易失性存储库(NVS)(知识点内容照抄 荻夜文章)
非易失性存储 (NVS) 库主要用于在 flash 中存储键值格式的数据。NVS 最适合存储一些较小的数据,而非字符串或二进制大对象 (BLOB) 等较大的数据。如需存储较大的 BLOB 或者字符串,请考虑使用基于磨损均衡库的 FAT 文件系统.
我们主要了解以下 NVS 接口的使用,NVS 接口类似于电脑上操作文件:
- 初始化
调用“nvs_flash_init();”,如果失败可调用“nvs_flash_erase()”擦除NVS,然后再次初始化.
- 打开一个表
首先声明句柄:“nvs_handle my_handle; ”。后面对表里面的键值进行读写,都需要输入键值所在表的句柄。
nvs_open(“List”, NVS_READWRITE, &my_handle);
这个API第一个形参为一个字符串,可称为表名。第二个是读写模式,可选读写或者只读,第三个是当前打开的表的句柄。
- 读写表
读:nvs_get_i8(my_handle, “nvs_i8”, &nvs_i8);
读写不同的数据类型需要调用不同的API,类似的API有:“nvs_get_i16”,“nvs_get_u32”等等
形参方面,第一个是表的句柄,第二个是键值,第三个则是对应的变量的指针,如“nvs_i8”是个“int8_t”类型的变量。
写:nvs_set_i8(my_handle, “nvs_i8”, nvs_i8);
基本跟读差不多,注意的是第三个形参变成了对应的变量,而不是变量的指针。
- 提交和关闭文件
提交(保存):nvs_commit(my_handle);
关闭:nvs_close(my_handle);
读写文件的具体操作流程
写文件的操作
打开文件(nvs_open), 写文件(nvs_set_xxx), 保存文件(nvs_commit), 关闭文件(nvs_close)
读文件的操作
打开文件(nvs_open), 读取文件(nvs_get_xxx), 关闭文件(nvs_close)
官网提供的详细的中文讲解,请点击[ 非易失性存储 (NVS)]查看!
----------------------------------照抄结束---------------------------------------------
我这里保存读出ID和password是用下面的函数,二进制块读写。
esp_err_t nvs_set_blob(nvs_handle_t handle, const char* key, const void* value, size_t length);
esp_err_t nvs_get_blob(nvs_handle_t handle, const char* key, void* out_value, size_t* length);
我们看看wifi配网信息的结构体(我们需要的是前面96个字节):
typedef struct {
uint8_t ssid[32]; /**< SSID of target AP. */
uint8_t password[64]; /**< Password of target AP. */
wifi_scan_method_t scan_method; /**< do all channel scan or fast scan */
......
} wifi_sta_config_t;
在狄夜的基础上修改成3个独立的函数(代码中做了详尽的注释):
typedef enum {
wifi_unconfiged = 0,
wifi_configed = 0xAA,
}wifi_info_storage_t;
#define ID_AND_PWD_LEN (32+64)
/**********************************************
* *函数名:clearWifiConfigFlag
* *功能描述:清除配网标记,如果运行这个函数,可以配合esp_restart(),复位系统。重新配网
* * -- 主要是取代nvs_flash_erase()函数,这个函数把所有的数据都擦除,是不对的。
* *******************************************/
void clearWifiConfigFlag(void)
{
nvs_handle my_handle;
// 0.打开
nvs_open("WIFI_CONFIG", NVS_READWRITE, &my_handle);
// 1.写入标记 0x00,清除配网标记
nvs_set_u8(my_handle, "WifiConfigFlag", wifi_unconfiged);
// 2.提交 并保存表的内容
ESP_ERROR_CHECK(nvs_commit(my_handle));
// 3.关闭nvs退出
nvs_close(my_handle);
}
//保存wifi配置参数结构体变量wifi_config到nvs
static void saveWifiConfig(wifi_config_t *wifi_config)
{
nvs_handle my_handle;
// 0.打开
nvs_open("WIFI_CONFIG", NVS_READWRITE, &my_handle);
// 1.写入标记 0xaa,表示已经配过网
nvs_set_u8(my_handle, "WifiConfigFlag", wifi_configed);
// 2.写入AP ID和AP password
ESP_ERROR_CHECK(nvs_set_blob(my_handle, "wifi_config", wifi_config, ID_AND_PWD_LEN));
// 3.提交 并保存表的内容
ESP_ERROR_CHECK(nvs_commit(my_handle));
// 4.关闭nvs退出
nvs_close(my_handle);
}
//从nvs中读取wifi配置到给定的sta_config结构体变量
static esp_err_t readWifiConfig(wifi_config_t *sta_config)
{
nvs_handle my_handle;
unsigned char u8WifiConfigVal;
// 0.打开
nvs_open("WIFI_CONFIG", NVS_READWRITE, &my_handle);
// 1.读取标志位,并判断
nvs_get_u8(my_handle, "WifiConfigFlag", &u8WifiConfigVal);
if(u8WifiConfigVal != wifi_configed){
// 1.1 没有配过网,关闭nvs,返回错误码
ESP_LOGI(TAG, "no wifi config,read fail!");
nvs_close(my_handle);
return ESP_FAIL;
}else{
// 1.2 进入下个步骤
ESP_LOGI(TAG, "wifi configed ,read ok!");
}
// 2.读取上一次配网的ID,password
uint32_t len = ID_AND_PWD_LEN;
esp_err_t err = nvs_get_blob(my_handle, "wifi_config", sta_config, &len);
ESP_LOGI(TAG, "readout SSID:%s", sta_config->sta.ssid);
ESP_LOGI(TAG, "readout PASSWORD:%s", sta_config->sta.password);
// 3.关闭nvs退出
nvs_close(my_handle);
return err;
}
2.增加LED表示状态和按键重新配网
这部分两位网友的内容差不多,反正天下文章一大抄,不知道是否英雄所见略同。
2.1LED表示联网的状态
状态如下:
- 等待配网,1Hz闪烁;
- 正在配网,5Hz闪烁;
- 配网完成,常亮。
原理就是使用定时器中断,每中断一次改变一次灯的状态:
1、等待配网时,定时器500ms中断一次;
2、正在配网时,定时器100ms中断一次;
3、配网完成,删除定时器,LED常亮。
下面的代码主要抄自 Mr_VitaminC:
//--------------- smartconfig_led.c ---------------//
#define WIFI_STATUS_LED_GPIO 2
static const char* TAG = "WIFI_STATUS_LED";
static esp_timer_handle_t smartconfig_led_soft_timer;
//定时器回调里实现灯的闪烁
static void periodled_timer_callback(void* arg)
{
static uint8_t s_LEDToggle = 0;
s_LEDToggle = ~s_LEDToggle;
if(s_LEDToggle)
{
gpio_set_level(WIFI_STATUS_LED_GPIO, 0);
}
else
{
gpio_set_level(WIFI_STATUS_LED_GPIO, 1);
}
}
static void handle_smartconfig_led_status(Wifi_Status_t WifiState)
{
static uint8_t s_WifiDisconnectNotice;
switch(WifiState)
{
case WIFI_DISCONNECT:
//没有连上网的状态下创建并开启软件定时器,并且确保只创建一次,不然会报错
if(s_WifiDisconnectNotice == 0)
{ esp_timer_create_args_t periodled_timer_args = {
.callback = &periodled_timer_callback,
/* name is optional, but may help identify the timer when debugging */
.name = "periodled"
};
ESP_ERROR_CHECK(esp_timer_create(&periodled_timer_args, &smartconfig_led_soft_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(smartconfig_led_soft_timer, ConnectStatusInterval));
s_WifiDisconnectNotice = 1;
}
break;
case WIFI_CONNECTING:
//正在联网的时候LED快闪
if(s_WifiDisconnectNotice == 1)
{
ESP_ERROR_CHECK(esp_timer_stop(smartconfig_led_soft_timer));
}
ESP_LOGI(TAG,"Delegate wifi is connecting\n");
ESP_ERROR_CHECK(esp_timer_start_periodic(smartconfig_led_soft_timer, DisconnectStatusInterval));
break;
case WIFI_CONNECTED:
//连上网后LED常亮,并注销软件定时器,减少消耗
gpio_set_level(WIFI_STATUS_LED_GPIO, 1);
if(s_WifiDisconnectNotice == 1)
{
ESP_ERROR_CHECK(esp_timer_stop(smartconfig_led_soft_timer));
ESP_ERROR_CHECK(esp_timer_delete(smartconfig_led_soft_timer));
s_WifiDisconnectNotice = 0;
}
ESP_LOGI(TAG,"Delegate wifi is connected\n");
break;
default:
break;
}
}
//LED管脚初始化
void wifi_status_led_init(void)
{
gpio_config_t smartconfig_IO_conf;
smartconfig_IO_conf.intr_type = GPIO_PIN_INTR_DISABLE;
smartconfig_IO_conf.mode = GPIO_MODE_OUTPUT;
smartconfig_IO_conf.pin_bit_mask = 1 << WIFI_STATUS_LED_GPIO;
smartconfig_IO_conf.pull_down_en = 0;
smartconfig_IO_conf.pull_up_en = 0;
gpio_config(&smartconfig_IO_conf);
gpio_set_level(WIFI_STATUS_LED_GPIO, 1);
delegate_wifi_disconnect_status();
}
//通知网络未连接
void delegate_wifi_disconnect_status(void)
{
ESP_LOGI(TAG,"Delegate wifi is disconnect\n");
handle_smartconfig_led_status(WIFI_DISCONNECT);
}
//通知网络已连接
void delegate_wifi_connected_status(void)
{
ESP_LOGI(TAG,"Delegate wifi has connected\n");
handle_smartconfig_led_status(WIFI_CONNECTED);
}
//通知网络正在连接中
void delegate_wifi_connecting_status(void)
{
ESP_LOGI(TAG,"Delegate wifi is connecting\n");
handle_smartconfig_led_status(WIFI_CONNECTING);
}
<smartconfig_led.h>
//--------------- smartconfig_led.h ---------------//
#ifndef __SMARTCONFIG_LED_H__
#define __SMARTCONFIG_LED_H__
#ifdef __cplusplus
extern "C" {
#endif
#define ConnectStatusInterval 1000000 //单位为us
#define DisconnectStatusInterval 100000
typedef enum{
WIFI_DISCONNECT = 1,
WIFI_CONNECTING,
WIFI_CONNECTED,
}Wifi_Status_t;
void smartconfig_button_init();
void wifi_status_led_init(void);
void delegate_wifi_disconnect_status(void);
void delegate_wifi_connected_status(void);
void delegate_wifi_connecting_status(void);
void clearWifiConfigFlag(void);
#ifdef __cplusplus
}
#endif
#endif
2.2 按键清除配网信息,并重启系统,再次配网
如果没有配过网,上电时会进入自动配网;如果已经配过网,换了一个wifi环境,需要重新配网,就可以执行这个操作。
具体流程就是:
- 按住按键超过1秒,松开按键;
- 清除配网标志,clearWifiConfigFlag();
- 重启系统,esp_restart();
下面的代码主要抄自 Mr_VitaminC:
typedef enum {
KEY_SHORT_PRESS = 1,
KEY_LONG_PRESS =2,
} alink_key_t;
#define GPIO_LED_IO 2
#define GPIO_LED_PIN_SEL 1ULL<<GPIO_LED_IO
#define GPIO_KEY_IO 0
#define GPIO_KEY_PIN_SEL 1ULL<<GPIO_KEY_IO
static const char *TAG = "smartconfig_example";
static xQueueHandle gpio_evt_queue = NULL;
//获取系统时间
static int64_t get_time(){
struct timeval tv_now;
gettimeofday(&tv_now, NULL);
int64_t time_us = (int64_t)tv_now.tv_sec * 1000000L + (int64_t)tv_now.tv_usec;
return time_us;
}
//按键中断处理函数
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
uint32_t gpio_num = (uint32_t) arg;
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
//任务处理
static void led_task(void* arg)
{
uint32_t io_num;
BaseType_t press_key = pdFALSE;
BaseType_t lift_key = pdFALSE;
int backup_time = 0;
for(;;) {
if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
// printf("GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));
//记录下用户按下按键的时间点
if (gpio_get_level(io_num) == 0) {
press_key = pdTRUE;
backup_time = get_time();
//如果当前GPIO口的电平已经记录为按下,则开始减去上次按下按键的时间点
} else if (press_key) {
//记录抬升时间点
lift_key = pdTRUE;
backup_time = get_time() - backup_time;
}
//按下标志位和按键弹起标志位都为1时候
if (press_key & lift_key) {
press_key = pdFALSE;
lift_key = pdFALSE;
//大于1秒为长按
if (backup_time > 1000000) {
printf("长按 ... \r\n");
//按键长按,清除配网信息并重启
clearWifiConfigFlag();
//ESP_ERROR_CHECK(nvs_flash_erase());这里不用全部数据都清除
ESP_LOGI(TAG,"Set Restart now.\n");
esp_restart();
} else {
printf("短按 ... \r\n");
}
}
}
}
}
void smartconfig_button_init(void)
{//按键中断配置
gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_ANYEDGE;
io_conf.pin_bit_mask = GPIO_KEY_PIN_SEL;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_up_en = 1;
gpio_config(&io_conf);
//创建消息队列处理引脚中断事件
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
//创建任务
xTaskCreate(led_task, "led_task", 2048, NULL, 10, NULL);
//第一个处理器核安装中断处理程序
gpio_install_isr_service(0);
//添加中断处理函数
gpio_isr_handler_add(GPIO_KEY_IO, gpio_isr_handler, (void*) GPIO_KEY_IO);
printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());
}
3.将存储、LED、按键整合到smart_config例程中
官方例程是没有保存ID和password,一上电就进入智能配网;现在有了保存功能,上电时,判断一下是否需要进入智能配网:
static void initialise_wifi(void)
{
......
if(ESP_OK == readWifiConfig(&wifi_config))
{// 1.已经配过网,直接连AP
wifi_config.sta .threshold.authmode = WIFI_AUTH_WPA2_PSK;
/* 设置WiFi的工作模式为 STA */
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
/* 设置WiFi连接的参数,主要是ssid和password */
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
/* 启动WIFI 驱动程序*/
ESP_ERROR_CHECK(esp_wifi_start());
/* 启动WiFi连接到 AP*/
ESP_ERROR_CHECK(esp_wifi_connect());
} else {
// 2. 没有配过网,进入智能配网
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_start() );
xTaskCreate(smartconfig_example_task, "smartconfig_example_task", 4096, NULL, 3, NULL);
}
}
在wifi的事件机制中,esp_wifi_start()会触发一个WIFI_EVENT_STA_START事件,然后创建smartconfig_example_task任务;由于我们在配过网的情况下,也有调用esp_wifi_start(),但这时是不能进入智能配网的,所以要删除这部分代码。
LED状态改变的代码在注释中有说明。
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) {
// 1.连接成功,LED常亮
xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
delegate_wifi_connected_status();
} 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) {
// 2.准备连接,LED以5Hz闪烁
ESP_LOGI(TAG, "Found channel");
delegate_wifi_connecting_status();
} else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD) {
ESP_LOGI(TAG, "Got SSID and password");
//wifi_config_t wifi_config;
smartconfig_event_got_ssid_pswd_t *evt = (smartconfig_event_got_ssid_pswd_t *)event_data;
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();
// 3.运行到此处,可以保存id,password。但是如果密码错误,还是连不上网。
saveWifiConfig(&wifi_config);
} else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE) {
xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT);
}
}
4.本例子的硬件IO说明
LED – IO2
按键 – IO0
5.清除配网信息后重新配网的log信息
L2:第2行,接收到按键长按后松开的信息,清除配网并重启;
L69:第69行,进入主函数,LED以1Hz闪烁;
L96:第96行,在函数readWifiConfig 里面判断到没有配网信息,要重新配网;
L111-L113:第111,112,113行,开始接收到配网软件的信息,准备配网,LED以5Hz闪烁;
L141,L142:第141,142行,获取ip地址成功,表示配网成功,LED常亮。
[0;32mI (48953) smartconfig_example: Set Restart now.
[0m
I (48953) wifi:state: run -> init (0)
I (48953) wifi:pm stop, total sleep time: 24157576 us / 25528420 us
I (48953) wifi:new:<11,0>, old:<11,0>, ap:<255,255>, sta:<11,0>, prof:1
W (48963) wifi:hmac tx: ifx0 stop, discard
I (48993) wifi:flush txq
I (48993) wifi:stop sw txq
I (48993) wifi:lmac stop hw txq
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:6608
load:0x40078000,len:14788
ho 0 tail 12 room 4
load:0x40080400,len:3792
entry 0x40080694
[0;32mI (29) boot: ESP-IDF v4.4.1 2nd stage bootloader[0m
[0;32mI (29) boot: compile time 08:42:02[0m
[0;32mI (29) boot: chip revision: 1[0m
[0;32mI (32) boot_comm: chip revision: 1, min. bootloader chip revision: 0[0m
[0;32mI (39) boot.esp32: SPI Speed : 40MHz[0m
[0;32mI (43) boot.esp32: SPI Mode : DIO[0m
[0;32mI (48) boot.esp32: SPI Flash Size : 4MB[0m
[0;32mI (52) boot: Enabling RNG early entropy source...[0m
[0;32mI (58) boot: Partition Table:[0m
[0;32mI (61) boot: ## Label Usage Type ST Offset Length[0m
[0;32mI (69) boot: 0 nvs WiFi data 01 02 00009000 00006000[0m
[0;32mI (76) boot: 1 phy_init RF data 01 01 0000f000 00001000[0m
[0;32mI (84) boot: 2 factory factory app 00 00 00010000 00100000[0m
[0;32mI (91) boot: End of partition table[0m
[0;32mI (95) boot_comm: chip revision: 1, min. application chip revision: 0[0m
[0;32mI (102) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=16230h ( 90672) map[0m
[0;32mI (144) esp_image: segment 1: paddr=00026258 vaddr=3ffb0000 size=0385ch ( 14428) load[0m
[0;32mI (150) esp_image: segment 2: paddr=00029abc vaddr=40080000 size=0655ch ( 25948) load[0m
[0;32mI (161) esp_image: segment 3: paddr=00030020 vaddr=400d0020 size=79d8ch (499084) map[0m
[08:01:39.132]收←◆[0;32mI (342) esp_image: segment 4: paddr=000a9db4 vaddr=4008655c size=0df44h ( 57156) load[0m
[0;32mI (365) esp_image: segment 5: paddr=000b7d00 vaddr=50000000 size=00010h ( 16) load[0m
[0;32mI (375) boot: Loaded app from partition at offset 0x10000[0m
[0;32mI (376) boot: Disabling RNG early entropy source...[0m
[0;32mI (388) cpu_start: Pro cpu up.[0m
[0;32mI (388) cpu_start: Starting app cpu, entry point is 0x40081190[0m
[0;32mI (374) cpu_start: App cpu up.[0m
[0;32mI (402) cpu_start: Pro cpu start user code[0m
[0;32mI (402) cpu_start: cpu freq: 160000000[0m
[0;32mI (402) cpu_start: Application information:[0m
[0;32mI (407) cpu_start: Project name: smart_config[0m
[0;32mI (412) cpu_start: App version: 1[0m
[0;32mI (416) cpu_start: Compile time: Jun 28 2022 08:41:40[0m
[0;32mI (423) cpu_start: ELF file SHA256: 932de1cf28244c8c...[0m
[0;32mI (429) cpu_start: ESP-IDF: v4.4.1[0m
[0;32mI (434) heap_init: Initializing. RAM available for dynamic allocation:[0m
[0;32mI (441) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM[0m
[0;32mI (447) heap_init: At 3FFB77A8 len 00028858 (162 KiB): DRAM[0m
[0;32mI (453) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM[0m
[0;32mI (459) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM[0m
[0;32mI (466) heap_init: At 400944A0 len 0000BB60 (46 KiB): IRAM[0m
[0;32mI (473) spi_flash: detected chip: generic[0m
[0;32mI (477) spi_flash: flash io: dio[0m
[0;32mI (482) cpu_start: Starting scheduler on PRO CPU.[0m
[0;32mI (0) cpu_start: Starting scheduler on APP CPU.[0m
[0;32mI (551) gpio: GPIO[2]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 [0m
[0;32mI (551) WIFI_STATUS_LED: Delegate wifi is disconnect
[0m
[0;32mI (561) gpio: GPIO[0]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:3 [0m
Minimum free heap size: 271476 bytes
I (581) wifi:wifi driver task: 3ffc106c, prio:23, stack:6656, core=0
[0;32mI (581) system_api: Base MAC address is not set[0m
[0;32mI (581) system_api: read default base MAC address from EFUSE[0m
I (601) wifi:wifi firmware version: 63017e0
I (601) wifi:wifi certification version: v7.0
I (601) wifi:config NVS flash: enabled
I (601) wifi:config nano formating: disabled
I (611) wifi:Init data frame dynamic rx buffer num: 32
I (611) wifi:Init management frame dynamic rx buffer num: 32
I (621) wifi:Init management short buffer num: 32
I (621) wifi:Init dynamic tx buffer num: 32
I (621) wifi:Init static rx buffer size: 1600
I (631) wifi:Init static rx buffer num: 10
I (631) wifi:Init dynamic rx buffer num: 32
[0;32mI (641) wifi_init: rx ba win: 6[0m
[0;32mI (641) wifi_init: tcpip mbox: 32[0m
[0;32mI (641) wifi_init: udp mbox: 6[0m
[0;32mI (651) wifi_init: tcp mbox: 6[0m
[0;32mI (651) wifi_init: tcp tx win: 5744[0m
[0;32mI (661) wifi_init: tcp rx win: 5744[0m
[0;32mI (661) wifi_init: tcp mss: 1440[0m
[0;32mI (661) wifi_init: WiFi IRAM OP enabled[0m
[0;32mI (671) wifi_init: WiFi RX IRAM OP enabled[0m
[0;32mI (671) smartconfig_example: no wifi config,read fail![0m
[0;32mI (681) phy_init: phy_version 4670,719f9f6,Feb 18 2021,17:07:07[0m
[08:01:39.558]收←◆I (791) wifi:mode : sta (94:b9:7e:d5:42:cc)
I (801) wifi:enable tsf
[08:01:39.607]收←◆I (851) smartconfig: SC version: V3.0.1
[08:01:43.708]收←◆I (4941) wifi:ic_enable_sniffer
I (4951) smartconfig: Start to find channel...
[0;32mI (4951) smartconfig_example: Scan done[0m
[08:11:15.848]收←◆I (576991) smartconfig: TYPE: AIRKISS
I (576991) smartconfig: T|PHONE MAC: c4:06:83:49:a5:da
I (576991) smartconfig: T|AP MAC:06:ca:18:76:50:77
I (576991) smartconfig: Found channel on 11-0. Start to get ssid and password...
[0;32mI (577001) smartconfig_example: Found channel[0m
[0;32mI (577001) WIFI_STATUS_LED: Delegate wifi is connecting
[0m
[0;32mI (577011) WIFI_STATUS_LED: Delegate wifi is connecting
[0m
[08:11:18.783]收←◆I (579921) smartconfig: T|pswd: 12346789
I (579921) smartconfig: T|ssid: vivohyc
I (579921) wifi:ic_disable_sniffer
[0;32mI (579921) smartconfig_example: Got SSID and password[0m
[0;32mI (579931) smartconfig_example: SSID:vivohyc[0m
[0;32mI (579931) smartconfig_example: PASSWORD:12346789[0m
[08:11:18.934]收←◆I (580071) wifi:new:<11,0>, old:<11,0>, ap:<255,255>, sta:<11,0>, prof:1
[08:11:20.083]收←◆I (581221) wifi:state: init -> auth (b0)
I (581231) wifi:state: auth -> assoc (0)
I (581251) wifi:state: assoc -> run (10)
[08:11:20.136]收←◆I (581271) wifi:connected with vivohyc, aid = 2, channel 11, BW20, bssid = 06:ca:18:76:50:77
I (581271) wifi:security: WPA2-PSK, phy: bgn, rssi: -46
I (581301) wifi:pm start, type: 1
I (581301) wifi:AP's beacon interval = 102400 us, DTIM period = 2
[08:11:20.928]收←◆[0;32mI (582071) esp_netif_handlers: sta ip: 192.168.102.174, mask: 255.255.255.0, gw: 192.168.102.137[0m
[0;32mI (582071) WIFI_STATUS_LED: Delegate wifi has connected
[0m
[0;32mI (582
[08:11:20.960]收←◆071) smartconfig_example: WiFi Connected to ap[0m
[0;32mI (582071) WIFI_STATUS_LED: Delegate wifi is connected
[0m
[08:11:23.940]收←◆[0;32mI (585081) smartconfig_example: smartconfig over[0m