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

基于Pyserial传输,如何在Arduino中实现可靠的int64字节读取?

解决方案

一、是否需要在Python端添加结束符?

不需要额外添加特殊字符标识数据结束。你发送的是固定长度8字节的int64数据,Arduino端可以直接通过「等待并读取固定8字节」的方式完成可靠接收,这种方式比添加结束符更高效且逻辑简单。如果后续出现通信同步问题(比如初始连接时的字节错位),再考虑添加同步标记即可,当前场景下固定长度读取足够可靠。

二、Arduino端可靠读取8字节的实现

1. 读取8字节并解析为int64的函数

这个函数会阻塞等待直到凑够8字节,再按大端字节序(和Python端struct.pack(">q")对应)解析为int64_t类型:

#include <stdint.h> // 引入标准整数类型定义

int64_t readInt64FromSerial() {
  // 等待串口缓冲区至少有8字节数据
  while (Serial.available() < 8) {
    delay(1); // 短延时避免占用过多CPU资源
  }

  int64_t result = 0;
  // 大端字节序:从高位到低位依次读取字节并拼接
  for (int i = 0; i < 8; i++) {
    uint8_t byte = Serial.read();
    result = (result << 8) | byte;
  }
  return result;
}

2. 修改后的完整Arduino代码

替换你原有的占位逻辑,同时修正代码笔误:

#include <stdint.h>

int64_t readInt64FromSerial() {
  while (Serial.available() < 8) {
    delay(1);
  }

  int64_t result = 0;
  for (int i = 0; i < 8; i++) {
    uint8_t byte = Serial.read();
    result = (result << 8) | byte;
  }
  return result;
}

void setup() {
  Serial.begin(115200); // 波特率必须与Python端一致
}

void loop() {
  // 检测到串口有数据时,启动8字节读取流程
  if (Serial.available() > 0) {
    int64_t receivedValue = readInt64FromSerial();
    
    Serial.print("I received: ");
    Serial.println(receivedValue, DEC);
    Serial.write("ACK"); // 发送确认信号
  }
}

三、Python端的配套优化

原代码中readline()读取ACK的逻辑有问题:Arduino发送的是"ACK"(无换行符),readline()会因超时返回空。建议改为读取固定长度的3字节,确保正确接收确认:

import serial
import struct

def write_read(arduino, x):
    arduino.write(x)
    # 读取3字节的ACK确认信号
    data = arduino.read(3)
    return data

with serial.Serial(port='COM4', baudrate=115200, timeout=1) as arduino:    
    # 示例:发送一个int64类型数值
    test_value = -17
    packed_data = struct.pack(">q", test_value)
    ack = write_read(arduino, packed_data)
    print(f"Received ACK: {ack}")

内容的提问来源于stack exchange,提问作者user20035360

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 19:50:26