3

我正在尝试使用Synchronous Server Example实现一个简单的同步 TCP 服务器。但是,我不理解文档中的语法解释。该示例包括以下代码块:

store = ModbusSlaveContext(
     di=ModbusSequentialDataBlock(0, [17]*100),
     co=ModbusSequentialDataBlock(0, [17]*100),
     hr=ModbusSequentialDataBlock(0, [17]*100),
     ir=ModbusSequentialDataBlock(0, [17]*100))

context = ModbusServerContext(slaves=store, single=True)

假设我想存储152to address 的值和 to Input Register (ir)address的30001值?我应该如何调整上面的代码?27630002

4

2 回答 2

2

假设我想将值 152 存储到“输入寄存器 (ir)”地址 30001,将值 276 存储到地址 30002?我应该如何调整上面的代码?

以下代码是您想要的:

from pymodbus.server.sync import StartTcpServer
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

import logging
FORMAT = ('%(asctime)-15s %(threadName)-15s'
          ' %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)


def run_server():
    store = ModbusSlaveContext(
        ir=ModbusSequentialDataBlock(30001, [152, 276]), 
        zero_mode=True
    )
    context = ModbusServerContext(slaves=store, single=True)
    StartTcpServer(context, address=("localhost", 5020))


if __name__ == "__main__":
    run_server()

测试用例:

from pymodbus.client.sync import ModbusTcpClient as ModbusClient

cli = ModbusClient('127.0.0.1', port=5020)
assert cli.connect()
res = cli.read_input_registers(30001, count=2, unit=1)
assert not res.isError()
print(res.registers)

出去:

[152, 276]
于 2019-04-08T20:38:01.387 回答
0

来自 Pymodbus 文档。

数据存储仅响应它们初始化的地址。因此,如果您将 DataBlock 初始化为 0x00 到 0xFF 的地址,则对 0x100 的请求将响应无效地址异常。这是因为许多设备都表现出这种行为(但不是全部)::

 block = ModbusSequentialDataBlock(0x00, [0]*0xff)

ModbusSequentialDataBlock初始化addressvalue.

address – The starting address
values –  List of values to initialise each address with. 

数据块的总大小取决于len(values).

所以看上面的例子,我们试图创建一个大小的顺序数据块,0xFF每个地址都用 value 初始化0。同样,在您的情况下,如果您要将值 152 存储到“输入寄存器 (ir)”地址 30001,并将值 276 存储到地址 30002,那么您必须执行以下操作。

存储 = ModbusSlaveContext(

         di=ModbusSequentialDataBlock(0, [17]*100),
         co=ModbusSequentialDataBlock(0, [17]*100),
         hr=ModbusSequentialDataBlock(0, [17]*100),
         ir=ModbusSequentialDataBlock(0, [152, 276]), zero_mode=True)

context = ModbusServerContext(slaves=store, single=True)

请注意,如果不使用 kwarg zero_mode=Trueread_input_registers针对偏移量 0 的请求将返回 276 而不是 152,这是因为不使用zero_mode=Truepymodbus 会尝试根据规范的第 4.4 节存储值,因此 address(0-7) 将映射到(1-8)。如果您不想使用zero_mode,则将数据块初始化为ir=ModbusSequentialDataBlock(1, [152, 276]).

于 2019-04-06T05:15:41.910 回答