Arduinoでなんらかの動的なデータを保存しておく方法として、マイコン内蔵のEEPROMに保存する方法がある。容量は少ないが、設定を保存しておく時等に使える。
データの保存と読み出しはEEPROMのライブラリのread/writeやput/get関数で簡単に出来るが、考えておかないといけないのは
- 初めてスケッチを動かす時
- 保存するデータの種類や構造を変える時
である。当然初めてスケッチを動かす際は保存しているデータは無いので、なんらかのデフォルトの値を使う事になるが、どうやってEEPROMに既存のデータが無いのか判断しないといけない。Arduinoを使いまわしている場合、他のスケッチで適当なデータが書き込まれているかもしれない。
良くスケッチをバージョンアップする際データの形式(intやfloatとか)を変えたくなったり、保存するデータの構造を変えたくなったりもする。そんな時は古いデータを新しい形式に保存し直すか、破棄する必要がある。
では、どうやってデータの整合性を確認するか。手軽な方法としてはデータをstructで纏め、チェック用の文字列を入れておく。チェック用の文字列に適当なバージョン情報を設定し、保存する。
読み出す時、この文字列をチェックする事で、既存データがあるか、データのバージョンが合っているか確認できる。文字列が一致しないか古い形式であればデフォルト値を使う等の処理をする。
構造の中にCRCによるチェックも入れておけばなお完璧である。
簡単なデータチェックと保存データが無い場合にデフォルトを使うサンプルスケッチは以下の通り。intデータを二つ保存し、一つは起動毎にカウントアップする。データの構造を変える際には”DATA1.1″等に文字列を変えれば良い。
#include <EEPROM.h>
#define DEFAULT_VALA 10
#define DEFAULT_VALB 20
#define DATA_VERSION "DATA1.0"
struct DATA_SET{
int vala;
int valb;
char check[10];
};
DATA_SET data;
//データをEEPROMから読み込む。保存データが無い場合デフォルトにする。
void load_data() {
EEPROM.get<DATA_SET>(0, data);
if (strcmp(data.check, DATA_VERSION)) { //バージョンをチェック
//保存データが無い場合デフォルトを設定
data.vala = DEFAULT_VALA;
data.valb = DEFAULT_VALB;
}
}
//EEPROMへの保存
void save_data() {
//EEPROMに設定を保存する。
strcpy(data.check, DATA_VERSION);
EEPROM.put<DATA_SET>(0, data);
}
void setup() {
Serial.begin(9600);
load_data();
data.vala++;
save_data();
Serial.println(data.vala);
}
void loop() {
}
EEPROMで稀に保存したデータが正しく読めない事がある。EEPROMが不良なのか分からないが、その様な場合は書き込み開始アドレスをずらすと直る事がある。