ESP32 Arduino EEPROM 完整使用代码

ESP32 没有物理 EEPROM ,Arduino 核心通过Flash 模拟 EEPROM 实现数据掉电保存,使用官方自带的EEPROM.h库即可,无需额外安装。

方式一:Preferences 库(⭐ 推荐)

官方推荐,基于 NVS,更稳定、不易磨损。

cpp 复制代码
#include <Preferences.h>

Preferences preferences;

void setup() {
  Serial.begin(115200);

  // 打开命名空间(类似分区)
  preferences.begin("my-app", false);  // false = 读写模式

  // === 写入数据 ===
  preferences.putInt("counter", 42);
  preferences.putFloat("voltage", 3.3);
  preferences.putString("ssid", "MyWiFi");
  preferences.putBool("flag", true);

  // === 读取数据 ===
  int counter = preferences.getInt("counter", 0);        // 默认值 0
  float voltage = preferences.getFloat("voltage", 0.0);
  String ssid = preferences.getString("ssid", "");
  bool flag = preferences.getBool("flag", false);

  Serial.printf("counter=%d, voltage=%.2f, ssid=%s, flag=%d\n",
                counter, voltage, ssid.c_str(), flag);

  preferences.end();
}

void loop() {}

注意事项

  1. EEPROM 写入有寿命限制(约 10 万次/扇区),频繁写入用 Preferences
  2. EEPROM.commit() 忘了调 = 数据没存上,这是最常见的坑
  3. Preferences 适合存配置,EEPROM 适合兼容老 Arduino 代码

核心知识点

  1. 模拟 EEPROM 大小最大4096 字节(推荐使用 512 字节足够日常存储)
  2. 必须先EEPROM.begin(大小)初始化
  3. 写入后必须EEPROM.commit()才会真正保存到 Flash
  4. 支持存储:int、float、String、结构体等任意数据

完整示例代码(通用版)

包含基础读写字符串读写浮点数读写,直接复制可用

cpp 复制代码
#include <EEPROM.h>

// 定义模拟EEPROM大小(单位:字节),最大4096
#define EEPROM_SIZE 512

// 存储地址定义(每个地址存1字节,不同数据要错开地址,避免覆盖)
#define ADDR_INT  0     // int类型地址
#define ADDR_FLOAT 4    // float类型地址(int占4字节,所以从4开始)
#define ADDR_STR   8    // 字符串地址

void setup() {
  Serial.begin(115200);
  
  // 1. 初始化EEPROM
  EEPROM.begin(EEPROM_SIZE);
  Serial.println("EEPROM初始化完成");

  // ============== 写入数据(只需要执行一次,注释掉后重启仍能读取) ==============
  writeInt(ADDR_INT, 12345);       // 写入int
  writeFloat(ADDR_FLOAT, 3.14159); // 写入float
  writeString(ADDR_STR, "ESP32 EEPROM"); // 写入字符串
  EEPROM.commit(); // 关键:提交保存!
  Serial.println("数据写入完成");

  // ============== 读取数据 ==============
  int readInt = readInt(ADDR_INT);
  float readFloat = readFloat(ADDR_FLOAT);
  String readStr = readString(ADDR_STR);

  Serial.print("读取到int:");
  Serial.println(readInt);
  Serial.print("读取到float:");
  Serial.println(readFloat);
  Serial.print("读取到字符串:");
  Serial.println(readStr);
}

void loop() {
  // 主循环无需操作
}

// ------------------- 工具函数:任意类型读写 -------------------
// 写入int(4字节)
void writeInt(int address, int value) {
  EEPROM.write(address, value & 0xFF);
  EEPROM.write(address + 1, (value >> 8) & 0xFF);
  EEPROM.write(address + 2, (value >> 16) & 0xFF);
  EEPROM.write(address + 3, (value >> 24) & 0xFF);
}

// 读取int
int readInt(int address) {
  int value = 0;
  value |= EEPROM.read(address);
  value |= EEPROM.read(address + 1) << 8;
  value |= EEPROM.read(address + 2) << 16;
  value |= EEPROM.read(address + 3) << 24;
  return value;
}

// 写入float(4字节)
void writeFloat(int address, float value) {
  byte* p = (byte*)&value;
  for (int i = 0; i < 4; i++) {
    EEPROM.write(address + i, *(p + i));
  }
}

// 读取float
float readFloat(int address) {
  float value = 0;
  byte* p = (byte*)&value;
  for (int i = 0; i < 4; i++) {
    *(p + i) = EEPROM.read(address + i);
  }
  return value;
}

// 写入字符串(最大32字节,可修改)
void writeString(int address, String str) {
  int len = str.length();
  for (int i = 0; i < len; i++) {
    EEPROM.write(address + i, str[i]);
  }
  // 写入结束符
  EEPROM.write(address + len, '\0');
}

// 读取字符串
String readString(int address) {
  String str = "";
  char ch;
  int i = 0;
  // 读取到结束符为止
  while ((ch = EEPROM.read(address + i)) != '\0' && i < 32) {
    str += ch;
    i++;
  }
  return str;
}

极简版代码(只读写单字节)

适合存储开关状态、数字 0-255

cpp 复制代码
#include <EEPROM.h>
#define EEPROM_SIZE 512
#define ADDR 0

void setup() {
  Serial.begin(115200);
  EEPROM.begin(EEPROM_SIZE);

  // 写入(0-255)
  EEPROM.write(ADDR, 100);
  EEPROM.commit(); // 必须提交

  // 读取
  byte val = EEPROM.read(ADDR);
  Serial.print("读取值:");
  Serial.println(val);
}

void loop() {}

重要使用规则

  1. 地址不能重叠

    • int/float 占 4 字节
    • char/byte 占 1 字节
    • 字符串根据长度分配
  2. 必须 commit

    • EEPROM.write() 只是写入缓存
    • 必须调用 EEPROM.commit() 才会保存到 Flash
  3. Flash 寿命

    • 模拟 EEPROM 擦写寿命约 10 万次
    • 不要在loop()里频繁写入
  4. 清空 EEPROM

cpp 复制代码
// 清空所有数据(写入0)
void clearEEPROM() {
  for (int i = 0; i < EEPROM_SIZE; i++) {
    EEPROM.write(i, 0);
  }
  EEPROM.commit();
}

总结

  1. ESP32 用 Flash 模拟 EEPROM,库文件EEPROM.h
  2. 流程:begin()write()commit()read()
  3. 支持 int/float/String/ 结构体存储
  4. 地址规划好,避免数据覆盖,commit 是保存关键
相关推荐
鉴生Eric2 小时前
BMA系统在工业厂房实现OT与IT融合时,具体如何解决不同品牌设备的数据协议兼容难题?
人工智能·物联网·工业厂房ot与it融合·智能边缘网关
鉴生Eric2 小时前
拉孚物联网bas系统与传统ba楼控系统区别
物联网
LinuxRos2 小时前
从 MCU 到 Linux:机器人嵌入式OTA升级原理解密
linux·单片机·嵌入式硬件·物联网·iot
MetrixAeroCore3 小时前
新加坡跨境物联网通信解决方案:Metrix Aero Core物联网卡本地化能力全解析
物联网
想你依然心痛3 小时前
工业物联网云原生时代:时序数据库全链路选型与 Apache IoTDB 实践
物联网·云原生·时序数据库·iotdb
逍遥德3 小时前
物联网-01-Spring Boot + MyBatis‑Plus 操作 IoTDB(表模型)
spring boot·物联网·iotdb
仰泳之鹅13 小时前
【物联网】使用MQTTX与OneNET云平台进行模拟MQTT协议通信
网络·物联网
河南博为智能科技有限公司15 小时前
基于物联网关的开闭所智能远程巡检控制系统设计方案!
物联网
华普微HOPERF20 小时前
电视冰箱洗衣机、空调风扇热水器,Matter协议如何塑造全屋智能?
嵌入式硬件·物联网·智能家居·matter协议·全屋智能