内部メモリが十分でない場合は、外部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ビットしか格納できません。しかし、ライブラリには、より大きなデータを簡単に分割できる関数が用意されています。興味のある方は、他のライブラリと同様に、対応するドキュメントに詳細な情報が記載されています。
コメントを残す