Parts

24LC256 I2C EEPROM

32 KB of memory that keeps its contents with the power off, in an eight-pin DIP. Aliases: external EEPROM, AT24C256, 24C256, I2C memory.

It is where a data logger keeps its readings when the chip's own EEPROM (1 KB on an Uno) is too small, and it is the plainest example there is of an I2C device with a sixteen-bit address.

Pins

Pin What it does
A0, A1, A2 The low three bits of the address. Pulled down inside the chip.
VSS Ground.
SDA I2C data.
SCL I2C clock.
WP Write protect: high refuses every write. Pulled down inside the chip.
VCC Supply, 2.5 to 5.5 V.

The address is 0x50 plus the address pins, so eight of them can share a bus. This is a bare chip: SDA and SCL want 4.7 kΩ pull-ups to VCC, unless a module elsewhere on the bus already carries them. Without them it still answers on the weak pull-ups Wire switches on inside the board's own pins, as it does on a real board at 100 kHz on a short breadboard bus.

Properties

model picks the chip in the 24-series, which differ in size, page and how the address is sent:

Model Size Page Address
24lc256, 24c256 32 KB 64 bytes two bytes
24c02 256 bytes 8 bytes one byte
24c04 512 bytes 16 bytes one byte; A8 in the device address
24c08 1 KB 16 bytes one byte; A9 and A8 in the device address
24c16 2 KB 16 bytes one byte; A10 to A8 in the device address (0x50 to 0x57)
24c32 4 KB 32 bytes two bytes: the AT24C32 on DS3231 and DS1307 modules
24c64 8 KB 32 bytes two bytes
24c128 16 KB 64 bytes two bytes
24c512 64 KB 128 bytes two bytes

Talking to it with Wire

There is no library to install; Wire.h is the whole driver. Every access starts by writing the address inside the chip, high byte first:

#include <Wire.h>

void writeByte(unsigned int at, byte value) {
  Wire.beginTransmission(0x50);
  Wire.write(at >> 8);
  Wire.write(at & 0xff);
  Wire.write(value);
  Wire.endTransmission();
  delay(5);                         // the write cycle
}

byte readByte(unsigned int at) {
  Wire.beginTransmission(0x50);
  Wire.write(at >> 8);
  Wire.write(at & 0xff);
  Wire.endTransmission(false);
  Wire.requestFrom(0x50, 1);
  return Wire.read();
}

What the model gets right

The write cycle. Nothing is written until the STOP; then the chip goes away for up to 5 ms and does not acknowledge its own address until it is done. A sketch either waits, or polls with an empty write until endTransmission() returns 0. A sketch that does neither loses every write after the first.

Pages. A write can carry up to 64 bytes, but the address only steps on within its 64-byte page. A write that runs past the end of a page wraps round to the start of the same page and overwrites it: 20 bytes written at address 60 land four at 60 to 63 and sixteen at 0 to 15. Wire's 32-byte buffer less the two address bytes means 30 bytes at most per write anyway.

A read steps through the whole array and wraps from 0x7FFF back to 0, and a read with no address in front of it carries on from wherever the last access left off. A new chip reads 0xFF everywhere.

What it does not model

The contents do not survive the end of a run: every run starts with the chip erased. Endurance: a real cell wears out after about a million writes and this one never does. The write cycle is always the 5 ms maximum.

Common mistakes

Forgetting the pull-ups on a breadboard: the board's internal ones carry a short bus, but a longer one, or a faster clock, needs the 4.7 kΩ pair. Writing the next byte straight after the last and finding it lost, because the chip was busy. Writing a long record across a page boundary and finding its start overwritten by its end.