如何用Python的minimalmodbus库发送指定结构的带CRC的Modbus消息?
解决minimalmodbus发送自定义Modbus RTU报文的问题
你现在的问题出在错误使用了minimalmodbus的API——这个库本身就是用来封装Modbus协议细节的,不需要你手动组装包含地址、功能码、CRC的完整报文。你手动拼的data数组会被库重复处理,导致发送的报文不符合设备要求。
正确做法:用库封装好的功能函数
你的需求是用功能码04(读输入寄存器)、起始寄存器0、数量1、从站地址1,直接调用库的read_input_registers方法即可,库会自动处理报文组装、CRC计算和响应解析:
import minimalmodbus import serial # 初始化仪器,第二个参数是从站地址 instrument = minimalmodbus.Instrument('COM1', 1) # 配置串口参数 instrument.serial.baudrate = 19200 instrument.serial.parity = serial.PARITY_EVEN instrument.serial.bytesize = 8 instrument.serial.stopbits = 1 instrument.mode = minimalmodbus.MODE_RTU instrument.serial.timeout = 1 try: # 读输入寄存器:起始寄存器0,数量1,功能码默认04(可省略functioncode参数) data = instrument.read_input_registers(address=0, numberOfRegisters=1, functioncode=4) print("读取到的数据:", data) except Exception as e: print("通信错误:", e) finally: instrument.close()
如果确实需要发送原始自定义报文
如果设备有特殊要求必须手动拼接完整报文,不要用minimalmodbus的封装方法,直接用底层serial对象发送:
import serial ser = serial.Serial( port='COM1', baudrate=19200, parity=serial.PARITY_EVEN, bytesize=8, stopbits=1, timeout=1 ) # 手动组装的报文转成字节格式 raw_data = bytes([1, 4, 0, 0, 0, 1, 49, 202]) ser.write(raw_data) # 根据设备响应长度调整读取字节数 response = ser.read(8) print("原始响应:", response) ser.close()
原代码的错误点
instrument.write(data):该方法不是用来发送完整Modbus帧的,它的参数是寄存器地址和数据,库会自动封装成符合协议的报文,手动传完整帧会导致重复处理。instrument.readline():minimalmodbus不推荐用这个方法读取响应,应该用对应功能的读取函数,库会自动解析响应内容。- 手动添加的CRC会被库再次计算并追加,导致报文长度错误,设备无法识别。
内容的提问来源于stack exchange,提问作者Isaac Zaiek
相关产品推荐
相关产品推荐

