Here are some general notes and a sample class on how to speak to AT24C256B (32KB) EEPROM by Atmel (datasheet) through TWI/I2C.
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.
The general idea is that we first have to send 2 bytes for the address inside the EEPROM and then either read or write.
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.
#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
#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); }