Five milliseconds a write
After the stop, the chip spends up to 5 ms writing and answers nobody, not even its own address. A read in that time fails. delay(5) always works; asking the chip 'are you there?' until it says yes, called acknowledge polling, works too and never waits longer than it has to. This sketch shows both, and times the chip.
Three ways to wait
Press play for each. The write goes out on the wire in well under half a millisecond. Then the stop, and the chip goes quiet while it writes.
Reading straight away reaches a chip that is busy. It does not acknowledge its own address, so the read fails. The value was written; the sketch asked too soon, and the byte it prints is 255 or the old value.
delay(5) waits the datasheet's worst case every time. It always works, and for a setting saved now and then it is all you need. The last sketch used it.
Acknowledge polling asks "are you there?", an address with nothing after it, until the chip says yes. It is the datasheet's own method, and it never waits longer than the chip needs.
How long this chip takes
The datasheet gives only a maximum, 5 ms. The sketch measures yours. The serial monitor prints the failed read first:
asked straight away: endTransmission() = 2then five lines of write 0 was done after … us, each a number of
microseconds. It should be under 5000; how far under is the chip's own
business and is not in the datasheet. The code on the first line depends on
your board: an Uno says 2, which means "the address was not acknowledged".
Whatever you see, write every sketch for 5 ms.
Why it matters most in a loop
Writing one setting, the 5 ms is invisible. Writing 16,384 bytes one at a time, it is 16,384 waits: about a minute and a half. Sixty-four-byte pages cuts that to under ten seconds by writing many bytes per wait.
The code
Writes five bytes and times each one by polling for the chip's acknowledge. Before that, it asks once straight after a write, to show what a sketch without a wait sees.
/*
EEPROM Memory - how long a write takes TK31 / /p/tk31
Wiring. Count from the square pad on the TinkerBlock board, parts
up, header at the bottom:
GND -> GND
VCC -> your board's logic supply: 5V on an Uno, 3V3 on an
ESP32 or ESP32-S3, 3V3(OUT) on a Pico. Never 5V beside
a 3.3 V board: the pull-ups would put 5 V on its pins.
SDA -> A4 on an Uno, GPIO 21 on an ESP32, GPIO 8 on an
ESP32-S3, GP4 on a Raspberry Pi Pico
SCL -> A5 on an Uno, GPIO 22 on an ESP32, GPIO 9 on an
ESP32-S3, GP5 on a Raspberry Pi Pico
Arduino IDE
Tools > Board your board, e.g. Arduino Uno
Tools > Port the one that appears when you plug in
Tools > USB CDC On Boot Enabled (ESP32-S3 only)
No library to install: Wire comes with every board.
*/
#include <Wire.h>
const int EEPROM_ADDR = 0x50;
// Send a write, and return as soon as the stop has gone.
void sendByte(uint16_t at, uint8_t value) {
Wire.beginTransmission(EEPROM_ADDR);
Wire.write((uint8_t)(at >> 8));
Wire.write((uint8_t)(at & 0xFF));
Wire.write(value);
Wire.endTransmission();
}
// Is the chip there? 0 from endTransmission means it acknowledged.
bool answers() {
Wire.beginTransmission(EEPROM_ADDR);
return Wire.endTransmission() == 0;
}
// Acknowledge polling: ask until it answers, at most 20 ms.
unsigned long waitReady() {
unsigned long t0 = micros();
while (!answers() && micros() - t0 < 20000) {
}
return micros() - t0;
}
void setup() {
Serial.begin(115200);
delay(1000);
Wire.begin();
sendByte(100, 42);
Wire.beginTransmission(EEPROM_ADDR);
Serial.print("asked straight away: endTransmission() = ");
Serial.println(Wire.endTransmission()); // not 0: nobody answered
waitReady();
for (int i = 0; i < 5; i++) {
sendByte(100 + i, i);
unsigned long us = waitReady();
Serial.print("write ");
Serial.print(i);
Serial.print(" was done after ");
Serial.print(us);
Serial.println(" us");
}
}
void loop() {
}waitReady() gives up after 20 ms, so a missing chip cannot hang the sketch. It is the wait every later sketch in this book uses in place of delay(5).
The same test in MicroPython. A write the chip does not acknowledge raises OSError, so wait_ready() asks by setting the chip's address pointer, which stores nothing, until that stops happening.
"""
EEPROM Memory - how long a write takes, MicroPython TK31 / /p/tk31
Wiring. Count from the square pad on the TinkerBlock board, parts
up, header at the bottom:
GND -> GND
VCC -> 3V3 on an ESP32 or ESP32-S3, 3V3(OUT) on a Pico.
Never 5V: the pull-ups would put 5 V on your pins.
SDA -> GPIO 21 on an ESP32, GPIO 8 on an ESP32-S3,
GP4 on a Raspberry Pi Pico
SCL -> GPIO 22 on an ESP32, GPIO 9 on an ESP32-S3,
GP5 on a Raspberry Pi Pico
Thonny
Run > Configure interpreter MicroPython (ESP32) or
MicroPython (Raspberry Pi Pico)
Nothing to install: machine and time are built in.
"""
import time
from machine import I2C, Pin
# SDA, SCL. ESP32: 21, 22. ESP32-S3: 8, 9. Pico: 4, 5.
i2c = I2C(0, sda=Pin(21), scl=Pin(22), freq=100_000)
EEPROM = 0x50
def answers():
try:
i2c.writeto(EEPROM, b"\x00\x00") # set the pointer only
return True
except OSError: # no acknowledge
return False
def wait_ready():
t0 = time.ticks_us()
while not answers():
if time.ticks_diff(time.ticks_us(), t0) > 20_000:
break
return time.ticks_diff(time.ticks_us(), t0)
i2c.writeto_mem(EEPROM, 100, b"\x2a", addrsize=16)
print("asked straight away:", "answered" if answers() else "no answer")
wait_ready()
for i in range(5):
i2c.writeto_mem(EEPROM, 100 + i, bytes([i]), addrsize=16)
print("write", i, "was done after", wait_ready(), "us")wait_ready() sends the two address bytes rather than an empty write, because not every board's I2C hardware can send a write with no data. Setting the pointer writes nothing, so it costs the chip no wear.
When it does not work
The read went out while the chip was still writing, so the address was not acknowledged. Wait after every write: delay(5), or the waitReady() loop in this sketch.
Some boards' Wire library waits or retries on its own before it gives up, and the chip had finished by then. The timing lines below it are still right; the point is that the sketch cannot count on that.
5 ms is the datasheet's maximum, not its typical. The chip is allowed to finish sooner, and the datasheet does not say by how much, so one chip's time says nothing about the next. Never hard-code the time you measured.
No, but a scan run straight after a write can miss the chip, because it does not answer while writing. Scan again a moment later and 0x50 is back.
Writing more than one byte at a time, and the edge a write must never cross.
Sixty-four-byte pages →Edit this page — content/books/eeprom-memory/five-milliseconds-a-write.mdx
Questions about this product
See what other owners have asked, and read their solutions.
EEPROM Memory
Loading discussions…
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.