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.