データ保存方法の候補
- SPIFFS
- 疑似EEPROM
- Preferences
- microSD
4のmicroSDは大げさなので、使わない。
1,2に関しては、
こちらの記事 が詳しい。
この記事を読んでEEPROMを使おうかと思ったが、
参考先のgithubでEEPROMは非推奨で、Preferencesを使えとあったので、3のPreferencesを使うことにする。
EEPROM is deprecated. For new applications on ESP32, use Preferences.
Preferencesの使い方
大まかな流れ
bool begin(const char * name, bool readOnly=false, const char* partition_label=NULL)
でnamespaceでpreferencesを開く
- get*, put*でデータの読み書きをする
void end()
で開いていたpreferencesを閉じる。
StartCounter
exampleのstart counterを動かしてみる。
これは起動した回数を保存して出力するサンプルである。
/*
ESP32 startup counter example with Preferences library.
This simple example demonstrates using the Preferences library to store how many times
the ESP32 module has booted. The Preferences library is a wrapper around the Non-volatile
storage on ESP32 processor.
created for arduino-esp32 09 Feb 2017
by Martin Sloup (Arcao)
*/
#include <Preferences.h>
Preferences preferences;
void setup() {
Serial.begin(115200);
Serial.println();
// bool begin(const char * name, bool readOnly=false, const char* partition_label=NULL)
// 第一引数のnamespaceでPreference領域を開く。第二引数をtrueにすると、Read-onlyになる。
// 第三引数はちょっとよくわからない。
// namespaceは 15 charasまで。
// 成功したらtrue, 失敗したらfalseが返ってくる。
preferences.begin("kj-app", false);
// 第一引数のkeyに紐づいているデータをUIntで読み込む。
// keyは15charasまで。
// 第二引数は、keyに紐づいているデータがないときに帰ってくる、デフォルト値
unsigned int counter = preferences.getUInt("counter", 0);
counter++;
Serial.printf("Current counter value: %u\n", counter);
// size_t putUInt(const char* key, uint32_t value)
// 第一引数のkeyに第二引数のデータを格納する。
// 成功したら格納したデータのバイト数(4)を返し、失敗したら0を返す。
preferences.putUInt("counter", counter);
// 開いているnamespaceの領域を閉じる。
preferences.end();
Serial.println("Restarting in 10 seconds...");
delay(10000);
// Restart ESP
ESP.restart();
}
void loop() {}
結果は下記。2から始まってるのはモニターのタイミングかなあ。
Current counter value: 2
Restarting in 10 seconds...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:12784
load:0x40080400,len:3032
entry 0x400805e4
Current counter value: 3
Restarting in 10 seconds...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:12784
load:0x40080400,len:3032
entry 0x400805e4
Current counter value: 4
Restarting in 10 seconds...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:12784
load:0x40080400,len:3032
entry 0x400805e4
Current counter value: 5
Restarting in 10 seconds...
検証
型ごとにメソッド使っているが、それがずれたらどうなるだろうか?
上記のサンプルで、putUint()をputInt()にしてみたら、エラーは怒らないがずっと出力結果が1になった。
エラーが出れば気が付けるが、そうではなさそうなので注意が必要そう。
Current counter value: 1
Restarting in 10 seconds...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:12784
load:0x40080400,len:3032
entry 0x400805e4
Current counter value: 1
Restarting in 10 seconds...
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:12784
load:0x40080400,len:3032
entry 0x400805e4
Current counter value: 1
Restarting in 10 seconds...
構造体の保存
ちなみに、 prefs.putBytes("schedule", schedule, 3*sizeof(schedule_t));
で3をかけているのは、schedule_tのデータが3個あるから。
uint8_t content[] = {9, 30, 235, 255, 20, 15, 0, 1}; // two entries
で二つデータを作っていて、
schedule[2] = {8, 30, 20, 21}; // add a third entry (unsafely)
でもう一つを追加し、合計3つのデータがあるため。
終わりに
esp32で設定値を保存するために、Preferencesを使ってみた。