本人从事的项目中需要多串口、多设备读取串口数据,要求响应速度足够快,原本用的是modbus-tk库,每个串口设置一个通信线程,串口内各设备轮询读取数据。相信这也是大多数用户的常见用法。
用了一段时间后意外发现,只要其中一个串口通信中断,则其他串口的线程也都等待,造成整个系统的通信瞬间慢下来。我估计是modbus-tk内部采用了同步控制,但是怎么也找不到设置的地方,网上也搜不到资料。无奈之下尝试改用pymodbus库,瞬间通信顺畅起来,不同线程之间完全没有影响。
正在以为问题得到解决的时候,却发现采用pymodbus库后通信误码率大幅度增加,到了难以忍受的程度。用串口监测,发现每次都有正确返回的前提下,仍旧有许多被判定读取失败。
下面是一个典型的pymodbus库读取03数据的测试函数:
def modbus_communication(port):
client = ModbusSerialClient(port=port, baudrate=19200, timeout=10)
try:
while True:
# 假设读取保持寄存器地址为 0 的值
# if client.connect():
# print("Modbus RTU Client Connected")
# else:
# print("Failed to connect to Modbus RTU Client")
result = client.read_holding_registers(0, 6, slave=1)
# print(f"Port24 {port}: {result}")
if result.isError():
print(f" {port} tx_f/tx_ok = {tx_f}/{tx_ok} Error: {result}")
else:
print(f" {port}: {result.registers}")
except Exception as e:
print(f"Port17 {port}tx_f/tx_ok = {tx_f}/{tx_ok} Exception: {e}")
tx_f += 1
finally:
client.close()
下面调用测试函数的线程:
threading.Thread(target=modbus_communication, args=('COM3',)).start()
在线路非常好的前提下,误码率达到5%,不可理解,我再用modbus-tk测试同样的硬件设备通信情况,几乎不掉线。多方查找client的创建函数的各种参数和client.read_holding_registers函数的各项参数未能找到有效的设置方法,后来偶然发现client有一个可以设置的对象名inter_byte_timeout,打印了一下默认值为0.00078125,把它改成0.1后问题终于解决。这个参数应该是用于设置数据间等待时长,我们的波特率设置是19200,数据间因各种偶然因素导致该库判断数据已经结束,然后通不过校验,导致出错。
1718

被折叠的 条评论
为什么被折叠?



