【问题标题】:What is the pymodbus syntax to assign values to TCP server registers?将值分配给 TCP 服务器寄存器的 pymodbus 语法是什么?
【发布时间】:2019-08-26 22:18:27
【问题描述】:

我正在尝试使用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)

假设我想将152 的值存储到Input Register (ir) 地址30001 并将276 的值存储到地址30002?我应该如何调整上面的代码?

【问题讨论】:

    标签: python modbus modbus-tcp pymodbus


    【解决方案1】:

    假设我想将值 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]
    

    【讨论】:

      【解决方案2】:

      来自 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的顺序数据块,每个地址都用值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=True 没有这个,read_input_registers 对偏移量 0 的请求将返回 276 而不是 152,这是因为没有 zero_mode=True pymodbus 尝试根据第 4.4 节存储值规范,因此地址(0-7)将映射到(1-8)。如果您不想使用zero_mode,则将数据块初始化为ir=ModbusSequentialDataBlock(1, [152, 276])

      【讨论】:

        猜你喜欢
        • 2019-07-30
        • 1970-01-01
        • 2014-11-09
        • 1970-01-01
        • 2015-03-08
        • 2021-12-21
        • 1970-01-01
        • 2021-06-22
        • 2014-10-31
        相关资源
        最近更新 更多