首页 > 解决方案 > 在使用 modbus_tk 库时需要帮助

问题描述

我正在使用 modbus_tk 库作为 Modbus RTU 从站。我有一个现成的 Modbus RTU 主模拟器,通过 USB 到 485 转换器在另一台 PC 上运行。我在 Master 中看不到我的持有登记册。

我已经验证了串行链路是好的,因为我可以使用串行程序向从机发送字符串。我尝试为 16 位和 32 位整数设置主控,响应始终为 83 04。我尝试使用几个不同的主控,起始地址为 0,这个恰好默认为第一个寄存器 40001。波特率和串行端口设置匹配。

import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
import serial
import time  

modbusServ = modbus_rtu.RtuServer(serial.Serial('/dev/ttyS0'),baudrate= 9600,
                 bytesize=8, parity='N', stopbits=1, xonxoff=0)
print("start")

modbusServ.start()

slave_1 = modbus_tk.modbus.Slave(1)

slave_1.add_block("BlockName", modbus_tk.defines.HOLDING_REGISTERS, 40001, 10)

aa= (1,2,3,4,5,6,7,8,9,10) # data in the register

while True:

    slave_1.set_values ("BlockName", 40001, aa)
    time.sleep(0.5)

标签: modbus-tk

解决方案


首先,我认为您没有任何理由在循环中不断更新“BlockName”上的值,但也许您有一个。

您的寄存器编号似乎也错误,您不需要将寄存器 0 定义为编号 40001,您可以替换以下行:

slave_1.add_block("BlockName", modbus_tk.defines.HOLDING_REGISTERS, 40001, 10)
slave_1.set_values ("BlockName", 40001, aa)

和:

slave_1.add_block("BlockName", cst.HOLDING_REGISTERS, 0, 10)
slave_1.set_values ("BlockName", 0, aa)

实例化数据块和从站的方式也存在一个小问题。

所以一个完整的从属示例应该如下所示:

import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
import serial
import time  

modbusServ = modbus_rtu.RtuServer(serial.Serial('/dev/ttyS0'),baudrate= 9600,
                 bytesize=8, parity='N', stopbits=1, xonxoff=0)
print("start")

modbusServ.start()

slave_1 = modbusServ.add_slave(1)

slave_1.add_block("BlockName", cst.HOLDING_REGISTERS, 0, 10)

aa= (1,2,3,4,5,6,7,8,9,10) # data in the register

#you need to get a new handler to write values to your slave
slave = modbusServ.get_slave(1)

slave.set_values ("BlockName", 0, aa)

while True:

    print("Modbus Server Waiting for client queries...")
    time.sleep(0.5)

有一个带有命令行参数的完整从属示例,并且全部包含在代码中:https ://github.com/ljean/modbus-tk/blob/master/examples/rtuslave_example.py

为了与寄存器编号保持一致,在您的客户端中,您也必须从寄存器 0 中读取:

master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 10)

导致:(1,2,3,4,5,6,7,8,9,10)

我想你已经知道了,但是还有一些其他好的库可以与 Modbus 一起使用,比如pymodbuspylibmodbus

编辑:测试后我必须更正我的完整示例以添加

slave = modbusServ.get_slave(1)

显然,您不能使用原件slave_1作为处理程序在您的药膏上写入值,而是必须调用函数modbusServ.get_slave(slave_id)


推荐阅读