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 是保存关键
相关推荐
乐讯通物联网服务商1 小时前
可视烟感器是怎么组网报警的?联网型烟感与物联网卡的数据链路解析
物联网·物联网卡·烟感器
一知半解仙18 小时前
乌镇2026:当“智能互联网”第一次被数据照进现实
人工智能·物联网·机器人·开源
梯度下降者1 天前
软硬件开源!一套物联网监测平台
物联网·开源·边缘计算·农业·双端管理
国科安芯2 天前
把接口变成观测量:CANFD收发器状态可观测性驱动的星上故障检测隔离与恢复方法
大数据·人工智能·物联网·卫星·抗辐射·通信芯片·载荷
Dev_XH2 天前
【成品设计】基于CH32H417的CH32H417AIOT家庭微电网
单片机·嵌入式硬件·物联网·ai
t13970182 天前
MPPT 和 PWM 有什么区别?小功率太阳能供电到底该选哪个
嵌入式硬件·物联网
QXWZ_IA2 天前
定位数据怎么推给 IoT 平台?消息协议选型与接入准备
网络·人工智能·物联网·安全
天空'之城2 天前
010基于 ESP32-CAM 的智能家居视频监控系统
物联网·毕业设计·视频监控·esp32-cam·移动侦测
Dev_XH2 天前
【成品设计】基于物联网的旅游生态农业互动系统
stm32·单片机·嵌入式硬件·物联网·旅游
智码看视界2 天前
Edge AI 与 IoT 全栈:云端时序数据库 + Grafana 看板,把数据变成洞察
物联网·mqtt·esp32·时序数据库·influxdb·tdengine