当前位置:主页 > 查看内容

使用Arduino开发ESP32(18):使用Preferences保存数据

发布时间:2021-06-08 00:00| 位朋友查看

简介:文章目录 目的 基础说明 使用演示 基础读写 键值查询 键值删除 剩余空间获取 支持的数据类型 存在的问题 总结 目的 对于传统的单片机来说我们如果要固化保存小批量的数据的话通常会使用EEPROM在Arduino core for the ESP32中也有相关的功能。不过对于ESP32来……

目的

对于传统的单片机来说我们如果要固化保存小批量的数据的话通常会使用EEPROM,在Arduino core for the ESP32中也有相关的功能。不过对于ESP32来说官方还提供了一种叫做 Preferences 的功能,这个功能也可以用来固化保存数据,并且使用上比EEPROM更加方便。这篇文章将对此做个使用说明。

基础说明

ESP32官方在Flash上建立了一个叫做nvs的分区,而Preferences功能就是建立在该分区上的。Arduino core for the ESP32中默认分区( Partition Scheme: “Default 4MB with spiffs (1.2MB APP /1.5MB SPIFFS)” )情况下nvs分区的大小为 20480 字节,实际可存放的数据大小要小于这个值( 单个数据来说最大为496K或者97%的nvs分区大小 )。
Preferences中数据以键值对(key - value)的方式存储。在键值对之上还有一层命名空间(namespace),不同命名空间中可以有相同的键名存在。在Preferences中命名空间和键名均为字符串,并且长度不大于15个字节

使用演示

基础读写

#include <Preferences.h>

void setup() {
    Serial.begin(115200);
    Serial.println();
    delay(2000);

    Preferences prefs; // 声明Preferences对象
    prefs.begin("mynamespace"); // 打开命名空间mynamespace
    uint32_t count = prefs.getUInt("count", 0); // 获取当前命名空间中的键名为"count"的值
                                                // 如果没有该元素则返回默认值0
    count++; // 累加计数
    Serial.printf("这是系统第 %u 次启动\n", count);
    prefs.putUInt("count", count); // 将数据保存到当前命名空间的"count"键中
    prefs.end(); // 关闭当前命名空间

    delay(5000);
    ESP.restart(); // 重启系统
}

void loop() {}

在这里插入图片描述

键值查询

#include <Preferences.h>

void setup() {
    Serial.begin(115200);
    Serial.println();
    delay(2000);

    Preferences prefs;
    prefs.begin("mynamespace");
    if(prefs.isKey("naisu")) { // 如果当前命名空间中有键名为"naisu"的元素
        Serial.printf("naisu: %s\n\n", prefs.getString("naisu"));
        while (1) {}     
    } else {
        String naisu = prefs.getString("naisu", "555"); // 获取当前命名空间中的键名为"naisu"的值
                                                        // 如果没有该元素则返回默认值"555"
        Serial.printf("naisu: %s\n\n", naisu);
        prefs.putString("naisu", "233");
        prefs.end();
        delay(5000);
        ESP.restart();
    }
}

void loop() {}

在这里插入图片描述

键值删除

#include <Preferences.h>

void setup() {
    Serial.begin(115200);
    Serial.println();
    delay(2000);

    Preferences prefs;
    prefs.begin("mynamespace");

    prefs.putString("naisu", "233");
    Serial.printf("naisu: %s\n\n", prefs.getString("naisu", "not found"));
    prefs.remove("naisu"); // 删除当前命名空间中键名为"naisu"的元素
    Serial.printf("naisu: %s\n\n", prefs.getString("naisu", "not found"));

    prefs.putString("naisu", "233");
    Serial.printf("naisu: %s\n\n", prefs.getString("naisu", "not found"));
    prefs.clear(); // 删除当前命名空间中的所有元素
    Serial.printf("naisu: %s\n\n", prefs.getString("naisu", "not found"));

    prefs.end();
}

void loop() {}

在这里插入图片描述

剩余空间获取

Preferences的freeEntries方法可以获取剩余可用空间,不同类型的键值对会占用不同尺寸的空间。

#include <Preferences.h>

void setup() {
    Serial.begin(115200);
    Serial.println();
    delay(2000);

    Preferences prefs;
    prefs.begin("mynamespace");

    Serial.println(prefs.freeEntries());

    prefs.putString("string", "22333");
    Serial.println(prefs.freeEntries());

    prefs.putInt("int", 1234567890);
    Serial.println(prefs.freeEntries());

    prefs.putChar("char", 127);
    Serial.println(prefs.freeEntries());

    uint8_t buf[5] = {1, 2, 3, 4, 5};
    prefs.putBytes("byte", buf, 5);
    Serial.println(prefs.freeEntries());

    prefs.end();
}

void loop() {}

在这里插入图片描述

支持的数据类型

Preferences支持的数据类型主要就是下面API中涵盖的这部分(当然只要能保存数据那其实什么类型都无所谓了):

// put开头的方法 返回0表示操作失败 返回非0值表示操作成功
size_t putChar(const char* key, int8_t value);
size_t putUChar(const char* key, uint8_t value);
size_t putShort(const char* key, int16_t value);
size_t putUShort(const char* key, uint16_t value);
size_t putInt(const char* key, int32_t value);
size_t putUInt(const char* key, uint32_t value);
size_t putLong(const char* key, int32_t value);
size_t putULong(const char* key, uint32_t value);
size_t putLong64(const char* key, int64_t value);
size_t putULong64(const char* key, uint64_t value);
size_t putFloat(const char* key, float_t value);
size_t putDouble(const char* key, double_t value);
size_t putBool(const char* key, bool value);
size_t putString(const char* key, const char* value);
size_t putString(const char* key, String value);
size_t putBytes(const char* key, const void* value, size_t len);

int8_t getChar(const char* key, int8_t defaultValue = 0);
uint8_t getUChar(const char* key, uint8_t defaultValue = 0);
int16_t getShort(const char* key, int16_t defaultValue = 0);
uint16_t getUShort(const char* key, uint16_t defaultValue = 0);
int32_t getInt(const char* key, int32_t defaultValue = 0);
uint32_t getUInt(const char* key, uint32_t defaultValue = 0);
int32_t getLong(const char* key, int32_t defaultValue = 0);
uint32_t getULong(const char* key, uint32_t defaultValue = 0);
int64_t getLong64(const char* key, int64_t defaultValue = 0);
uint64_t getULong64(const char* key, uint64_t defaultValue = 0);
float_t getFloat(const char* key, float_t defaultValue = NAN);
double_t getDouble(const char* key, double_t defaultValue = NAN);
bool getBool(const char* key, bool defaultValue = false);
size_t getString(const char* key, char* value, size_t maxLen);
String getString(const char* key, String defaultValue = String());
size_t getBytesLength(const char* key);
size_t getBytes(const char* key, void * buf, size_t maxLen);

存在的问题

通过Arduino IDE上传固件请自动复位启动的话,第一次工作可能会异常(如果Preferences对象是全局声明的话异常可能会更加明显)。再次重启之后工作就正常了,或者在Arduino IDE上传固件完成时马上通过复位按钮手动复位设备也可以正常工作。目前不清楚由于什么原因引起该问题。

总结

Preferences的使用比较简单,更多内容可以参考如下:
https://github.com/espressif/arduino-esp32/tree/master/libraries/Preferences

;原文链接:https://blog.csdn.net/Naisu_kun/article/details/115514715
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐