If you need to store a small amount of data, EEPROM may be the most simple choice. Actually ATmega chips has build-in EEPROM, but the space is very small. We designed this external EEPROM memory module using I2C bus to connect with the Arduino. It uses DIP pluggable chip series, which makes memory expansion very easy, basically just change for another EEPROM chip with larger capacity.

The memory module using AT24C series EEPROM chip. The I2C's base address is 0x50. And the last three addresses can be set depending on the application. Therefore, we must set the last three addresses first before using it. We do it through four A2, A1, and A0 of DIP switch, in which A0 is the last bit. Push the DIP switch up and the corresponding bit is 1, push down and the bit is 0. That is, if A2, A1, A0 are pushed up, the address is 0x57; If A2, A1, A0 are all pushed down, the address is 0x50.

Another configuration is switch RS, which decides whether on-board pull-up resistor is connected to the SDA and SCL of I2C bus. We know, I2C is known as the bus, because you can connect multiple devices on I2C. According to I2C protocol, only the I2C device which is the closest to the controller is allows to connect with pull-up resistor. So if there are more than one memory modules are connected to the Arduino I2C-bus, we must get the RS switch of the first (closest to Arduino) memory modules on, and get RS swithes of other modules off.

If Arduino special sensors board V4 is used, note that set the jumper of IIC/COM to the IIC side, because we need to use I2C connection:

Then use I2C/COM cable to connect the EEPROM memory module to sensor board:

Arduino's official Web site provides I2CEEPROM and TWIPROM. Here we test the code:
#include <Wire.h>
#define EEPROM_ADDR 0x50 // I2C Buss address of 24LC256 256K EEPROM
void setup()
{
Wire.begin(); // join I2C bus (address optional for master)
Serial.begin(9600);
// TESTS FOR EACH FUNCTION BEGIN HERE
Serial.println("Writing Test:");
for (int i=0; i<20; i++){ // loop for first 20 slots
i2c_eeprom_write_byte(EEPROM_ADDR,i,i+65); // write address + 65 A or 97 a
Serial.print(". ");
delay(10); // NEED THIS DELAY!
}
Serial.println("");
delay(500);
Serial.println("Reading Test:");
for (int i=0; i<20; i++){ // loop for first 20 slots
Serial.print(i2c_eeprom_read_byte(EEPROM_ADDR, i),BYTE);
Serial.print(" ");
}
// setup for page tests . . .
byte PageData[30]; // array that will hold test data for a page
byte PageRead[30]; // array that will hold result of data for a page
for (int i=0; i<30; i++){ // zero both arrays for next test
PageData[i]=0;
PageRead[i]=0;
}
Serial.println("");
for (int i=0; i<30; i++) PageData[i] = i+33; // fill up array for next test char 33 = !
Serial.println("Writing Page Test:");
i2c_eeprom_write_page(EEPROM_ADDR,100,PageData,28);// 28 bytes/page is max
Serial.println("Reading Page Test:");
i2c_eeprom_read_buffer(EEPROM_ADDR,100,PageRead,28);
for (int i=0; i<28; i++){
Serial.print(PageRead[i],BYTE); // display the array read
Serial.print(" ");
}
}
void loop()
{
}
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data )
{
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // Address High Byte
Wire.send((int)(eeaddress & 0xFF)); // Address Low Byte
Wire.send(rdata);
Wire.endTransmission();
}
//Address is a page address,6-bit(63),More and end will wrap around
//But data can be maximum of 28 bytes,because the Wire library has a buffer of 32 bytes
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length )
{
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddresspage >> 8)); // Address High Byte
Wire.send((int)(eeaddresspage & 0xFF)); // Address Low Byte
byte c;
for ( c = 0; c < length; c++)
Wire.send(data[c]);
Wire.endTransmission();
delay(10); // need some delay
}
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress )
{
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // Address High Byte
Wire.send((int)(eeaddress & 0xFF)); // Address Low Byte
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.receive();
return rdata;
}
//should not read more than 28 bytes at a time!
void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length )
{
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // Address High Byte
Wire.send((int)(eeaddress & 0xFF)); // Address Low Byte
Wire.endTransmission();
Wire.requestFrom(deviceaddress,length);
//int c = 0;
for ( int c = 0; c < length; c++ )
if (Wire.available()) buffer[c] = Wire.receive();
}Test result is shown below:
