ESP32开发之路(6)

您所在的位置:网站首页 wi-fi的ssid是什么 ESP32开发之路(6)

ESP32开发之路(6)

2024-07-10 13:34| 来源: 网络整理| 查看: 265

ESP32开发之路(6)—连接到WiFi然后保存ssid和password

本次开发是在Ubuntu下的,使用的模块是GOOUUU-ESP32,使用VSCode编辑项目。代码使用来自esp-idf的例程。

一、为什么要保存ssid和password

在之前的工程(ESP32开发之路(5)—连接到WiFi)我们已经成功通过智能配网连接到wifi了,但是我们发现一个问题,就是如果在程序中写入的ssid和password不能使用的话,我们在ESP32每次重新上电后都需要智能配网,所以我们对程序进行修改,将连接成功后的ssid和password保存下来。

二、NVS的使用

我们可以把NVS的使用类比于一个文件的使用,要操作一个文件,首先需要的就是一个文件描述符,在NVS里,就是NVS操作句柄,我们定义一个NVS操作句柄,

/* 定义一个NVS操作句柄 */ nvs_handle my_HandleNvs;

对文件进行操作,我们需要打开文件,在NVS里对应的就是打开一个命名空间,第一个参数是命名空间的名字,第二个参数是打开方式,我们以读写方式打开,第三个参数就是操作句柄,当打开成功后,就会得到该命名空间的操作句柄;

/* 打开一个NVS命名空间 */ err = nvs_open("WiFi_cfg", NVS_READWRITE, &my_HandleNvs);

命名空间打开成功后,我们往里面写入WiFi更新标志码、ssid和password,写完后我们需要进行提交,就好像文件操作的保存一样,然后关闭命名空间。 我们可以看到,写入函数的第一个参数是操作句柄,第二个参数是需要写入的键值对的键,第三个参数是需要写入的键值对的值。

if (err != ESP_OK) printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err)); else { printf("Done\n"); err = nvs_set_u32(my_HandleNvs,"wifi_update",2048); if(err == ESP_OK) printf("wifi_update set ok \n"); else printf("wifi_update set err \n"); err = nvs_set_str(my_HandleNvs,"wifi_ssid","wifi-esp"); if(err == ESP_OK) printf("wifi_ssid set ok \n"); else printf("wifi_ssid set err \n"); err = nvs_set_str(my_HandleNvs,"wifi_passwd","passwd-esp"); if(err == ESP_OK) printf("wifi_passwd set ok \n"); else printf("wifi_passwd set err \n"); /* 提交*/ err = nvs_commit(my_HandleNvs); } nvs_close(my_HandleNvs);

然后下载烧录,可以看到,写入成功 在这里插入图片描述 然后我们将写入替换成读出

uint32_t wifi_update = 0; char wifi_ssid[33] = { 0 }; char wifi_passwd[65] = { 0 }; size_t len; if (err != ESP_OK) printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err)); else { printf("Done\n"); err = nvs_get_u32(my_HandleNvs,"wifi_update",&wifi_update); if(err == ESP_OK) printf("wifi_update get = %u \n",wifi_update); else printf("wifi_update get err \n"); len = sizeof(wifi_ssid); err = nvs_get_str(my_HandleNvs,"wifi_ssid",wifi_ssid,&len); if(err == ESP_OK) printf("wifi_ssid get ok :%s \n",wifi_ssid); else printf("wifi_ssid get err \n"); len = sizeof(wifi_passwd); err = nvs_get_str(my_HandleNvs,"wifi_passwd",wifi_passwd,&len); if(err == ESP_OK) printf("wifi_passwd get ok : %s \n",wifi_passwd); else printf("wifi_passwd get err \n"); /* 提交*/ err = nvs_commit(my_HandleNvs); } nvs_close(my_HandleNvs);

下载到开发板,运行结果,读出成功

贴上完整代码:

#include #include #include #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_spi_flash.h" #include "esp_wifi.h" #include "driver/gpio.h" #include "nvs_flash.h" #include "esp_smartconfig.h" #define GPIO_LED_NUM 2 void app_main(void) { /* 打印Hello world! */ printf("Hello world!\n"); /* 初始化非易失性存储库 (NVS) */ esp_err_t err = nvs_flash_init(); if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { /* NVS分区被截断,需要删除,然后重新初始化NVS */ ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } ESP_ERROR_CHECK( err ); /* 定义一个NVS操作句柄 */ nvs_handle my_HandleNvs; /* 打开一个NVS命名空间 */ err = nvs_open("WiFi_cfg", NVS_READWRITE, &my_HandleNvs); #if 1 uint32_t wifi_update = 0; char wifi_ssid[33] = { 0 }; char wifi_passwd[65] = { 0 }; size_t len; if (err != ESP_OK) printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err)); else { printf("Done\n"); err = nvs_get_u32(my_HandleNvs,"wifi_update",&wifi_update); if(err == ESP_OK) printf("wifi_update get = %u \n",wifi_update); else printf("wifi_update get err \n"); len = sizeof(wifi_ssid); err = nvs_get_str(my_HandleNvs,"wifi_ssid",wifi_ssid,&len); if(err == ESP_OK) printf("wifi_ssid get ok :%s \n",wifi_ssid); else printf("wifi_ssid get err \n"); len = sizeof(wifi_passwd); err = nvs_get_str(my_HandleNvs,"wifi_passwd",wifi_passwd,&len); if(err == ESP_OK) printf("wifi_passwd get ok : %s \n",wifi_passwd); else printf("wifi_passwd get err \n"); /* 提交*/ err = nvs_commit(my_HandleNvs); } nvs_close(my_HandleNvs); #else if (err != ESP_OK) printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err)); else { printf("Done\n"); err = nvs_set_u32(my_HandleNvs,"wifi_update",2048); if(err == ESP_OK) printf("wifi_update set ok \n"); else printf("wifi_update set err \n"); err = nvs_set_str(my_HandleNvs,"wifi_ssid","wifi-esp"); if(err == ESP_OK) printf("wifi_ssid set ok \n"); else printf("wifi_ssid set err \n"); err = nvs_set_str(my_HandleNvs,"wifi_passwd","passwd-esp"); if(err == ESP_OK) printf("wifi_passwd set ok \n"); else printf("wifi_passwd set err \n"); /* 提交*/ err = nvs_commit(my_HandleNvs); } nvs_close(my_HandleNvs); #endif /* 定义一个gpio配置结构体 */ gpio_config_t gpio_config_structure; /* 初始化gpio配置结构体*/ gpio_config_structure.pin_bit_mask = (1ULL 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)); } /* 打印WiFi名称和密码 */ memcpy(ssid, evt->ssid, sizeof(evt->ssid)); memcpy(password, evt->password, sizeof(evt->password)); printf("SSID:%s \n", ssid); printf("PASSWORD:%s \n", password); /* 将得到的WiFi名称和密码存入NVS*/ nvs_handle wificfg_nvs_handler; ESP_ERROR_CHECK( nvs_open("WiFi_cfg", NVS_READWRITE, &wificfg_nvs_handler) ); ESP_ERROR_CHECK( nvs_set_str(wificfg_nvs_handler,"wifi_ssid",ssid) ); ESP_ERROR_CHECK( nvs_set_str(wificfg_nvs_handler,"wifi_passwd",password) ); ESP_ERROR_CHECK( nvs_commit(wificfg_nvs_handler) ); /* 提交 */ nvs_close(wificfg_nvs_handler); /* 关闭 */ printf("smartconfig save wifi_cfg to NVS .\n"); /* 根据得到的WiFi名称和密码连接WiFi*/ ESP_ERROR_CHECK( esp_wifi_disconnect() ); ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) ); ESP_ERROR_CHECK( esp_wifi_connect() ); } else if (event_id == SC_EVENT_SEND_ACK_DONE) /* 智能配网成功,已经给智能配网设备发送应答*/ { xEventGroupSetBits(wifi_event_group_handler, SMART_CONFIG_BIT); } } } static void smartconfig_init_start(void) { /* 设置智能配网类型为 AirKiss */ ESP_ERROR_CHECK( esp_smartconfig_set_type(SC_TYPE_AIRKISS) ); /* 通过SMARTCONFIG_START_CONFIG_DEFAULT宏 来获取一个默认的smartconfig配置参数结构体变量*/ smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT(); /* 开始智能配网 */ ESP_ERROR_CHECK( esp_smartconfig_start(&cfg) ); printf("smartconfig start ....... \n"); /* 使用事件标志组等待连接建立(WIFI_CONNECTED_BIT)或连接失败(WIFI_FAIL_BIT)事件 */ EventBits_t uxBits; /* 定义一个事件位变量来接收事件标志组等待函数的返回值 */ /* 等待事件标志组,退出前清除设置的事件标志,任意置1就会返回*/ uxBits = xEventGroupWaitBits(wifi_event_group_handler, WIFI_CONNECTED_BIT | SMART_CONFIG_BIT, true, false, portMAX_DELAY); if(uxBits & WIFI_CONNECTED_BIT) { printf("WiFi Connected to ap ok. \n"); esp_smartconfig_stop(); /* 关闭智能配网 */ } if(uxBits & SMART_CONFIG_BIT) { printf("smartconfig over \n"); esp_smartconfig_stop(); /* 关闭智能配网 */ } } void wifi_init_sta(void) { /* 创建一个事件标志组 */ wifi_event_group_handler = xEventGroupCreate(); /* 初始化底层TCP/IP堆栈。在应用程序启动时,应该调用此函数一次。*/ ESP_ERROR_CHECK(esp_netif_init()); /* 创建默认事件循环,*/ ESP_ERROR_CHECK(esp_event_loop_create_default()); /* 创建一个默认的WIFI-STA网络接口,如果初始化错误,此API将中止。*/ esp_netif_create_default_wifi_sta(); /* 使用WIFI_INIT_CONFIG_DEFAULT() 来获取一个默认的wifi配置参数结构体变量*/ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); /* 根据cfg参数初始化wifi连接所需要的资源 */ ESP_ERROR_CHECK(esp_wifi_init(&cfg)); /* 将事件处理程序注册到系统默认事件循环,分别是WiFi事件、IP地址事件及smartconfig事件 */ 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)); nvs_handle wificfg_nvs_handler; /* 定义一个NVS操作句柄 */ char wifi_ssid[32] = { 0 }; /* 定义一个数组用来存储ssid*/ char wifi_passwd[64] = { 0 }; /* 定义一个数组用来存储passwd */ size_t len; /* 打开一个NVS命名空间 */ ESP_ERROR_CHECK( nvs_open("WiFi_cfg", NVS_READWRITE, &wificfg_nvs_handler) ); len = sizeof(wifi_ssid); /* 从NVS中获取ssid */ ESP_ERROR_CHECK( nvs_get_str(wificfg_nvs_handler,"wifi_ssid",wifi_ssid,&len) ); len = sizeof(wifi_passwd); /* 从NVS中获取ssid */ ESP_ERROR_CHECK( nvs_get_str(wificfg_nvs_handler,"wifi_passwd",wifi_passwd,&len) ); ESP_ERROR_CHECK( nvs_commit(wificfg_nvs_handler) ); /* 提交 */ nvs_close(wificfg_nvs_handler); /* 关闭 */ /* 设置WiFi连接的ssid和password参数 */ wifi_config_t wifi_config; bzero(&wifi_config, sizeof(wifi_config_t)); /* 将结构体数据清零 */ memcpy(wifi_config.sta.ssid, wifi_ssid, sizeof(wifi_config.sta.ssid)); memcpy(wifi_config.sta.password, wifi_passwd, sizeof(wifi_config.sta.password)); /* 设置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()); printf("wifi_init_sta finished. \n"); /* 使用事件标志组等待连接建立(WIFI_CONNECTED_BIT)或连接失败(WIFI_FAIL_BIT)事件 */ EventBits_t bits; /* 定义一个事件位变量来接收事件标志组等待函数的返回值 */ bits = xEventGroupWaitBits( wifi_event_group_handler, /* 需要等待的事件标志组的句柄 */ WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, /* 需要等待的事件位 */ pdFALSE, /* 为pdFALSE时,在退出此函数之前所设置的这些事件位不变,为pdFALSE则清零*/ pdFALSE, /* 为pdFALSE时,设置的这些事件位任意一个置1就会返回,为pdFALSE则需全为1才返回 */ portMAX_DELAY); /* 设置为最长阻塞等待时间,单位为时钟节拍 */ /* 根据事件标志组等待函数的返回值获取WiFi连接状态 */ if (bits & WIFI_CONNECTED_BIT) /* WiFi连接成功事件 */ { printf("connected to ap %s OK \n",wifi_ssid); vEventGroupDelete(wifi_event_group_handler); /* 删除WiFi连接事件标志组,WiFi连接成功后不再需要 */ } else if (bits & WIFI_FAIL_BIT) /* WiFi连接失败事件 */ { printf("Failed to connect to ap %s. \n",wifi_ssid); smartconfig_init_start(); /* 开启智能配网 */ } else { printf("UNEXPECTED EVENT \n"); /* 没有等待到事件 */ smartconfig_init_start(); /* 开启智能配网 */ } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3