我正在使用 Modbus TCP 进行一些测试,我正在努力理解此处计算的关于每秒扫描的最大寄存器数的理论速度限制。
我的测试是使用 beaglebone 来托管我从笔记本电脑轮询的 modbus 服务器(从属服务器)。两台设备都位于私有子网上,并且它们是该子网上仅有的两台设备。服务器和客户端在 python 中使用 pymodbus 实现。作为测试,我使用块读取来轮询 6000 个保持寄存器(48 个块读取中的每一个 125 个寄存器),并且花费了 0.17163 秒。这转化为大约 35,000 个寄存器/秒的扫描速率。这速度很快,但与上面链接页面中计算的 Base100T 接口的理论极限相去甚远。
根据该页面,Base100T 连接的理论限制应该在 3,600,000 个寄存器/秒左右。我意识到由于 python 程序的吞吐量等原因会有一些损失,但是它比理论值低得多,以至于我很难理解这些主要损失在哪里。吞吐量会限制在哪里?
以下是我用于此测试的代码清单:
服务器(Beaglebone)
from pymodbus.server.sync import StartTcpServer
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
def run_server():
holding_registers = ModbusSequentialDataBlock(0,[i for i in range(15000)])
store = ModbusSlaveContext(hr = holding_registers)
context = ModbusServerContext(slaves=store, single=True)
StartTcpServer(context, address=("localhost", 5020))
if __name__ == "__main__":
run_server()
客户端(笔记本电脑)
import time
import math
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
modbus = ModbusClient('192.168.0.10', port=5020)
modbus.connect()
def timeit(f):
def timed(*args, **kw):
ts = time.time()
result = f(*args, **kw)
te = time.time()
print('func: {} took: {} sec'.format(f.__name__, te-ts))
return result
return timed
@timeit
def block_read_arbitrary(bus, n):
last_read = n % 125
if last_read > 0:
nreads = int(math.ceil(n/125))
else:
nreads = int(n/125)
print("Reading {} Blocks...".format(nreads))
data = []
for i in range(nreads):
if i == nreads - 1 and last_read > 0:
rr = bus.read_holding_registers(i*125, last_read)
data.extend(rr.registers)
else:
rr = bus.read_holding_registers(i*125,125)
data.extend(rr.registers)
return data
block_read_arbitrary(bus, 6000)