RS485半双工串口读写故障求助:pySerial通信无数据返回
修复RS485半双工串口读写无响应的问题
我来帮你排查这个RS485半双工通信的问题,你的代码里有几个关键误区,导致无法正常接收数据,下面一步步帮你修正:
核心问题分析
你当前的代码误用了rtscts硬件流控参数,这和RS485半双工的收发切换逻辑完全无关。RS485半双工需要手动控制RTS引脚电平来切换收发模式(使能/禁用发送器),而不是启用硬件流控。另外,你的时序切换和循环逻辑也有问题,导致接收不到设备的响应。
修正后的代码实现
下面是调整后的函数,我会标注关键修改点:
import serial import time def Transmission(ser, data): response = b"" # 初始化响应变量,避免未定义返回 if ser.isOpen(): try: print(f"待发送数据: {data}") # 清空收发缓冲区,避免残留数据干扰 ser.flushInput() ser.flushOutput() # 关键1:切换到发送模式(根据你的RS485模块调整RTS电平!) # 多数RS485模块是低电平使能发送,高电平切换到接收,若你的模块相反则改成True ser.rts = False # 确保数据是字节串(pySerial write要求传入bytes) if isinstance(data, str): data = data.encode('utf-8') ser.write(data) # 等待发送缓冲区完全清空,确保所有数据都发送出去 ser.flush() # 给设备预留响应时间(根据波特率调整,波特率越低需要越长时间) time.sleep(0.1) # 关键2:切换回接收模式,禁用发送器 ser.rts = True # 设置读取超时,避免readline无限阻塞 ser.timeout = 0.5 numOfLines = 0 while numOfLines < 5: line = ser.readline() if line: # 解码字节串为字符串并打印 print(f"收到数据: {line.decode('utf-8').strip()}") response += line numOfLines += 1 # 不建议每次调用都关闭串口,建议在外部统一管理串口生命周期 # ser.close() except Exception as e1: print(f"通信错误...: {str(e1)}") else: print("无法打开串口") return response
关键修改说明
- 替换
rtscts为直接控制ser.rts:rtscts=True是启用硬件流控(用于Modem握手),和RS485的收发切换无关。我们需要直接操控RTS引脚电平来控制RS485模块的发送使能端(DE/RE)。 - 正确的收发时序:发送前先切换到发送模式,发送完成后
flush()确保数据全部发出,再切换回接收模式,最后才开始读取响应。 - 添加读取超时:设置
ser.timeout避免readline()无限阻塞,没数据时会按时返回空值,循环可以正常退出。 - 字节串与字符串转换:pySerial的读写操作都基于字节串,所以要做好编码解码的转换。
- 避免频繁开关串口:串口的打开/关闭应该在外部主逻辑中统一处理,频繁开关容易导致通信异常。
额外硬件与参数检查
除了代码,还要确认这些硬件相关的点:
- 确认RS485模块的RTS引脚定义:有些模块是高电平使能发送,这时需要把
ser.rts = True作为发送模式,一定要对照模块的 datasheet 确认。 - 串口参数完全匹配:波特率、奇偶校验、停止位、数据位必须和目标设备的参数完全一致,参数不匹配会导致数据乱码或无法接收。
- RS485总线接线:A/B线不能接反,总线长度超过100米时要在两端接120Ω终端电阻,否则信号衰减会导致通信失败。
内容的提问来源于stack exchange,提问作者lemming




