不揮発性メモリで設定値を保存する方法(preferences/nvs) with Arduino IDE
はじめに
ESP32には、EEPROM(Electrically Erasable and Programmable Read Only Memory) は実装されておらず、電源を切っても保持すべきデータはフラッシュメモリを使用します。
ESP-IDF には、NVS(Non-volatile storage) というAPIが実装されており、その NVS を使いやすくした preferences という Arduino core for the ESP32 のライブラリが存在します。
Arduino IDE を使用するので、preferences を使用していこうと思います。
Document
– ESP-IDF NVS(Non-Volatile Storage Library)
– Arduino core for the ESP32 ライブラリ preferences

👈パーティションテーブルのここを使用します。
開発環境
OS : Windows 11 Pro
ESP32:ESP-WROOM-32
統合開発環境 : Arduino IDE 2.3.2
Arduino core for the ESP32:2.0.17
使用ライブラリ:なし
使用パーツ
ESP32開発ボード(38Pin)

作業内容
ライブラリインストール
preferences は、Arduino core for the ESP32 の標準ライブラリのため、インストールの必要はありません。
スケッチ作成
テストプログラムのスケッチを作成します。
#include <Preferences.h>
Preferences preferences;
void setup() {
Serial.begin(115200);
Serial.println();
// Open Preferences with my-app namespace. Each application module, library, etc
preferences.begin("my-app", false);
// Get the counter value, if the key does not exist, return a default value of 0
unsigned int counter = preferences.getUInt("counter", 0);
counter++;
Serial.printf("Current counter value: %u\n", counter);
// Store the counter to the Preferences
preferences.putUInt("counter", counter);
// Close the Preferences
preferences.end();
// Wait 10 seconds
Serial.println("Restarting in 10 seconds...");
delay(10000);
// Restart ESP
ESP.restart();
}
void loop() {
}
コード説明
カウンタ値をインクリメントしていく内容です。
「カウンタ値を読込む → インクリメント → カウンタ値を書き込み → 再起動」
preferences を開始します。
preferences.begin("my-app", false);
bool Preferences::begin(const char * name, bool readOnly, const char* partition_label)
引数
・name — 名前空間名。NULLは不可。15文字まで。
・readOnly — 読込み専用フラグ。
・partition_label — パーティションラベル名。NULLでも可。指定がある場合は、そのパーティションを使用する。
戻り値
・成功(true)、失敗(false)
「counter」キーの値を読み出します。
「counter」キーを作成していませんが、なければデフォルトの値が返ってくる仕組みになっています。
unsigned int counter = preferences.getUInt("counter", 0);
uint32_t Preferences::getUInt(const char* key, const uint32_t defaultValue)
引数
・key — キー名称。
・defaultValue — デフォルト値。キーが見つからなければこの値が戻る。
戻り値
・読み込んだ値。キーが見つからなかった場合は defaultValue。
「counter」キーの値を書き込みます。
preferences.putUInt("counter", counter);
size_t Preferences::putUInt(const char* key, uint32_t value)
引数
・key — キー名称。
・value — 書き込む値。
戻り値
・書き込み成功したサイズ。
preferences を終了します。
preferences.end();
Preferences::end()
引数
・なし
戻り値
・なし
動作確認
シリアルモニタにこのように出力されていれば成功です。
10秒毎に再起動し、カウンタがインクリメントされています。

おわりに
今回のサンプルでは、「unsigned int」の大きさを読み書きしたので、「getUInt」や「putUInt」を使用していますが、サイズにより関数が異なります。
👇読み書き関数の一覧👇
int8_t Preferences::getChar(const char* key, const int8_t defaultValue)
uint8_t Preferences::getUChar(const char* key, const uint8_t defaultValue)
int16_t Preferences::getShort(const char* key, const int16_t defaultValue)
uint16_t Preferences::getUShort(const char* key, const uint16_t defaultValue)
int32_t Preferences::getInt(const char* key, const int32_t defaultValue)
uint32_t Preferences::getUInt(const char* key, const uint32_t defaultValue)
int32_t Preferences::getLong(const char* key, const int32_t defaultValue)
uint32_t Preferences::getULong(const char* key, const uint32_t defaultValue)
int64_t Preferences::getLong64(const char* key, const int64_t defaultValue)
uint64_t Preferences::getULong64(const char* key, const uint64_t defaultValue)
float_t Preferences::getFloat(const char* key, const float_t defaultValue)
double_t Preferences::getDouble(const char* key, const double_t defaultValue)
bool Preferences::getBool(const char* key, const bool defaultValue)
size_t Preferences::getString(const char* key, char* value, const size_t maxLen)
String Preferences::getString(const char* key, const String defaultValue)
size_t Preferences::getBytesLength(const char* key)
size_t Preferences::getBytes(const char* key, void * buf, size_t maxLen)
size_t Preferences::putChar(const char* key, int8_t value)
size_t Preferences::putUChar(const char* key, uint8_t value)
size_t Preferences::putShort(const char* key, int16_t value)
size_t Preferences::putUShort(const char* key, uint16_t value)
size_t Preferences::putInt(const char* key, int32_t value)
size_t Preferences::putUInt(const char* key, uint32_t value)
size_t Preferences::putLong(const char* key, int32_t value)
size_t Preferences::putULong(const char* key, uint32_t value)
size_t Preferences::putLong64(const char* key, int64_t value)
size_t Preferences::putULong64(const char* key, uint64_t value)
size_t Preferences::putFloat(const char* key, const float_t value)
size_t Preferences::putDouble(const char* key, const double_t value)
size_t Preferences::putBool(const char* key, const bool value)
size_t Preferences::putString(const char* key, const char* value)
size_t Preferences::putString(const char* key, const String value)
size_t Preferences::putBytes(const char* key, const void* value, size_t len)
コメント