在ESP32 NVS中保存wifi ssid和password,并记录设备重启次数

本文介绍ESP32使用NVS存储WiFi SSID和密码的方法,并演示如何记录设备重启次数。通过示例代码展示了NVS的基本操作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接上篇文章,增加了在NVS中保存wifi ssid和password的代码:

运行结果如图:
在这里插入图片描述

1.nvs初始化:

在这里插入图片描述

2.记录设备重启次数:

在这里插入图片描述

3.保存wifi ssid和password

在这里插入图片描述

4.关闭NVS:

在这里插入图片描述

完整代码如下:

/* Hello World Example

This example code is in the Public Domain (or CC0 licensed, at your option.)

Unless required by applicable law or agreed to in writing, this
software is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h> //michael add for NVS test
#include “sdkconfig.h”
#include “freertos/FreeRTOS.h”
#include “freertos/task.h”
#include “esp_system.h”
#include “esp_spi_flash.h”
#include “nvs_flash.h” //michael add for NVS test
#include “esp_log.h”//michael add for NVS test

void app_main(void)
{

vTaskDelay(1000/portTICK_PERIOD_MS);//阻止flash esp32后下面程序被立即执行

/* 初始化nvs*/
char * michael_nvs_namespace = "michael2";//namespace类似windows的文件夹
nvs_flash_init();//类似windows插入U盘
nvs_handle_t michael_handle;
nvs_open(michael_nvs_namespace,NVS_READWRITE,&michael_handle);//取得namespace句柄,类似windows打开文件夹

/* 下面这段是在nvs中记录设备重启次数*/

uint32_t counter_val = 0;//value类似windows的文件内容
char * counter_key = "counter";//key类似windows的文件名
nvs_get_u32(michael_handle,counter_key,&counter_val);
ESP_LOGI("nvs","KEY:VALUE %s:%d",counter_key,counter_val);

counter_val = counter_val + 1;
nvs_set_u32(michael_handle,counter_key,counter_val);
nvs_commit(michael_handle);//立刻执行nvs_set动作

/* 下面这段是在nvs中记录wifi ssid和password*/
uint32_t max_ap = 2;
typedef struct {
    char ssid[50];
    char password[50];
} ap_t;

ap_t aps_set[max_ap];

memset(aps_set,0,sizeof(aps_set));

for (int i=0;i<max_ap;i++) {
    strcpy(aps_set[i].ssid, "michaelap");
    strcpy(aps_set[i].password, "123456");
}

nvs_set_blob(michael_handle,"aps",aps_set,sizeof(aps_set));//写入ssid和password
nvs_commit(michael_handle);//立刻执行nvs_set动作
ap_t aps_get[max_ap];
size_t length = sizeof(aps_get);
nvs_get_blob(michael_handle,"aps",aps_get,&length);//读出ssid和password,用于后面打印

for (int i=0;i<max_ap;i++) {
    ESP_LOGI("wifi","SSID:PASSORD %s:%s", aps_get[i].ssid, aps_get[i].password);
}

/* 关闭nvs*/
nvs_close(michael_handle);//释放namespace句柄,类似windows关闭文件夹
nvs_flash_deinit();//类似windows拔出U盘

/* 下面这段是Hello world例程*/
printf("Hello world!\n");
/* Print chip information */
esp_chip_info_t chip_info;
esp_chip_info(&chip_info);
printf("This is %s chip with %d CPU core(s), WiFi%s%s, ",
        CONFIG_IDF_TARGET,
        chip_info.cores,
        (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
        (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");

printf("silicon revision %d, ", chip_info.revision);

printf("%dMB %s flash\n", spi_flash_get_chip_size() / (1024 * 1024),
        (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");

printf("Minimum free heap size: %d bytes\n", esp_get_minimum_free_heap_size());

for (int i = 10; i >= 0; i--) {
    printf("Restarting in %d seconds...\n", i);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
}
printf("Restarting now.\n");
fflush(stdout);
esp_restart();

}

<think>首先,用户的问题是关于在ESP32-S3上使用NVS(非易失性存储)存储WiFi配置信息的教程或示例代码。我需要根据系统指令来构建回答。 系统指令关键点: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如:[^1] - 回答结构清晰,帮助用户逐步解决问题,尽量保证回答真实可靠。 - 参考站内引用,但用户提供了引用内容,我需要基于这些来回答问题。 用户提供的引用: - [^1]: 关于ESP32-S3示例项目的工程结构。 - [^2]: 关于WiFi初始化的官方方式。 - [^3]: 关于ESP32-S3使用HTTP协议获取天气数据的示例。 用户的问题是:“我想在ESP32 S3上使用NVS存储WiFi信息的方法 请问ESP32 S3 NVS 存储 WiFi 配置信息 教程 或 示例代码” 所以,我需要提供如何使用NVS存储WiFi配置信息的教程或代码示例。NVS是ESP-IDF框架中的一个组件,用于在闪存中存储键值对数据。 步骤: 1. **理解NVS**:NVS允许在ESP32上持久化存储数据。WiFi配置如SSID密码可以存储在这里。 2. **相关API**:在ESP-IDF中,使用nvs_flash.h头文件来操作NVS。 3. **初始化NVS**:在应用启动时初始化NVS分区。 4. **存储读取数据**:使用nvs_set_*nvs_get_*函数来存储读取字符串或其他数据类型。 5. **集成WiFi配置**:在WiFi初始化部分,从NVS读取存储的SSID密码,而不是硬编码。 用户引用中提到了WiFi初始化HTTP示例,我可以参考这些来构建答案。 生成相关问题:在回答结束后,添加几个相关问题,如示例所示。 回答结构: - 逐步解释过程。 - 提供代码示例。 - 确保代码语法正确(使用代码块)。 - 使用中文。 - 添加引用标识。 可能的引用点: - 基于用户提供的引用[^1],[^2],[^3],我可以引用它们,但需要自然地融入。 - 例如,在提到ESP-IDF框架时引用[^1],在WiFi部分引用[^2]。 现在,构建回答大纲: 1. **介绍NVSWiFi存储**:简要解释NVS是什么,为什么用它存储WiFi配置。 2. **初始化NVS**:如何设置NVS分区。 3. **存储WiFi配置**:代码示例存储SSID密码。 4. **读取WiFi配置**:代码示例读取使用在WiFi连接中。 5. **完整示例**:提供一个简单的代码片段。 6. **注意事项**:如错误处理、NVS命名空间等。 7. **生成相关问题**:在结尾添加相关问题。 代码示例:使用C语言,因为ESP-IDF是基于C的。 确保LaTeX:在这个上下文中,可能没有数学表达式,但如果提到变量,使用$...$。例如,变量名如$ssid$。 最终,生成相关问题: 1. 如何优化NVS存储以提高性能? 2. NVS存储的容量限制是什么? 3. 如何在ESP32-S3上处理NVS分区损坏? 现在,写出回答。</think>### 在 ESP32-S3 上使用 NVS 存储 WiFi 配置信息的教程 在 ESP32-S3 开发中,使用非易失性存储(NVS保存 WiFi 配置信息(如 SSID 密码)是一种高效且持久化的方法。NVS 是 ESP-IDF 框架内置的组件,允许在闪存中以键值对形式存储数据,确保设备重启后配置不丢失。以下教程基于 ESP-IDF 官方示例[^1][^2],逐步指导您实现此功能。整个过程包括初始化 NVS、存储读取 WiFi 配置,集成到 WiFi 连接流程中。 #### 步骤 1: 初始化 NVS 分区 在应用启动时,必须先初始化 NVS 分区。这通常在 `app_main()` 函数中完成。NVS 分区用于管理闪存存储空间,确保数据持久化。 ```c #include "nvs_flash.h" void app_main() { // 初始化 NVS 分区 esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { // 如果分区损坏或版本不匹配,擦除重新初始化 ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); // 后续步骤:存储或读取 WiFi 配置 } ``` - **关键点**:使用 `nvs_flash_init()` 初始化默认分区。如果初始化失败(如闪存损坏),需先擦除分区再重试。这确保了 NVS 的可靠性[^1]。 #### 步骤 2: 存储 WiFi 配置到 NVS 使用 NVS API 将 WiFi SSID 密码存储为字符串键值对。您可以在设备首次配置 WiFi 时调用此函数(例如,通过串口输入或 Web 界面)。 ```c #include "nvs.h" void save_wifi_config(const char *ssid, const char *password) { nvs_handle_t my_handle; // 打开 NVS 命名空间 "wifi_config",用于隔离 WiFi 数据 esp_err_t err = nvs_open("wifi_config", NVS_READWRITE, &my_handle); if (err != ESP_OK) { printf("Error opening NVS: %s\n", esp_err_to_name(err)); return; } // 存储 SSID 密码 err = nvs_set_str(my_handle, "ssid", ssid); if (err != ESP_OK) printf("Failed to save SSID\n"); err = nvs_set_str(my_handle, "password", password); if (err != ESP_OK) printf("Failed to save password\n"); // 提交更改到闪存 err = nvs_commit(my_handle); if (err != ESP_OK) printf("Commit failed\n"); nvs_close(my_handle); // 关闭句柄 printf("WiFi config saved: SSID=%s, Password=%s\n", ssid, password); } ``` - **参数说明**: - `ssid`:WiFi 网络名称,例如 `"MyWiFi"`。 - `password`:WiFi 密码,例如 `"secure123"`。 - **注意**:使用 `nvs_set_str()` 存储字符串,通过 `nvs_commit()` 确保数据持久化。命名空间 `"wifi_config"` 帮助组织数据,避免键冲突[^1]。 #### 步骤 3: 从 NVS 读取 WiFi 配置连接 在 WiFi 初始化阶段,从 NVS 读取存储的 SSID 密码,用于建立连接。这基于 ESP-IDF 的 WiFi 初始化流程[^2]。 ```c #include "esp_wifi.h" #include "esp_event.h" #include "esp_log.h" void connect_to_wifi() { nvs_handle_t my_handle; char ssid[32] = {0}; // 缓冲区存储 SSID char password[64] = {0}; // 缓冲区存储密码 // 打开 NVS 命名空间 esp_err_t err = nvs_open("wifi_config", NVS_READONLY, &my_handle); if (err != ESP_OK) { ESP_LOGE("NVS", "Failed to open NVS: %s", esp_err_to_name(err)); return; // 或处理错误,如进入配置模式 } // 读取 SSID 密码 size_t required_size; err = nvs_get_str(my_handle, "ssid", NULL, &required_size); if (err == ESP_OK) { nvs_get_str(my_handle, "ssid", ssid, &required_size); } else { ESP_LOGE("NVS", "SSID not found"); } err = nvs_get_str(my_handle, "password", NULL, &required_size); if (err == ESP_OK) { nvs_get_str(my_handle, "password", password, &required_size); } else { ESP_LOGE("NVS", "Password not found"); } nvs_close(my_handle); // 配置启动 WiFi wifi_config_t wifi_config = { .sta = { .ssid = "", .password = "", }, }; strncpy((char *)wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid)); strncpy((char *)wifi_config.sta.password, password, sizeof(wifi_config.sta.password)); ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); ESP_ERROR_CHECK(esp_wifi_start()); ESP_ERROR_CHECK(esp_wifi_connect()); // 注册事件回调处理连接状态(参考官方示例[^2]) esp_event_handler_instance_t instance; ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance)); ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance)); } // 事件回调函数示例(简化) 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_CONNECTED) { ESP_LOGI("WiFi", "Connected to AP"); } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; ESP_LOGI("WiFi", "Got IP: " IPSTR, IP2STR(&event->ip_info.ip)); } } ``` - **关键点**: - 使用 `nvs_get_str()` 读取数据,先获取大小再复制到缓冲区。 - 集成到官方 WiFi 初始化流程:`esp_wifi_set_config()` 使用从 NVS 读取的配置[^2]。 - 错误处理:如果 NVS 中无数据,设备可进入配置模式(如启动 AP 供用户输入)。 #### 完整示例代码整合 以下是一个简单的 `app_main()` 函数,整合上述步骤。假设设备首次运行时存储配置,后续启动时自动连接。 ```c #include "nvs_flash.h" #include "esp_wifi.h" #include "esp_event.h" #include "esp_log.h" void save_wifi_config(const char *ssid, const char *password); // 步骤 2 的函数 void connect_to_wifi(); // 步骤 3 的函数 void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); // 事件回调 void app_main() { // 初始化 NVS esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); // 检查是否首次运行(示例:通过 NVS 标志) nvs_handle_t handle; bool configured = false; if (nvs_open("sys_config", NVS_READONLY, &handle) == ESP_OK) { uint8_t flag; if (nvs_get_u8(handle, "wifi_configured", &flag) == ESP_OK && flag == 1) { configured = true; } nvs_close(handle); } if (!configured) { // 首次运行:存储 WiFi 配置(示例值) save_wifi_config("YourSSID", "YourPassword"); // 设置标志 nvs_open("sys_config", NVS_READWRITE, &handle); nvs_set_u8(handle, "wifi_configured", 1); nvs_commit(handle); nvs_close(handle); } // 初始化 WiFi 连接 ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); esp_netif_create_default_wifi_sta(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); connect_to_wifi(); } ``` #### 注意事项 1. **NVS 容量限制**:ESP32-S3 的 NVS 分区默认大小约 20KB,适合存储小型数据。如存储大量配置,需修改分区表。 2. **错误处理**:始终检查 API 返回错误(如 `ESP_ERROR_CHECK()`),防止闪存操作失败导致崩溃。 3. **安全性**:WiFi 密码以明文存储,如需加密,可结合 ESP-IDF 的加密库(如 AES)。 4. **实时更新**:WiFi 配置变更时,调用 `save_wifi_config()` 更新 NVS重启 WiFi 模块。 5. **参考官方资源**:此方法基于 ESP-IDF 示例项目结构[^1] WiFi 初始化流程[^2],确保兼容性。 通过上述步骤,您可以在 ESP32-S3 上高效管理 WiFi 配置,提升设备可靠性用户体验。如需进一步优化,可参考 ESP-IDF 文档中的 NVS 高级用法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值