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

如何解决Python发送数组存入Arduino EEPROM时数据错误的问题

故障原因排查
  • Python端发送数据未携带换行符:Arduino端使用readStringUntil('\n')读取数据,但Python仅发送了数值的字符串内容,没有追加换行符,导致读取函数超时,返回不完整内容,转整数后结果异常。
  • Arduino端串口接收逻辑错误:loop中只要检测到串口有任意数据就立即循环156次尝试读取全部数组元素,但串口数据是逐帧传输的,单次触发时根本没有156条完整数据,后续读取全部超时返回空值。
  • 函数参数类型不匹配:writeIntArrayIntoEEPROM函数定义的第二个参数为int数组类型,但调用时传入的是numbers[i]这个单个int值,导致函数内部访问非法内存地址,读取到的写入值完全错误。
  • 不必要的串口缓冲区清空操作:写入函数内while(Serial.read() >= 0)会清空所有未处理的串口数据,直接丢弃后续待接收的数组元素。
  • 地址计数变量逻辑不合理:全局变量aux仅初始化一次为0,单次写入完成后不会重置,重复发送数据时会直接写入EEPROM越界地址。
修复方案

1. 修改Python端代码

发送每个数值时追加换行符,确保Arduino可以正确识别单条数据的结束位置:

for i in range(0,156):
    # 追加换行符作为单条数据的结束标记
    conexao.write((str(eeprom[i]) + '\n').encode('utf-8'))
    time.sleep(0.1) # 原2秒等待完全没必要,0.1秒足够EEPROM写入和串口传输
conexao.close()

2. 修改Arduino端代码

  • 简化EEPROM写入函数,修正参数错误
  • 改为单条数据接收逻辑,收一条写一条,避免批量读取超时
  • 移除不必要的缓冲区清空操作
  • 用接收计数计算写入地址,避免全局变量错误
#include <EEPROM.h>

const int STARTING_EEPROM_ADDRESS = 0;
const int ARRAY_SIZE = 156;
int recvCount = 0; // 记录已接收的元素数量

// 简化写入函数,直接传入要写入的地址和单个int值
void writeIntIntoEEPROM(int address, int value) {
  EEPROM.write(address, value >> 8);
  EEPROM.write(address + 1, value & 0xFF);
}

void readIntArrayFromEEPROM(int address, int numbers[], int arraySize) {
  int addressIndex = address;
  for (int i = 0; i < arraySize; i++) {
    numbers[i] = (EEPROM.read(addressIndex) << 8) + EEPROM.read(addressIndex + 1);
    addressIndex += 2;
  }
}

void setup() {
  Serial.begin(9600);
  // 启动时打印EEPROM内存储的数组用于校验
  int newNumbers[ARRAY_SIZE];
  readIntArrayFromEEPROM(STARTING_EEPROM_ADDRESS, newNumbers, ARRAY_SIZE);
  for (int i = 0; i < ARRAY_SIZE; i++) {
    Serial.println(newNumbers[i]);
  }
}

void loop() {
  // 还没接收完所有元素时才处理串口数据
  if (recvCount < ARRAY_SIZE && Serial.available() > 0) {
    String c = Serial.readStringUntil('\n');
    // 校验读取到的内容是否为有效数字,避免错误值写入
    if (c.length() > 0) {
      int value = c.toInt();
      int writeAddr = STARTING_EEPROM_ADDRESS + recvCount * 2;
      writeIntIntoEEPROM(writeAddr, value);
      recvCount++;
      // 可选:给Python返回应答确认写入完成,实现更可靠的传输
      Serial.print("recv ok:");
      Serial.println(value);
    }
  }
}

内容的提问来源于stack exchange,提问作者Carlos Henrique Santos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 19:45:08