如何通过 Modbus TCP 使用“struct.pack”类型发送?

Posted

技术标签:

【中文标题】如何通过 Modbus TCP 使用“struct.pack”类型发送?【英文标题】:How can I send with 'struct.pack' type over Modbus TCP? 【发布时间】:2019-04-03 13:22:49 【问题描述】:

我想通过 Modbus TCP 发送数据包。我想使用:

但是我不能以这种方式发送我该如何发送这个数据包? (我不知道会发生什么)

req = struct.pack(
   'Something', transaction, identifier, length, unitid, func_code, reg_addr
) 

这些是我的变量:

transaction=0x01
identifier=0x00
length=[0x00,0x06]
unitid=0x01
func_code=0x03
reg_addr=[0x13,0x14,0x15]

【问题讨论】:

为什么不使用pymodbus 库? 另外struct.pack 不支持列表作为参数。 【参考方案1】: 一开始你可以使用pymodbus库,功能非常丰富。 另外struct.pack() 不支持列表作为参数。 0001 0000 0006 11 03 006B 0003 是 Modbus-TCP 数据包的标准示例,其中包含:

0001: Transaction Identifier

0000: Protocol Identifier

0006: Message Length (6 bytes to follow)

11: The Unit Identifier (17 = 11 hex)

03: The Function Code (read Analog Output Holding Registers)

006B: The Data Address of the first register requested. (40108-40001 = 107 =6B hex)

0003: The total number of registers requested. (read 3 registers 40108 to 40110)

Reference

因此,您可以使用上面的示例创建一个 Modbus-TCP 数据包:

import struct

transaction = 0x0001
identifier = 0x0000
length = 0x0006
unitid = 0x11
fcode = 0x03  # Holding register fcode.
reg_addr = 0x006B  # Register address.
count = 0x0003  # Read three register.


total_pack_string = '0x:04x:04x:04x:02x:02x:04x:04x'.format(
    transaction, identifier, length, unitid, fcode, reg_addr, count
)
total_pack_hex = hex(int(total_pack_string, 16))

'''Or with using pack method.'''
pack_ = struct.pack(
   '>HHHBBHH', transaction, identifier, length, unitid, fcode, reg_addr, count
)

# Then send the pack_ or total_pack_hex using a TCP-Socket.

[注意]:

transaction 是 2Byte == 短 == H identifier 是 2Byte == 短 == H length 是 2Byte == 短 == H unitid 是 1Byte == B fcode 是 1Byte == B reg_addr 是 2Byte == 短 == H count 是 2Byte == 短 == H Bunsigned byte Hunsigned short

因此,格式将是这样的>HHHBBHH


使用pymodbus 等效:

from pymodbus.client.sync import ModbusTcpClient

unitid = 0x11
fcode = 0x03  # Holding register fcode.
reg_addr = 0x006B  # Register address.
count = 0x0003  # Read three register.

cli = ModbusTcpClient('127.0.0.1', port=502)

if cli.connect():
    res = cli.read_holding_registers(reg_addr, count=count, unit=unitid)
    
    if not res.isError():
        print(res.registers)
    else:
        print('There is an error.')
    cli.close()
else:
    print('Error in connection.')

【讨论】:

这是一个美妙的答案。谢谢你。 (我不想使用 pymodbus 库,所以我尝试不使用 pymodbus)

以上是关于如何通过 Modbus TCP 使用“struct.pack”类型发送?的主要内容,如果未能解决你的问题,请参考以下文章

modbus tcp和modbusrtu的区别

EasyARM i.mx287学习笔记——通过modbus tcp控制GPIO

omron cp1h modbus tcp 怎么设置

如何使用 Apache NiFi 读取 Modbus TCP/IP 数据?

modbus TCP/IP、EtherNet/IP与TCP/IP、以太网通讯是啥关系?

1200modbus连续读取多个数据