ESP32 偏好設定



非易失性儲存器是嵌入式系統的重要需求。通常,我們希望晶片即使在電源迴圈之間也能記住一些事情,例如設定變數、WiFi憑據等。如果每次裝置進行電源重置都必須執行設定或配置,那將非常不方便。ESP32 有兩種常用的非易失性儲存方法:偏好設定和 SPIFFS。偏好設定通常用於儲存鍵值對,而 SPIFFS(SPI Flash 檔案系統)顧名思義,用於儲存檔案和文件。在本章中,讓我們關注偏好設定。

偏好設定儲存在主快閃記憶體的一個區域中,型別為資料,子型別為nvsnvs代表非易失性儲存器。預設情況下,為偏好設定保留 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是因為該值是無符號整型。根據值的型別,需要呼叫其他函式,如getFloatgetString等。完整的選項列表可以在這裡找到。

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() {}
Serial Monitor Output

此示例很好地演示了 ESP32 偏好設定儲存確實是持久的。當您檢查序列埠監視器上的列印語句時,您可以看到計數在連續重置之間遞增。這對於區域性變數來說是不可能的。這隻有透過偏好設定使用非易失性儲存才能實現。

參考資料

廣告
© . All rights reserved.