`ModbusSerialClient`性能很差,快到超时了

问题描述 投票:0回答:2

对于一个项目,我有 4 个 modbus 设备连接在 RS485 串行线上。这些设备工作正常,现在我正在编写一个控制器,我对

pymodbus
的性能非常不满意。

我找到了这个线程Python modbus库,在我看来,可能有更好的python modbus库。

pymodbus
很容易使用,如果可能的话我宁愿继续使用它。

但是我发现任何读/写例程返回所需的时间等于超时。这对我来说似乎不对,所以我写了一个快速测试:

from pymodbus.client.sync import  ModbusSerialClient
import time

for t in xrange(1, 11):
    client = ModbusSerialClient("rtu", port="/dev/ttyUSB0", baudrate=9600, timeout=t)

    start = time.time()
    data = client.read_holding_registers(0x9000, count=7, unit=2)
    stop = time.time()

    if data:
        succ = "was successful"
    else:
        succ = "failed"

    print "timeout: %ss, read %s, time spent reading: %fs" % (t, succ, stop-start)

这是我得到的输出

timeout: 1s, read was successful, time spent reading: 1.039731s
timeout: 2s, read was successful, time spent reading: 2.038965s
timeout: 3s, read was successful, time spent reading: 3.041441s
timeout: 4s, read was successful, time spent reading: 4.040762s
timeout: 5s, read was successful, time spent reading: 5.043523s
timeout: 6s, read was successful, time spent reading: 6.040139s
timeout: 7s, read was successful, time spent reading: 7.042159s
timeout: 8s, read was successful, time spent reading: 8.045216s
timeout: 9s, read was successful, time spent reading: 9.047682s
timeout: 10s, read was successful, time spent reading: 10.048799s

我用不同的 RS845<->USB 转换器对其进行了测试,并且总是得到类似的结果。

其他人可以证实这一点吗?或者我是否遗漏了一些未记录的论点,这些论点会提高

ModbusSerialClient
的性能?

python modbus rs485
2个回答
2
投票

我可以确认 - pymodbus 总是等待超时(1-3 秒),即使它立即收到从站的响应(在我的情况下为 14 毫秒)。所以我用minimalmodbus进行了测试,并立即收到了响应。在我的例子中,当我用循环测试它时,每秒高达35次。

编辑:我找到了原因 - pymodbus 在使用 RTU 协议时等待超过 1000 个字节或超时。他们需要计算预期的字节,并且他们对此有修复,但这还没有在主分支中(AFAIK)。检查这篇文章https://github.com/bashwork/pymodbus/issues/76所以如果你真的需要使用pymodbus你可以尝试补丁。


0
投票

我也有同样的问题。当我移动

时它对我有用
client = ModbusSerialClient("rtu", port="/dev/ttyUSB0", baudrate=9600, timeout=t)

在for循环之前,像这样:

from pymodbus.client.sync import  ModbusSerialClient
import time

client = ModbusSerialClient("rtu", port="/dev/ttyUSB0", baudrate=9600, timeout=t)
for t in xrange(1, 11):

    start = time.time()
    data = client.read_holding_registers(0x9000, count=7, unit=2)
    stop = time.time()

    if data:
        succ = "was successful"
    else:
        succ = "failed"

    print "timeout: %ss, read %s, time spent reading: %fs" % (t, succ, stop-start)
© www.soinside.com 2019 - 2024. All rights reserved.