如何判断NodeMCU EEPROM是否未预存值?解决首次读取垃圾值问题
解决NodeMCU EEPROM首次读取垃圾值的问题
你已经想到用was_set标志做校验,这个思路非常靠谱!核心逻辑就是通过这个约定的标志值,判断EEPROM是否被我们初始化过——刚出厂的EEPROM里全是随机垃圾值,第一次读取时was_set肯定不是我们约定的9090,这时候就加载默认值并写入EEPROM,之后再读取就会正常调用预存的配置了。
下面是修改后的完整代码,我把关键逻辑标出来了:
#include <Arduino.h> #include <EEPROM.h> #include <ESP8266WiFi.h> #include <WiFiClient.h> #include <ESP8266WebServer.h> const char* ssid_default = "NodeMCU"; const char* pass_default = "1234"; uint addr = 0; ESP8266WebServer server(80); struct { int was_set = 9090; // 约定的初始化标志值,非该值则视为未初始化 char ssid[40]; // 优化命名避免和全局变量重名,更清晰 char pass[40]; int step = 0; } creds; void setup() { Serial.begin(9600); EEPROM.begin(512); delay(5000); // 从EEPROM读取结构体数据 EEPROM.get(addr, creds); // 核心判断:检查标志位是否符合约定,判断是否为首次启动 if (creds.was_set != 9090) { Serial.println("首次启动,加载默认配置并写入EEPROM"); // 给结构体赋值默认参数 strcpy(creds.ssid, ssid_default); strcpy(creds.pass, pass_default); creds.was_set = 9090; // 设置标志位为约定值 creds.step = 0; // 将默认配置写入EEPROM并提交 EEPROM.put(addr, creds); EEPROM.commit(); } else { Serial.println("读取已保存的配置"); } // 打印当前配置信息 Serial.print("当前SSID: "); Serial.println(String(creds.ssid)); Serial.print("当前密码: "); Serial.println(String(creds.pass)); Serial.print("执行次数: "); Serial.println(String(creds.step)); // 增加执行次数并保存 creds.step++; EEPROM.put(addr, creds); EEPROM.commit(); Serial.println("执行次数已增加,重启后可查看变化"); } void loop() { delay(1000); }
关键细节说明:
- 校验标志的核心作用:
was_set是判断EEPROM有效性的关键,只有我们主动写入过9090,才说明配置是有效的,否则就用默认值初始化。 - 字符数组赋值规范:不能直接用
creds.ssid = ssid_default,要使用strcpy函数复制字符串到字符数组中,这是C语言操作字符串的基础要求。 - EEPROM.commit()的必要性:每次修改EEPROM数据后必须调用该函数,否则修改只会停留在内存中,不会真正写入硬件存储。
- 命名优化:把结构体里的
ssid_default改名为ssid,避免和全局默认变量重名,代码可读性更高。
这样修改后,第一次启动会自动写入默认配置,之后每次启动都会读取之前保存的有效数据,再也不会出现垃圾值的问题了。
内容的提问来源于stack exchange,提问作者Piyush jain
相关产品推荐
相关产品推荐

