内部メモリが十分でない場合は、外部EEPROMモジュールを使用することも可能です。例えば、RTCモジュールDS3231はタイマに加えて、4096バイトのEEPROMメモリを搭載したAT24C32チップを搭載しています。タイマとEEPROMは電源とI²Cバスを共有していますが、それ以外は完全に独立しています。このモジュールは、もともとデータロガーとして使用するために開発されたものなので、このような構成になっています。
タイマとEEPROMのI²Cアドレスは異なるため、両方のチップを別々に制御することができます。さらに、AT24C32のEEPROMチップは、はんだパッドをブリッジすることでI²Cバスアドレスを変更できます。手順は液晶バックパック(HD44780)の場合と全く同じです。このように、1つのI²Cバスで最大8個のメモリを動作させることができます。
I²Cアドレス | A0 | A1 | A2 |
80 | Low | Low | Low |
81 | High | Low | Low |
82 | Low | High | Low |
83 | High | High | Low |
84 | Low | Low | High |
85 | High | Low | High |
86 | Low | High | High |
87(デフォルト) | High | High | High |
はんだパッドをブリッジすることで、チップの対応する入力に Lowを設定できます。ブリッジをしない場合は、プルアップ抵抗でHighを自動的に設定しています。したがって、はんだパッドが変更されていない状態でのデフォルトアドレスは87です
RTCモジュールに含まれるAT24C32を使用して、前回の例を再現してみましょう。
EEPROMを簡単に制御できるように、ライブラリ uEEPROMlib.h をインストールします。
下記のプログラムは基本的には前回と同様のプログラムなので、相違点だけを以下にコメントします。
#define BUTTON1 9 #define BUTTON2 8 #define LED 6 #include "uEEPROMLib.h" uEEPROMLib externalMemory(87); //(1) byte Brightness; long Timer; void setup() { pinMode(BUTTON1,INPUT_PULLUP); pinMode(BUTTON2,INPUT_PULLUP); pinMode(LED,OUTPUT); Wire.begin(); //(2) Brightness = externalMemory.eeprom_read(0); //(3) analogWrite(LED, Brightness); } void loop() { if(!digitalRead(BUTTON1)) { if(Brightness < 255) Brightness++; analogWrite(LED, Brightness); Timer = millis() + 1000; while(!digitalRead(BUTTON1)) { if(millis() > Timer) { if(Brightness < 255) Brightness++; analogWrite(LED, Brightness); delay(10); } } externalMemory.eeprom_write(0,Brightness); //(4) } if(!digitalRead(BUTTON2)) { if(Brightness > 0) Brightness--; analogWrite(LED, Brightness); Timer = millis() + 1000; while(!digitalRead(BUTTON2)) { if(millis() > Timer) { if(Brightness > 0) Brightness--; analogWrite(LED, Brightness); delay(10); } } externalMemory.eeprom_write(0,Brightness); } }
(1) クラスuEEPROMLibのインスタンスとしてのオブジェクト。外部メモリは、このモジュールを表しています。ここではI²Cアドレスを引数として渡す必要があります。
(2) I²C接続はマスタとして開始されます。Wire.h ライブラリはすでに uEEPROMLib.h の中で実行されているため、インクルードする必要はありませんが、2回インクルードしてもコンパイラが無視するので、間違いではありません。
(3) 本オブジェクトの関数 eeprom_read()は、引数として渡されたメモリアドレス(本チップ上では 0~4095 の範囲)から 1 バイトのデータを読み込みます。
(4) 書き込みも同様で、ここで使用されている関数eeprom_write()は、メモリアドレスとデータ(1バイト)を引数にすることで書き込まれます。
ここでも、各メモリアドレスは8ビットしか格納できません。しかし、ライブラリには、より大きなデータを簡単に分割できる関数が用意されています。興味のある方は、他のライブラリと同様に、対応するドキュメントに詳細な情報が記載されています。
コメントを残す