ArduinoVN
Đăng nhập Tham gia
Thư viện Code /u/linucat /11/05/2026

Thư viện EEPROM.h: lưu cấu hình vào flash Arduino

Thảo luận

Arduino có vùng nhớ EEPROM (Electrically Erasable Programmable Read-Only Memory) tích hợp sẵn — giữ dữ liệu kể cả khi tắt nguồn. Đó là nơi lưu cấu hình (SSID WiFi, mật khẩu, ngưỡng cảm biến, lần khởi động) mà không cần thẻ SD. Bài viết tổng hợp thư viện EEPROM.h và cách dùng đúng.

1. Dung lượng EEPROM theo board

BoardEEPROM
Arduino Uno (ATmega328P)1024 byte
Arduino Nano1024 byte
Arduino Mega 25604096 byte
ESP8266 / ESP32Không có EEPROM thật — giả lập trên flash. ESP32 nên dùng Preferences.h thay thế.

2. API căn bản

#include 

EEPROM.write(addr, value);   // ghi 1 byte (0..255)
uint8_t v = EEPROM.read(addr);
EEPROM.update(addr, value);  // ghi chỉ khi khác giá trị hiện tại
uint16_t size = EEPROM.length();

Luôn dùng update() thay vì write() — EEPROM chỉ chịu được ~100.000 chu kỳ ghi mỗi ô. update() tránh ghi không cần thiết.

3. Ghi/đọc biến đa byte với put() và get()

Đây là cách bạn sẽ dùng 90% thời gian:

float temp = 25.5;
EEPROM.put(0, temp);          // ghi 4 byte ở địa chỉ 0

float val;
EEPROM.get(0, val);           // đọc 4 byte vào val

put()/get() tự xác định kích thước biến qua template, hoạt động với mọi kiểu (int, float, double, struct, mảng). Bên trong dùng update() nên an toàn.

4. Lưu struct cấu hình

struct Config {
  uint32_t magic;          // để detect EEPROM trắng
  char ssid[32];
  char pass[32];
  uint16_t threshold;
};

const uint32_t MAGIC = 0xCAFE1234;

void saveConfig(const Config& c) {
  EEPROM.put(0, c);
#if defined(ESP32) || defined(ESP8266)
  EEPROM.commit();         // ESP cần commit thủ công
#endif
}

bool loadConfig(Config& c) {
  EEPROM.get(0, c);
  return c.magic == MAGIC;
}

Trường magic giúp phát hiện EEPROM lần đầu (toàn 0xFF) để đặt giá trị mặc định.

5. ESP32 / ESP8266 — khác biệt quan trọng

ESP không có EEPROM thật. Thư viện EEPROM.h được "giả lập" bằng cách:

  • Phải gọi EEPROM.begin(size) với kích thước RAM buffer trước khi dùng.
  • Mọi write()/put() chỉ ghi vào RAM — phải EEPROM.commit() để flush xuống flash.
  • Tuổi thọ flash 10k–100k lần ghi — kém EEPROM thật.
EEPROM.begin(512);
EEPROM.put(0, value);
EEPROM.commit();
EEPROM.end();

Khuyến nghị mạnh: ESP32 nên dùng Preferences.h (key-value API) hoặc LittleFS — hiện đại hơn và wear-leveling tốt hơn.

6. Iterate toàn bộ EEPROM

for (uint16_t i = 0; i < EEPROM.length(); i++) {
  uint8_t b = EEPROM.read(i);
  if (b != 0xFF) {
    Serial.print(i); Serial.print("="); Serial.println(b, HEX);
  }
}

EEPROM "chưa ghi" có giá trị 0xFF (255).

7. Reset EEPROM

for (uint16_t i = 0; i < EEPROM.length(); i++) {
  EEPROM.update(i, 0xFF);
}

Hoặc giữ một nút bấm khi khởi động → nếu nhấn thì clear.

8. Cảnh báo wear-out

100.000 chu kỳ nghe nhiều nhưng nếu bạn ghi trong loop() không debounce, EEPROM chết trong vài giờ. Quy tắc:

  • Chỉ ghi khi giá trị thực sự thay đổi (dùng update()).
  • Đừng ghi liên tục mỗi loop — gom các thay đổi và ghi 1 lần.
  • Cấu hình WiFi, ngưỡng cảnh báo → ghi vài lần/ngày là OK. Đếm số bước motor → ghi mỗi giây sẽ phá EEPROM trong tuần.

9. Bảng tóm tắt

HàmKhi dùng
read(addr)Đọc 1 byte
write(addr, v)Ghi 1 byte (hạn chế dùng)
update(addr, v)Ghi 1 byte chỉ khi khác — DÙNG NÀY
put(addr, anyType)Ghi struct/biến nhiều byte
get(addr, anyType)Đọc struct/biến nhiều byte
length()Dung lượng EEPROM
begin(size)Chỉ ESP32/ESP8266
commit()Chỉ ESP32/ESP8266 — flush RAM xuống flash

Liên quan

Trên ESP32, đọc bài Preferences.h: thay EEPROM trên ESP32. Để lưu dữ liệu lớn hơn, xem SD.h: đọc/ghi file CSV trên Arduino.

Thảo luận (0)

Đăng nhập để tham gia thảo luận.
Chưa có bình luận nào. Hãy là người đầu tiên!