Arduino外接I2C EEPROM读取异常:重复读取相同数据
Arduino 24LC256 EEPROM 读取异常问题
问题现象
使用SparkFun_External_EEPROM库向24LC256型I2C外接EEPROM写入CSV格式数据时,写入程序自带的实时读取验证功能正常,串口可输出包含递增SampleCounter和随机值的CSV行;但单独运行读取程序时,会重复读取相同数据,且无法确认是否为实际存储的记录。更换两款不同的I2C/EEPROM模块、两台不同的Arduino设备,以及使用两人编写的相似代码,均出现相同问题。
写入程序(含调试读取代码,串口输出正常)
/* Library: SparkFun_External_EEPROM_Arduino_Library Stores serial number and 2 values Also reads to get confirmation on Ser mon.*/ #include <Wire.h> #include "SparkFun_External_EEPROM.h" ExternalEEPROM myMem; String sample2Write = ""; // 构建单条样本数据 String sampleRead = ""; int sampleCounter = 0; int sampleSize = 32; // 单条样本占用字节数 void setup() { Serial.begin(9600); Wire.begin(); if (myMem.begin() == false) { Serial.println("未检测到存储器。程序暂停。"); while (1); } } void loop() { delay(1000); sampleCounter++; // 写入数据 sample2Write = ""; sample2Write = sample2Write + String(" - ") + "," ; // 预留字段 sample2Write = sample2Write + String(sampleCounter) + "," ; sample2Write = sample2Write + String(random(10, 20)) + "," ; sample2Write = sample2Write + String(random(21, 30)); myMem.put(sampleCounter * sampleSize, sample2Write); // (存储地址, 数据) // 以下读取仅用于实时调试,实际读取使用独立程序 sampleRead = ""; myMem.get(sampleCounter * sampleSize, sampleRead); // (读取地址, 接收变量) Serial.println(sampleRead); }
读取程序(串口重复显示相同CSV数据,非实际存储值)
/* Library: SparkFun_External_EEPROM_Arduino_Library*/ #include <Wire.h> #include "SparkFun_External_EEPROM.h" ExternalEEPROM myMem; String sampleRead = ""; int sampleSize = 32; // 单条样本占用字节数 int sampleCounter = 0; void setup() { Serial.begin(9600); Wire.begin(); if (myMem.begin() == false){ Serial.println("未检测到存储器。程序暂停。"); while (1); } } void loop(){ delay(300); // 读取数据并显示到串口监视器 sampleCounter++; sampleRead=""; myMem.get(sampleCounter*sampleSize, sampleRead); // (读取地址, 接收变量) Serial.println(sampleRead); }
问题分析与解决建议
字符串终止符缺失:SparkFun库的
get方法读取String时默认以\0作为终止符,但写入程序生成的CSV字符串未显式添加该终止符,且未填充到sampleSize长度,导致读取时无法正确识别数据结束位置,进而重复读取无效内容。- 解决:写入时在字符串末尾添加
\0,或用空格将字符串补全至sampleSize长度。
- 解决:写入时在字符串末尾添加
get方法读取长度不明确:当前读取代码仅传入地址和String变量,库可能默认读取到\0为止,若写入数据无终止符则读取异常。建议改用read方法指定读取长度:char tempBuffer[33]; // 预留一个字节存终止符 myMem.read(sampleCounter*sampleSize, tempBuffer, sampleSize); tempBuffer[sampleSize] = '\0'; // 手动添加终止符 sampleRead = String(tempBuffer); sampleRead.trim(); // 去除末尾无效空白字符地址边界检查:确认
sampleCounter*sampleSize未超出24LC256的地址范围(24LC256共32768字节,32字节单样本最多可存1024条数据),读取时可添加地址上限判断避免溢出。写入完成确认:24LC256单字节写入最多需5ms,写入程序虽有1秒延迟,但读取程序运行前需确保所有写入操作已完成(如停止写入程序后再上传读取程序)。
内容的提问来源于stack exchange,提问作者Playing with GAS
相关产品推荐
相关产品推荐

