Matlab与Python串口通信差异及超128数值发送问题咨询
问题解答
1. Matlab与Python串口通信的核心差异
这里的核心问题在于二进制字节的发送逻辑完全不同:
- 在Matlab里,当你用
fwrite(s, int_value)发送0-255的整数时,它会直接把这个整数转换成单字节的二进制数据发出去。比如发送255,串口上传输的就是单个字节0xff,和你预期的完全一致。 - 而你最初在Python里用
chr(m).encode(),默认是用UTF-8编码字符串。UTF-8对0-127的ASCII字符是单字节编码,但128-255的字符会被拆成多字节(比如chr(255).encode()得到b'\xc3\xbf',这是两个字节)。Arduino那边本来只等一个字节,结果收到两个,自然没法正确解析,导致通信失效。
至于你尝试的encode('charmap'),虽然偶尔能得到单字节,但这个方式依赖系统默认的字符映射表,不同系统可能有差异,而且不是构造二进制字节的标准做法,可靠性远不如直接操作bytes对象。
2. 如何通过Python串口发送128-255之间的数值
要和Matlab的fwrite行为对齐,你需要跳过字符串编码这一步,直接构造单字节的bytes对象。这里有几种简单可靠的方法:
最直接的方法:用bytes()构造单字节
把你代码里的s.write(chr(m).encode())替换成:
s.write(bytes([m]))
bytes([m])会直接把0-255的整数转换成对应的单字节二进制数据,比如m=255时就是b'\xff',和Matlab发送的内容完全一致。
修改后的完整Python测试代码
import serial from time import sleep port = 'COM4' baudrate = 38400 s = serial.Serial(port, baudrate) sleep(3) # 给Arduino留足初始化时间 # 测试发送255(之前失效的数值) m = 255 s.write(bytes([m])) # 等待接收回传数据 while s.in_waiting == 0: print('##### waiting for response #####') sleep(0.5) # 缩短等待间隔,不用等2秒 if s.in_waiting > 0: r = int.from_bytes(s.read(), byteorder='big') print(f"Received byte: {r}") s.close()
对应的Arduino测试代码(调整判断逻辑)
如果你要测试255这个数值,需要把Arduino的判断条件改成对应值:
void setup() { pinMode(13, OUTPUT); digitalWrite(13, LOW); Serial.begin(38400); } void loop() { if (Serial.available() > 0) { byte received_byte = Serial.read(); if (received_byte == 255) { // 匹配发送的255 digitalWrite(13, HIGH); Serial.write(received_byte); // 回传收到的字节 delay(2000); digitalWrite(13, LOW); } } else { digitalWrite(13, LOW); } }
其他可选方法
- 用
struct.pack:比如s.write(struct.pack('B', m)),其中'B'表示无符号单字节字符,效果和bytes([m])完全一样。 - 直接写死字节串:如果知道具体的字节值,比如要发255,可以直接写
s.write(b'\xff')。
这样修改后,不管你发送0-255之间的任何数值,都能和Matlab的发送行为保持一致,Arduino就能正确接收并响应了。
内容的提问来源于stack exchange,提问作者hknauer
相关产品推荐
相关产品推荐

