Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

Using the Wire library on a Serial EEPROM

Here are some general notes and a sample class on how to speak to AT24C256B (32KB) EEPROM by Atmel (datasheet) through TWI/I2C.

Table of contents

Pins

A0 - GND
A1 - GND
A2 - GND
GND - GND
VCC - 5V
SCL - SCL
SDA- SDA

A0..A2 can be whatever you choose. They will form the last part of the slave address of the EEPROM [1][0][1][0][A2][A1][A0]. In the sample case, the address is 0x50.

General Info

The general idea is that we first have to send 2 bytes for the address inside the EEPROM and then either read or write.

Trick

At first, only 16B could be written and 32B read at a time, but by changing Arduino Wire.h's BUFFER_LENGTH from 32 to 128, one can write 64B and read 128B. The Wire library's location varies with the board, to see which one it uses, enable "File -> Preferences -> Show Verbose Output During -> Compilation" in Arduino settings.

Code::


EEPROM.h

#ifndef	EEPROM_H
#define	EEPROM_H
#include <Wire.h>
#include <Arduino.h>
#include <Streaming.h>

#define	AT24C256B_ADDR	0x50
#define	EEPROM_BATCH_WRITE	64
#define	EEPROM_BATCH_READ	128
#define	EEPROM_DELAY	3
class EEPROM{
	public:
		void	writePage(byte array[],ushort size);
		void	writePage(ushort addr, byte array[],ushort size);
		void	writeAddr(ushort addr);
		void	request(ushort many);
		void	request(ushort addr,ushort many);
		void	print(ushort many);
		void	print(ushort addr, ushort many);
		byte	get(ushort addr);
		void	put(byte data);
		void	put(ushort addr,byte data);
	private:
		ushort	pos=0;
};
#endif

EEPROM.cpp

#include "EEPROM.h"
void EEPROM::writePage(byte array[],ushort size)
{
	writePage(0,array,size);
}
void EEPROM::writePage(ushort addr, byte array[],ushort size)
{
	int i=0;
	while(size-EEPROM_BATCH_WRITE>0)
	{
		Wire.beginTransmission(AT24C256B_ADDR);
		Wire.write(addr>>8); // addr
		Wire.write(addr&0xFF); // addr
		Wire.write(array+i*EEPROM_BATCH_WRITE,EEPROM_BATCH_WRITE);
		Wire.endTransmission();
		delay(EEPROM_DELAY);
		i++;
		size-=EEPROM_BATCH_WRITE;
		addr+=EEPROM_BATCH_WRITE;
	}
	if(size>0)
	{
		Wire.beginTransmission(AT24C256B_ADDR);
		Wire.write(addr>>8); // addr
		Wire.write(addr&0xFF); // addr
		Wire.write(array+i*EEPROM_BATCH_WRITE,size);
		Wire.endTransmission();
		delay(EEPROM_DELAY);
	}
}
void EEPROM::writeAddr(ushort addr)
{
	Wire.beginTransmission(AT24C256B_ADDR);
	Wire.write(addr>>8);  
	Wire.write(addr&0xFF);
	Wire.endTransmission(); 
	pos=addr;
}

void EEPROM::request(ushort many)
{
	request(0,many);
}

void EEPROM::request(ushort addr,ushort many)
{
	if(many>EEPROM_BATCH_READ)
	{
		Serial << "WARNING:\tEEPROM:\trequested more than " << EEPROM_BATCH_READ << "B, giving only " << EEPROM_BATCH_READ << "!!\n";
		many=EEPROM_BATCH_READ;
	}
	writeAddr(addr);
	Wire.requestFrom(AT24C256B_ADDR,many);
}

void EEPROM::print(ushort many)
{
	print(0,many);
}

void EEPROM::print(ushort addr, ushort many)
{
	for(int i=0;i<EEPROM_BATCH_READ;i++)
		Serial << i << '\t';
	Serial << endl;
	for(int i=0;i<EEPROM_BATCH_READ;i++)
		Serial << "________";
	Serial << endl;
	while(many-EEPROM_BATCH_READ>0)
	{
		request(addr,EEPROM_BATCH_READ);
		while(Wire.available())
		{
			Serial << Wire.read() << '\t';
		}
		Serial << endl;
		many-=EEPROM_BATCH_READ;
		addr+=EEPROM_BATCH_READ;
	}
	if(many > 0)
	{
		request(addr,many);
		while(Wire.available())
		{
			Serial << Wire.read() << '\t';
		}
		Serial << endl;
	}
}

byte EEPROM::get(ushort addr)
{// CHECK: please check this function later
	request(addr,1);
	return Wire.read();
}

void EEPROM::put(byte data)
{
	put(0,data);
}

void EEPROM::put(ushort addr,byte data)
{
	Wire.beginTransmission(AT24C256B_ADDR);
	Wire.write(addr>>8); // addr
	Wire.write(addr&0xFF); // addr
	Wire.write(data);
	Wire.endTransmission();
	delay(EEPROM_DELAY);
}

References