前回記事にて、24FC1025をArduino で動かすところまで持っていくことができました。今回は、このライブラリとArduinoを活用して、シリアルモニタ経由でEEPROMを自由に読み書きできる装置を作ってみたいと思います。

前回記事はこちら↓

既存ライブラリの問題点

一般的にEEPROMは一度に最も多く読み書きできるデータの大きさが決まっています。これは「ページ」と呼ばれる単位で、大きさはEEPROMの型番に依存します。

24FC1025のページサイズは128Byteです。すべてchar文字の場合は128文字ということになります。

ただし、ArduinoでEEPROMと通信するときに使うWire.hの送信バッファが32Byteしかないため、EEPROMのページサイズがどんなに大きくても、結局32Byte以上のデータを一度に書きこむことができません。

せっかく131071Byteもの広大な空間が使えるのに、32Byte毎に区切って読み書きしなくてはならないのは不便ですね。

シリアルモニタ経由のRead/Writeプログラム

そこで、自由にアドレスやデータサイズを指定して読み書きができるプログラムを自作しました。

この記事に記載しているスケッチをArduino に書き込むと、Arduino IDEのシリアルモニタ経由でEEPROMを読み書きすることができます。

用意したコマンドは書き込みと読み出しの二種類です。コマンド[スペース]先頭アドレス[スペース]データ(readの場合はデータの大きさ)というフォーマットです。

wm 8000 ABCDEFG  //書込みコマンド。8000番地からABCDEFG書き込む。
rm 8000 7        //読出しコマンド。8000番地から7Byte(7文字)を読み出す。

これらのコマンドは一文字ずつ読み書きするアルゴリズムとしているため、扱えるデータサイズに制限がありません。ただし、ページライト・ページリードの速度に比べると遅いです。

データの書き込み

8000番地からABCDEFGの7バイトを書き込みます。成功するとコマンド、アドレス、データ長、データの内容が表示されます。

データの読み出し

続いてデータの読み出しです。8000番地から7バイトを読み出しています。先ほど書き込んだABCDEFGが問題なく表示されました。

試しに、3バイトずらして8003番地から4倍と読み出してみましょう。期待する結果はDEFGです。

期待通りの結果が得られました。アドレス解析結果の表示が邪魔であれば、下記に示すプログラムの61~69行目のprintfを削除すればOKです。

プログラム

#include <Wire.h>
#include <skMC24xxx.h>

skMC24xxx MEM(0,0,0);        // EEPROM関数の生成を行う(A0/A1端子は全てGNDに配線)

void setup(){
     Serial.begin(115200) ;     // シリアル通信の初期化
     Serial.println("Started.\n");
}

void loop(){
     if(Serial.available() > 0){
          
          //command解析
          String revString = Serial.readString();
          
          //先頭・末尾のスペースを削除
          revString.trim();

          //文字列中にスペースがあるかチェック
          if(revString.indexOf(" ") == -1){
               Serial.println("Error:No argument.");
               goto Exit;
          }


          String cmd = "";
          int len = revString.length();
          
          //command抽出
          for(int i = 0; i < len; i++){
               if(revString[i] == ' '){
                    revString = revString.substring(i + 1);
                    break;                   
               }
               else{
                    cmd += revString[i];
               }
          }

          //アドレス抽出
          String address = "";
          len = revString.length();
          //最初のスペースが来るまで文字を連結し続ける。
          for(int i = 0; i < len; i++){
               if(revString[i] == ' '){
                    revString = revString.substring(i + 1);
                    break;                   
               }
               else{
                    address += revString[i];
               }
          }          

          //データ抽出
          String data = revString;

          //データ長抽出
          int dataLen = data.length();

          Serial.println("");
          Serial.print("CMD=");
          Serial.print(cmd);
          Serial.print(", ADDRESS=");
          Serial.print(address);
          Serial.print(", DATA_LEN=");
          Serial.println(dataLen);
          Serial.print("DATA=");
          Serial.println(data);

          int addressInt = address.toInt();


          //書き込みコマンド
          if(cmd == "wm"){
               char wchar[1];
               int Ans = 0;
               for(int i = 0; i < dataLen; i++){
                    wchar[0] = data[i];
                    int  ans;
                    ans = MEM.Write2(addressInt + i, wchar, 1) ;
                    
                    if(ans != 0){
                         Serial.print("Record Write Error ans=") ;
                         Serial.println(ans) ;
                         Ans = 1;
                         break;
                    }
                    delay(3);
               }
               if (Ans == 0) {
                    Serial.println("Record Write Success.") ;
               }
          }


          //読み出しコマンド
          else if(cmd == "rm"){
               char wchar[1];
               for(int i = 0; i < data.toInt(); i++){
                    int  ans;
                    ans = MEM.Read2(addressInt + i, wchar, 1);
                    if (ans == 0) {
                         Serial.print(wchar[0]);
                    }
                    else {
                         Serial.println("");
                         Serial.print("EEPROM Read Error ans=") ;
                         Serial.println(ans);
                    }
               }
          }

          //その他のコマンド
          else{
               Serial.println("I do not know this command."); 
          }
     }

     Exit:;
}

このプログラムはArduinoで何かアプリケーションを作る際に使用するというよりも、ユーザによるのデータ書き込みとチェックを行ったり、長時間の記録したデータのダンプ(取り出し)などに使えそうですね。

是非活用してみてください。

参考サイト