基于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
相关产品推荐
相关产品推荐

