使用PySerial通过USB转RS232适配器跨COM口收发数据时的空接收及编码问题求助
解决串口发送后接收为空的问题
我帮你排查了代码里的几个关键问题,这应该就是你用Python读取串口数据为空的原因:
核心问题分析
- 发送后立即关闭串口,数据未完成传输:你调用
send_data后马上断开了发送端串口,串口的write操作是异步的,数据可能还在发送缓冲区里,没来得及通过物理线缆传输出去就被中断了,接收端自然拿不到数据。 readline()依赖换行符,但发送数据不含换行:你发送的是'hellodd ',没有换行符\n,而serial.readline()会一直等待换行符直到超时,超时后就返回空字节串。- 串口参数未显式对齐:虽然默认参数是8位数据位、无校验、1位停止位(8N1),但最好显式配置,避免和Hterm的设置不一致导致数据解析异常。
- 接收时机过早:发送完立刻去读接收端,可能数据还没传到接收端的串口缓冲区,导致读取时缓冲区为空。
修改后的代码
import serial from tkinter import * root = Tk() root.geometry('300x200') root.resizable(False, False) def myClick(): # 显式配置完整串口参数,和接收端保持一致 scm = SerialConnectionManager('COM6', 38400) scm.connect_port() # 发送带换行符的数据,适配readline() scm.send_data('hellodd\n') # 等待数据发送完成再关闭串口 scm.sc.flush() scm.disconnect_port() # 初始化接收端串口,同样显式配置参数 serialObj = serial.Serial( port='COM5', baudrate=38400, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1 # 稍微延长超时时间,确保数据能到达 ) # 方式1:用readline(),对应发送的换行符 receivedData = serialObj.readline() # 方式2:如果不想加换行符,可以指定读取长度,比如len('hellodd ') = 7 # receivedData = serialObj.read(7) print(f"Received: {receivedData}") print(f"Decoded: {receivedData.decode('utf-8').strip()}") serialObj.close() class SerialConnectionManager(): def __init__(self, port, baudrate): self.sc = serial.Serial() self.sc.baudrate = baudrate self.sc.port = port # 显式配置串口参数,和接收端统一 self.sc.bytesize = serial.EIGHTBITS self.sc.parity = serial.PARITY_NONE self.sc.stopbits = serial.STOPBITS_ONE self.sc.timeout = 1 def connect_port(self): if not self.sc.is_open: self.sc.open() def disconnect_port(self): if self.sc.is_open: self.sc.close() def send_data(self, message): if self.sc.is_open and message != "": self.sc.write(message.encode('utf-8')) root.mainloop()
关键修改说明
- 添加
flush()确保数据发送完成:在关闭发送端串口前调用scm.sc.flush(),会等待缓冲区所有数据发送完毕再继续执行,避免数据丢失。 - 发送数据添加换行符:把
'hellodd '改成'hellodd\n',这样readline()能正确识别结束符,返回完整数据。如果不想用换行符,也可以用serialObj.read(7)指定读取7个字节(对应原字符串长度)。 - 显式配置所有串口参数:在初始化串口时指定
bytesize、parity、stopbits,确保和Hterm以及接收端的参数完全一致,避免因参数不匹配导致数据乱码或无法接收。 - 延长接收超时时间:把接收端的
timeout从0.5秒改成1秒,给数据传输留足够的时间。
另外,你可以先在Hterm里同时打开COM5和COM6,手动发送带换行的数据,确认接收端能收到,再用Python代码测试,这样能排除硬件线缆的问题。
内容的提问来源于stack exchange,提问作者Arian P
相关产品推荐
相关产品推荐

