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 是保存关键
相关推荐
乐讯通物联网服务商7 小时前
智能蒸烤箱连 WiFi 还是插物联网卡?家电联网方案怎么选
物联网·物联网卡·厨房家用电器
数字会议深科技10 小时前
会议方案设计应如何融入 AI 和物联网等领先会议技术
人工智能·物联网·会议解决方案·会议设计方案
Alinket10 小时前
不训练模型也能加 AI:5 套可直接量产的组合方案
人工智能·物联网·ai·健康医疗·无线通信·智能硬件·iot
wuyk55511 小时前
《WiFi 嵌入式物联网开发全套实战》| 第 44 章 物联网 WiFi 产品整体架构设计(配网 + 通信 + 保活 + 升级)
物联网
SL-staff12 小时前
4G设备掉线三层归因实战:SIM卡、模组、JVS-IOT网关配置的精准诊断与代码级验证
物联网·mqtt协议·at指令·嵌入式通信·jvs-iot·4g调试·物联网运维
珠海西格电力13 小时前
物联网(IoT)在零碳园区中的关键作用:万物互联与数据采集
大数据·人工智能·物联网·安全·系统架构·能源
权球物联分享物联网连接服务14 小时前
墒情站自带摄像头,土壤墒情监测物联网卡就不能只按数值配
物联网
wuyk55514 小时前
《WiFi 嵌入式物联网开发全套实战》 | 第 45 章【终章】WiFi 开发全套知识复盘 + 面试高频题 + 进阶路线
物联网·面试·职场和发展
权球物联国际流量服务16 小时前
设备出海怎么联网?匈牙利物联网卡选型与回传要点
物联网
乐讯通物联网服务商16 小时前
户用储能柜里的 PCS 变流器,为什么也需要物联网卡?
物联网·物联网卡·储能变流器