- 物联网 ESP32 教程
- 首页
- 物联网简述
- ESP32 介绍
- 在 Arduino IDE 中安装 ESP32 开发板
- 设置 RTOS 用于双核和多线程操作
- ESP32 与 MPU6050 接口连接
- ESP32 与模拟传感器接口连接
- ESP32 偏好设置
- ESP32 SPIFFS 存储器(芯片自带的迷你 SD 卡)
- ESP32 与 OLED 显示屏接口连接
- ESP32 上的 WiFi
- 使用 HTTP 通过 WiFi 传输数据
- 使用 HTTPS 通过 WiFi 传输数据
- 使用 MQTT 通过 WiFi 传输数据
- 通过蓝牙传输数据
- 使用 NTP 客户端获取当前时间
- 执行 ESP32 固件的(OTA)更新
- ESP32 的应用
- 开发人员的后续步骤
- 物联网 ESP32 有用资源
- 快速指南
- 有用资源
- 讨论
ESP32 偏好设置
非易失性存储器是嵌入式系统的重要需求。通常,我们希望芯片即使在电源循环之间也能记住一些事情,例如设置变量、WiFi凭据等。如果每次设备进行电源重置都必须执行设置或配置,那将非常不方便。ESP32 有两种常用的非易失性存储方法:偏好设置和 SPIFFS。偏好设置通常用于存储键值对,而 SPIFFS(SPI Flash 文件系统)顾名思义,用于存储文件和文档。在本章中,让我们关注偏好设置。
偏好设置存储在主闪存的一个区域中,类型为数据,子类型为nvs。nvs代表非易失性存储器。默认情况下,为偏好设置保留 20 KB 的空间,因此请不要尝试在偏好设置中存储大量庞大的数据。对于庞大的数据,请使用 SPIFFS(SPIFFS 默认保留 1.5 MB 的空间)。在偏好设置中可以存储哪些类型的键值对?让我们通过示例代码来了解。
代码演练
我们将使用提供的示例代码。转到文件 -> 示例 -> 偏好设置 -> StartCounter。它也可以在GitHub上找到。
此代码记录 ESP32 重置了多少次。因此,每次它唤醒时,它都会从偏好设置中获取现有计数,将其加一,并将更新后的计数保存回偏好设置。然后它重置 ESP32。您可以通过 ESP32 上的打印语句看到,计数的值在重置之间不会丢失,它确实是持久的。
此代码包含大量的注释,因此在很大程度上是不言自明的。但是,让我们逐步浏览代码。
我们首先包含 Preferences 库。
#include <Preferences.h>
接下来,我们创建一个 Preferences 类的对象。
Preferences preferences;
现在让我们逐行查看 setup 函数。我们首先初始化 Serial。
void setup() { Serial.begin(115200); Serial.println();
接下来,我们使用命名空间打开偏好设置。现在,将偏好设置存储想象成一个银行储物柜室。有很多储物柜,你一次打开一个。命名空间就像储物柜的名称。在每个储物柜中,都有您可以访问的键值对。如果您提到的储物柜名称不存在,则会创建它,然后您可以向该储物柜添加键值对。为什么会有不同的储物柜?为了避免名称冲突。假设您有一个使用偏好设置存储凭据的 WiFi 库,还有一个也使用偏好设置存储凭据的蓝牙库。假设这两个库由不同的开发者开发。如果两者都使用相同的键名credentials怎么办?这显然会造成很大的混乱。但是,如果两者都在不同的储物柜中存储键值,则根本不会有任何混乱。
// Open Preferences with my-app namespace. Each application module, library, etc // has to use a namespace name to prevent key name collisions. We will open storage in // RW-mode (second parameter has to be false). // Note: Namespace name is limited to 15 chars. preferences.begin("my−app", false);
preferences.begin()的第二个参数false表示我们希望同时读取和写入此储物柜。如果是 true,我们只能读取储物柜,而不能写入。此外,如注释中所述,命名空间的长度不应超过 15 个字符。
接下来,代码中有一些已注释的语句,您可以根据需要使用它们。一个允许您清除储物柜,另一个帮助您从储物柜中删除特定的键值对(键为“counter”)。
// Remove all preferences under the opened namespace //preferences.clear(); // Or remove the counter key only //preferences.remove("counter");
下一步,我们获取与键“counter”关联的值。现在,当您第一次运行此程序时,可能不存在这样的键。因此,我们还提供 0 作为preferences.getUInt()函数的参数作为默认值。这告诉 ESP32,如果键“counter”不存在,则创建一个新的键值对,键为“counter”,值为0。另请注意,我们使用getUInt是因为该值是无符号整型。根据值的类型,需要调用其他函数,如getFloat、getString等。完整的选项列表可以在这里找到。
unsigned int counter = preferences.getUInt("counter", 0);
接下来,我们将此计数加一,并将其打印到串口监视器上。
// Increase counter by 1 counter++; // Print the counter to Serial Monitor Serial.printf("Current counter value: %u\n", counter);
然后我们将此更新后的值存储回非易失性存储器。我们基本上是在更新键“counter”的值。下次 ESP32 读取键“counter”的值时,它将获取递增后的值。
// Store the counter to the Preferences preferences.putUInt("counter", counter);
最后,我们关闭偏好设置储物柜并在 10 秒钟后重新启动 ESP32。
// Close the Preferences preferences.end(); // Wait 10 seconds Serial.println("Restarting in 10 seconds..."); delay(10000); // Restart ESP ESP.restart(); }
因为我们在进入循环之前重新启动了 ESP32,所以循环永远不会执行。因此,它保持为空。
void loop() {}
此示例很好地演示了 ESP32 偏好设置存储确实是持久的。当您检查串口监视器上的打印语句时,您可以看到计数在连续重置之间递增。这对于局部变量来说是不可能的。这只有通过偏好设置使用非易失性存储才能实现。