フラシュメモリを使ってEEPROMのエミュレーションを行う

〔Seeeduino XIAOの使い方に戻る〕


"Seeeduino XIAO"(ATSAMD21G18)にはEEPROMが搭載されていません、
なのでぇ、電源を切ってもデータ内容を保存する為にはプログラムを書き込む為のフラシュメモリを
利用しそこにデータを書き込むしか方法がありません。
ですが、リファレンスマニュアルにこう書いて有ります。

【限られた数の書き込み】
 フラッシュメモリの書き込みサイクルには制限があります。
 一般的なフラッシュメモリは、「摩耗」し始めてデータを保持する能力を失い始める前に、
 同じフラッシュブロックに対して約10000回の書き込みサイクルを実行できます。
 したがって、注意してください:
 このライブラリを不適切に使用すると、MICROのフラッシュメモリが迅速かつ永久に破壊される
 可能性があります。
 特に、write()関数を頻繁に呼び出さない様にし、MICROの存続期間全体で書き込みは上記の10000の
 制限を十分に下回るようにします。(MICROのメーカーがより多くのサイクル数を保証している
 場合でも、その数を覚えておく事は良い経験則です)。

【よくある質問】
 >EEPROMの代わりにフラッシュを使用するこ事をお勧めしますか?
  いいえ。MICROがEEPROMを提供する場合、それはユーザーデータを保存する為の特定の目的で
  設計された一種のメモリである為、ほとんどの場合それを使用する方が優れています(より長い寿命、
  書き込みサイクル数など...)。
  EEPROMがない場合は、このライブラリを使用して、フラッシュメモリの一部をEEPROMの代替として
  使用できます。 ただし、常にその限界に留意する必要があります。

とあるので書き込む場合は回数を減らす工夫をしましょう、読み込みはこの限りではありません。

《FlashStorage》

Arduino IDEでのライブラリのある場所は、
IDEのメニューバーから[ファイル]→[スケッチ例]→[FlashStorage] にあります。
  (このライブラリは""Arduino IDEに"Seeeduino XIAO"ボードを追加した時にインストール
  されている様だ。)

●使い方1
まず最初に、フラッシュメモリに格納するデータの各部分に対してグローバルなFlashStorage
オブジェクトを宣言する必要があります。
例えば、人の年齢を保存する場合は、次のようにage_storage名前を宣言する必要があります。

FlashStorage(age_storage, int) ;

この命令は、「age_storage名のint変数を格納する為のFlashStorageを作成する」事を意味します。
これで、整数を安全に格納する場所としてage_storage名を使用できます。
void readAndStoreUserAge() {
  Serial.println("Please enter your age:") ;
  String age = Serial.readStringUntil('\n') ;

  age_storage.write(age.toInt()) ; // 年齢の保存
}
マイクロコントローラーのリセット後、次を使用して保存されている年齢を取得できます。

int user_age = age_storage.read() ;

●使い方2
使い方1では、単一のFlashStorageオブジェクトを使用した例でした。
より多くのデータを保存する場合は、より多くのフィールドを持つ構造体を宣言し、
構造全体を格納するFlashStorageオブジェクトを作成できます。
typedef struct {
 int age ;
 char name[50] ;
 char address[100] ;
} PERSON

FlashStorage(flash_store, PERSON) ;

PERSON owner ;
owner = flash_store.read() ;

flash_store.write(owner) ;

動作確認用スケッチについて

"Seeeduino XIAO"ボードのD4ピンにスイッチをプルダウンで配線します。

@ XIAOの"USB port"とPCをUSB Type-Cコネクターケーブルで繋ぎます。

A ArduinoIDEを起動させ、ボードとポート設定を"Seeeduino XIAO"に設定します。

B IDEに下記のスケッチプログラムをコピーペーストして貼り付けて下さい。
---------------------------------------------------------------------
#include <FlashStorage.h>

FlashStorage(flash_store, int) ; // FlashStorageオブジェクトの作成

void setup() {
     Serial.begin(9600) ;
     pinMode(4, INPUT);          // スイッチをD4ピンに配線
}
void loop() {
     int number;

     // IDEのシリアル通信から数値を送りそれをフラッシュメモリに保存する
     if (Serial.available( ) != 0) {
          String strnum = SerialUSB.readStringUntil('\n') ;
          number = strnum.toInt() ;
          Serial.println(number) ;
          flash_store.write(number) ;
     }
     // スイッチはプルダウン接続押して"1"です。
     if (digitalRead(4) == HIGH) {
          number = flash_store.read() ; // フラッシュメモリから読み込む
          Serial.println(number) ;      // IDEのシリアル通信に数値を表示する
          delay(500) ;                  // チャタリング防止
     }
}
---------------------------------------------------------------------
C スケッチをコンパイルして書き込みます。

D "Tera Term"等のターミナルツール等で操作しても良いのですが、ここは簡単にIDEのシリアルモニタを
  使いましょう。

E シリアルモニタを表示させ、ボーレートは9600bpsで、改行を”LFのみ”に設定します。

F ボタンを押してみてください、メモリ内容"0"が表示されます。

G 次にシリアルモニタの送信ボックスに"123"を入れて[送信]を押して見て下さい。
  送信確認に"123"が表示され、メモリに"123"が保存されます。

H ボタンを押してみてください、メモリ内容"123"が表示されます。

I "Seeeduino XIAO"ボードの電源を切り再び入れます、
  で、再びシリアルモニタを表示させ、ボタンを押してみてください、
  フラッシュメモリ内容"123"が表示されるはずです。

【よくある質問】
 >新しいスケッチがアップロードされるたびにFlashStorageのコンテンツが消去されますか?
  はい、新しいスケッチをアップロードするたびに、FlashStorageの以前のコンテンツは消去されます。
  なのでぇ、フラッシュメモリに保存したデータは消えます注意しましょう。

《FlashAsEEPROM》

まずは、こちらのGitHubからライブラリをダウンロードしましょう。
このライブラリは、"FlashStorage"と"FlashAsEEPROM"が含まれていますが、"FlashStorage"は
上記の様に既にインストール済みだと思います。
なのでぇ、このライブラリから"FlashAsEEPROM"のみ抜き取りました、ここに置いておきます。
"FlashAsEEPROM"の登録方法は、ここのページの登録方法1を参照してインストールしましょう。

尚、"FlashAsEEPROM"は"FlashStorage"を必要とします、だからぁ、"FlashStorage"がインストール
されていないなら、GitHubからのライブラリをそのままインストルしましょう。

動作確認用スケッチについて

@ XIAOの"USB port"とPCをUSB Type-Cコネクターケーブルで繋ぎます。

A ArduinoIDEを起動させ、ボードとポート設定を"Seeeduino XIAO"に設定します。

B IDEのメニューバーから[ファイル]→[スケッチ例]→[FlashAsEEPROM]→[EmulateEEPROM]を
  順番にクリックします。

C スケッチをコンパイルして書き込みます。

D 書き込み終了後、IDEの[シリアルモニター]を開きましょう。

実行時のシリアルモニター図1
10秒後にこの様に表示され、メモリに書き込まれるでしょう。

E この後、XIAOのUSB ケーブルを引き抜き、再び挿してIDEの[シリアルモニター]を開きましょう。

実行時のシリアルモニター図2
10秒後にメモリから読み出されこの様に表示されるでしょう。


リファレンス

uint8_t EEPROM.read(int address)
 EEPROMから1バイト読み込みます。
 Parameters
  address: 読み取る位置。0以上の値
  Return :指定したアドレスの値 (byte)

void EEPROM.write(int address, uint8_t value)
 EEPROMに1バイト書き込みます。
 Parameters
  address: 書き込む位置。0以上の値
  value :書き込む値。0から255 (byte)

bool EEPROM.isValid()
 EEPROM内のデータが書き込まれているか否かの状態を返します。
  Return:EEPROM内のデータが有効な場合、つまりデータが少なくとも1回書き込まれた場合は
       trueを返します。
       それ以外の場合、EEPROMデータは「未定義」であり、関数はfalseを返します。

void EEPROM.commit()
 EEPROMデータをフラッシュメモリに保存します。 これは注意して使用してください。
 この呼び出しは、フラッシュメモリに完全なEEPROMデータを書き込みます。
 これにより、残りのフラッシュメモリ書き込みサイクルが削減されます。
 この関数をループで呼び出さないでください。フラッシュするとすぐに終了します。

”FlashAsEEPROM.h”に"#define EEPROM_EMULATION_SIZE 1024"が記述されていますので
  EEPROMのデータ保存サイズは1024バイトです、これを変更すれば増減可能と思われます。





【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.