文章目錄
- 目的
- 基礎說明
- 使用演示
- 基礎讀寫
- 鍵值查詢
- 鍵值洗掉
- 剩余空間獲取
- 支持的資料型別
- 存在的問題
- 總結
目的
對于傳統的單片機來說我們如果要固化保存小批量的資料的話通常會使用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://www.uj5u.com/qita/274808.html
標籤:其他
上一篇:破局共享汽車
下一篇:win+ubuntu系統引導修復
