data_store.set_values(cst.COILS, 0, [1, 0, 1, 0])报错modbus_tk.exceptions.MissingKeyError: block 1 not found
时间: 2024-04-07 08:30:51 浏览: 86
根据错误提示,这个错误是由于在调用 `set_values` 函数时,指定的 `block` 不存在所导致的。可能的原因是 `block` 的编号不正确,或者在调用 `set_values` 之前,没有先调用 `add_block` 函数添加该 `block`。
解决这个问题,你需要检查一下调用 `set_values` 时传入的 `block` 编号是否正确,同时也需要确保在调用 `set_values` 之前,已经调用了 `add_block` 函数添加了该 `block`。如果问题仍然存在,可以提供更多的上下文信息,以便更好地理解问题所在。
相关问题
import serial,time import modbus_tk.defines as cst from modbus_tk import modbus_rtu # from modbus_tk.utils import create_master_string # 打开两个串口 com1 = serial.Serial(port='com2', baudrate=38400, bytesize=8, parity='N', stopbits=1) com2 = serial.Serial(port='com3', baudrate=38400, bytesize=8, parity='N', stopbits=1) # 创建Modbus RTU主机(master) master = modbus_rtu.RtuMaster(com1) master.set_timeout(1.0) master.set_verbose(True) time.sleep(2) # 读取保持寄存器数据 red = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 9) print(red) red1 = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 9)[0] # 这里可以修改需要读取的功能码 print(red1) new = int(red1 * 0.8) print(new) red = master.execute(1, function_code=cst.WRITE_MULTIPLE_REGISTERS, starting_address=0, output_value=[new]) # 读取输入寄存器数据 input_regs = master.execute(1, cst.READ_INPUT_REGISTERS, 0, 9) print(input_regs, 1) # 读取输入线圈数据 input_bits = master.execute(1, cst.READ_COILS, 0, 9) print(input_bits, 2) # 读取输出线圈数据 output_bits = master.execute(1, cst.READ_DISCRETE_INPUTS, 0, 9) print(output_bits, 3) # 将所有读取数据打包为Modbus RTU消息并写入com2串口 data = red + input_regs + input_bits + output_bits.最后两种可能,一个有crc校验,一个没有。两种可能咋发送给com2
根据您的代码,您已经成功使用modbus_tk库创建了Modbus RTU主机(master)并读取了保持寄存器、输入寄存器、输入线圈和输出线圈的数据。现在,您需要将这些数据打包为Modbus RTU消息,并将消息发送到另一个串口(com2)。
实际上,您已经将读取数据分别存储在了red、input_regs、input_bits和output_bits这四个变量中。现在,您可以使用struct库将这些数据打包为二进制格式,并将打包后的数据发送到com2串口。
以下是一个示例代码,用于将读取的Modbus RTU数据打包并发送到com2串口:
```python
import serial
import struct
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
# 打开com2和com3串口
com2 = serial.Serial(port='com2', baudrate=38400, bytesize=8, parity='N', stopbits=1)
com3 = serial.Serial(port='com3', baudrate=38400, bytesize=8, parity='N', stopbits=1)
# 创建Modbus RTU主机(master)
master = modbus_rtu.RtuMaster(com2)
master.set_timeout(1.0)
master.set_verbose(True)
time.sleep(2)
# 读取保持寄存器数据
red = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 9)
red1 = red[0]
new = int(red1 * 0.8)
# 设置保持寄存器数据
master.execute(1, cst.WRITE_SINGLE_REGISTER, 0, output_value=[new])
# 读取输入寄存器数据
input_regs = master.execute(1, cst.READ_INPUT_REGISTERS, 0, 9)
# 读取输入线圈数据
input_bits = master.execute(1, cst.READ_COILS, 0, 9)
# 读取输出线圈数据
output_bits = master.execute(1, cst.READ_DISCRETE_INPUTS, 0, 9)
# 打包所有数据
data = struct.pack('>HH' + 'H'*len(red) + 'H'*len(input_regs) + 'B'*len(input_bits) + 'B'*len(output_bits),
1, cst.READ_HOLDING_REGISTERS, *red, *input_regs, *input_bits, *output_bits)
# 将数据发送到com3串口
com3.write(data)
```
以上代码中,我们首先使用Modbus RTU主机(master)读取保持寄存器、输入寄存器、输入线圈和输出线圈的数据,并将保持寄存器的值修改为原来的80%。然后,我们使用struct库将这些数据打包为二进制格式,最后将打包后的数据发送到com3串口。
请注意,不同的Modbus RTU设备可能对数据格式有不同的要求,因此您需要根据具体的设备规范进行调整和优化。另外,发送的数据可能需要进行CRC校验,具体方式也需要根据设备规范进行调整。
import serial,time,struct import modbus_tk.defines as cst from modbus_tk import modbus_rtu # from modbus_tk.utils import create_master_string def main(): # 打开两个串口 com1 = serial.Serial(port='com2', baudrate=38400, bytesize=8, parity='N', stopbits=1) com2 = serial.Serial(port='com3', baudrate=38400, bytesize=8, parity='N', stopbits=1) # 创建Modbus RTU主机(master) master = modbus_rtu.RtuMaster(com1) master.set_timeout(1.0) master.set_verbose(True) # time.sleep(2) # 读取保持寄存器数据 red = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 9) print(red) red1 = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 9)[0] # 这里可以修改需要读取的功能码 print(red1) new = int(red1 * 0.98) print(new) master.execute(1, function_code=cst.WRITE_MULTIPLE_REGISTERS, starting_address=0, output_value=[new]) time.sleep(0.5) red = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 9) print(red,0) # 读取输入寄存器数据 input_regs = master.execute(1, cst.READ_INPUT_REGISTERS, 0, 9) print(input_regs, 1) # 读取输入线圈数据 input_bits = master.execute(1, cst.READ_COILS, 0, 9) print(input_bits, 2) # 读取输出线圈数据 output_bits = master.execute(1, cst.READ_DISCRETE_INPUTS, 0, 9) print(output_bits, 3)。现在将所有读取数据打包为Modbus RTU消息并写入com2串口。要求打包的Modbus RTU消息格式要跟 master = modbus_rtu.RtuMaster(com1)一样
可以使用modbus_tk.modbus_rtu.master._compute_crc函数计算Modbus RTU消息的校验码,并使用struct.pack()函数将消息打包为字节流。以下是代码示例:
```python
import serial
import time
import struct
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
def pack_modbus_rtu_msg(address, function_code, starting_address, quantity_of_x, output_value=None):
# 构造Modbus RTU消息
if output_value is not None:
data_len = 2 + 2*len(output_value)
else:
data_len = 2
msg = struct.pack(">BBHH", address, function_code, starting_address, quantity_of_x)
if output_value is not None:
for val in output_value:
msg += struct.pack(">H", val)
# 计算校验码(CRC)
crc = modbus_rtu.master._compute_crc(msg)
msg += struct.pack(">H", crc)
return msg
def main():
# 打开两个串口
com1 = serial.Serial(port='com2', baudrate=38400, bytesize=8, parity='N', stopbits=1)
com2 = serial.Serial(port='com3', baudrate=38400, bytesize=8, parity='N', stopbits=1)
# 创建Modbus RTU主机(master)
master = modbus_rtu.RtuMaster(com1)
master.set_timeout(1.0)
master.set_verbose(True)
# 读取保持寄存器数据
red1 = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 9)[0]
new = int(red1 * 0.98)
master.execute(1, function_code=cst.WRITE_MULTIPLE_REGISTERS, starting_address=0, output_value=[new])
# 打包Modbus RTU消息并写入com2串口
msg = pack_modbus_rtu_msg(1, cst.READ_HOLDING_REGISTERS, 0, 9)
com2.write(msg)
# 读取输入寄存器数据
input_regs = master.execute(1, cst.READ_INPUT_REGISTERS, 0, 9)
print(input_regs, 1)
# 读取输入线圈数据
input_bits = master.execute(1, cst.READ_COILS, 0, 9)
print(input_bits, 2)
# 读取输出线圈数据
output_bits = master.execute(1, cst.READ_DISCRETE_INPUTS, 0, 9)
print(output_bits, 3)
```
阅读全文