使用: python3,pyModbusTCP,Linux,Raspberry pi 4,ViewMarq
我有一个数字显示板,可以接收ModBusTCP ascii包。下面的信息类似于我试图作为测试消息发送的内容。
Test
我刚开始使用pyModbus,并尝试使用pyModbus客户端通过端口502将数据发送到其411000的持有寄存器,我认为这仅仅是11000,因为删除了4。我已经建立了一个简单的客户端脚本,可以与板通信,但我必须对消息进行编码才能将其发送到寄存器。在PLCs的世界里,这要简单得多,但在这里这不是一个选择。
使用windows应用程序填充板,检测到我的Wireshark modbus数据如下:
Ethernet II, Src: Dell_63:da:e2 (34:48:ed:63:da:e2), Dst: FACTSEng_06:6c:fc (60:52:d0:06:6c:fc)
Internet Protocol Version 4, Src: 169.254.108.210, Dst: 169.254.108.223
Transmission Control Protocol, Src Port: 55053, Dst Port: 502, Seq: 1, Ack: 1, Len: 85
Modbus/TCP
Transaction Identifier: 256
Protocol Identifier: 0
Length: 79
Unit Identifier: 1
Modbus
.001 0000 = Function Code: Write Multiple Registers (16)<nl>
Reference Number: 10999
Word Count: 36
Byte Count: 72
Register 10999 (UINT16): 18748
Register 11000 (UINT16): 8260
Register 11001 (UINT16): 12339
Register 11002 (UINT16): 15422
Register 11003 (UINT16): 19523
Register 11004 (UINT16): 15954
Register 11005 (UINT16): 22332
Register 11006 (UINT16): 20041
Register 11007 (UINT16): 12320
Register 11008 (UINT16): 12320
Register 11009 (UINT16): 12832
Register 11010 (UINT16): 14136
Register 11011 (UINT16): 13088
Register 11012 (UINT16): 15921
Register 11013 (UINT16): 20540
Register 11014 (UINT16): 21327
Register 11015 (UINT16): 12320
Register 11016 (UINT16): 12320
Register 11017 (UINT16): 15422
Register 11018 (UINT16): 19020
Register 11019 (UINT16): 15422
Register 11020 (UINT16): 19522
Register 11021 (UINT16): 20000
Register 11022 (UINT16): 15422
Register 11023 (UINT16): 21315
Register 11024 (UINT16): 12320
Register 11025 (UINT16): 15422
Register 11026 (UINT16): 21063
Register 11027 (UINT16): 15950
Register 11028 (UINT16): 21564
Register 11029 (UINT16): 21566
Register 11030 (UINT16): 29541
Register 11031 (UINT16): 15476
Register 11032 (UINT16): 21551
Register 11033 (UINT16): 3390
Register 11034 (UINT16): 52237从这里开始,我对下一步该做什么感到有点困惑。我试着读了那些注册地址,但那里什么也没看到。
from pyModbusTCP.client import ModbusClient
client = ModbusClient('169.254.108.223', port=502)
client.open()
print(client.read_holding_registers(10999,100))然后收到..。
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,..... <all 100 zeros>]有人能帮我理解一下,如果我在朝着正确的方向前进,我下一步该怎么做?我尽量让这件事简单化,我很感激你的帮助。
提前谢谢你。
更新:
在提出建议后,我更深入地研究了文档。显示的文档会在执行完成后立即返回到0。从医生那里*
c)字交换和字节交换应该被选中,前提是ViewMarq显示中的选项为Off (默认)。d)从Modbus内存起始地址是命令块在ViewMarq显示中的位置(400000+11000 = 411000)。( e)功能代码应设置为16 -写入多个寄存器。
我得承认。我不知道怎么写有效载荷。我重写了代码并尝试了一种有效载荷构造方法。
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.payload import BinaryPayloadBuilder
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
from pymodbus.compat import iteritems
from collections import OrderedDict
client = ModbusClient('169.254.108.223', port=502)
client.connect()
builder = BinaryPayloadBuilder(byteorder=Endian.Little, wordorder=Endian.Little)
builder.add_string("<ID 30><CLR>""$0D") #$0D is the termination code in the docs
payload = builder.build()
client.write_registers(10999, payload, skip_encode=True, unit=1)这不管用。它运行了,但董事会没有更新。建议是非常欢迎的。
发布于 2020-09-30 18:51:54
这不是解决你的问题的一个完整的解决方案,而只是一个下一步该做什么的建议。
- Maybe the command buffer registers are write only?
- Or maybe you will read all 0 when the display has processed the command?18748=0x493c -> 0x49='I' 0x3c='<' ->
8260=0x2044 -> 0x20=' ' 0x44='D' ->
12339=0x3033 -> 0x30='0' 0x33='3' ->
这3个写入寄存器的值对应于"<ID 30"等。
因此,每个Modbus寄存器似乎对应2字节的缓冲区,以小字节的字节顺序。
最有可能的情况是响应缓冲区是相同的。
编辑了问题后的:
如果您的程序不工作,比较从您的程序发送的数据和从Windows应用程序发送的数据,例如使用Wireshark。
https://stackoverflow.com/questions/64143222
复制相似问题