You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
}

问题分析与解决建议

  1. 字符串终止符缺失:SparkFun库的get方法读取String时默认以\0作为终止符,但写入程序生成的CSV字符串未显式添加该终止符,且未填充到sampleSize长度,导致读取时无法正确识别数据结束位置,进而重复读取无效内容。

    • 解决:写入时在字符串末尾添加\0,或用空格将字符串补全至sampleSize长度。
  2. get方法读取长度不明确:当前读取代码仅传入地址和String变量,库可能默认读取到\0为止,若写入数据无终止符则读取异常。建议改用read方法指定读取长度:

    char tempBuffer[33]; // 预留一个字节存终止符
    myMem.read(sampleCounter*sampleSize, tempBuffer, sampleSize);
    tempBuffer[sampleSize] = '\0'; // 手动添加终止符
    sampleRead = String(tempBuffer);
    sampleRead.trim(); // 去除末尾无效空白字符
    
  3. 地址边界检查:确认sampleCounter*sampleSize未超出24LC256的地址范围(24LC256共32768字节,32字节单样本最多可存1024条数据),读取时可添加地址上限判断避免溢出。

  4. 写入完成确认:24LC256单字节写入最多需5ms,写入程序虽有1秒延迟,但读取程序运行前需确保所有写入操作已完成(如停止写入程序后再上传读取程序)。

内容的提问来源于stack exchange,提问作者Playing with GAS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:35:46