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 是保存关键
相关推荐
尺度商业3 小时前
中国稀土集团创新科技有限公司与本末科技战略合作落地
科技·物联网
m0_738185823 小时前
Flutter 鸿蒙化实战:flutter_iot_wifi 适配 OpenHarmony,IoT 设备 WiFi 配网
物联网·flutter·华为·harmonyos·鸿蒙
byte轻骑兵3 小时前
【PBAP】规范精讲[3]: 蓝牙PBAP协议应用层核心——电话本数据的格式与交互逻辑解析
物联网·蓝牙·pbap·短距离通信协议
沐欣工作室_lvyiyi4 小时前
基于物联网的智能商业零售管理系统设计与实现(论文+源码)
物联网·mysql·mysql数据库·零售
传感器与混合集成电路13 小时前
模态识别离不开三向同步:火箭振动测点选择与三轴压电加速度计配置方法
物联网
KaiwuDB16 小时前
KaiwuDB 运维实战04:DRBD + KaiwuDB——物联网场景下的低成本数据库高可用方案
运维·数据库·物联网·时序数据库·kaiwudb·aiot·多模数据库
盛世宏博北京16 小时前
档案库房防护能力升级:从八防到十二防的物联网全维度感知防护体系建设方案
网络·物联网
港股研究社21 小时前
餐饮IPO冰封期,袁记食品的“供应链平台”启示
大数据·人工智能·物联网
HZZD_HZZD1 天前
NILM模型换个楼F1就从0.87跌到0.62?合众致达跨楼宇迁移实测:冻结卷积微调7天数据让洗衣机分解F1回升至0.81
大数据·物联网
新中地GIS开发老师1 天前
空间信息与数字技术VS地理空间信息工程,两个专业有什么区别?考研有哪些选择?
物联网·gis开发