You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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.rtsrtscts=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

火山引擎 最新活动