我正在使用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)
答案 0 :(得分:0)
首先,我认为您没有任何理由继续更新您的值 循环中出现“ 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的优秀库,例如 pymodbus 和 pylibmodbus 。
编辑:测试后,我不得不更正完整的示例以添加
slave = modbusServ.get_slave(1)
显然,您不能使用原始的slave_1
作为处理程序来在从膏上写入值,而必须调用函数modbusServ.get_slave(slave_id)