Modbus TCP でいくつかのテストを行っていますが、 1 秒あたりにスキャンされるレジスタの最大数に関して、ここで計算された理論上の速度制限を理解するのに苦労しています。
私のテストでは、ラップトップからポーリングする modbus サーバー (スレーブ) をホストするためにビーグルボーンを使用しています。両方のデバイスがプライベート サブネット上にあり、そのサブネット上のデバイスは 2 つだけです。サーバーとクライアントは、pymodbus を使用して python で実装されています。テストとして、ブロック読み取りを使用して 6000 個の保持レジスター (48 個のブロック読み取りごとに 125 個のレジスター) をポーリングし、0.17163 秒かかりました。これは、約 35,000 レジスタ/秒のスキャン レートに相当します。これは高速ですが、上記のリンク先のページで計算された Base100T インターフェースの理論上の限界にはほど遠いものです。
そのページによると、Base100T 接続の理論上の制限は、約 3,600,000 レジスタ/秒です。Pythonプログラムのスループットなどによる損失があることは認識していますが、理論値よりもはるかに低いため、それらの大きな損失がどこにあるかを理解するのに苦労しています. スループットが制限される可能性があるのはどこですか?
以下は、このテストに使用したコードのリストです。
サーバー (ビーグルボーン)
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)