在 RTU 模式包含一个对全部报文内容执行的,基于循环冗余校验 (CRC - Cyclical Redundancy Checking) 算法的错误检验域。CRC 域检验整个报文的内容。不管报文有无奇偶校验,均执行此检验。
CRC 包含由两个 8 位字节组成的一个 16 位值。
CRC 域作为报文的最后的域附加在报文之后。计算后,首先附加低字节,然后是高字节。CRC 高字
节为报文发送的最后一个子节。
附加在报文后面的 CRC 的值由发送设备计算。接收设备在接收报文时重新计算 CRC 的值,并将计
算结果于实际接收到的 CRC 值相比较。如果两个值不相等,则为错误。
CRC 的计算, 开始对一个 16 位寄存器预装全 1。 然后将报文中的连续的 8 位子节对其进行后续的计
算。只有字符中的 8 个数据位参与生成 CRC 的运算,起始位,停止位和校验位不参与 CRC 计算。
CRC 的生成过程中, 每个 8–位字符与寄存器中的值异或。然后结果向最低有效位(LSB)方向移动
(Shift) 1 位,而最高有效位(MSB)位置充零。 然后提取并检查 LSB:如果 LSB 为 1, 则寄存器中的值与一个固定的预置值异或;如果 LSB 为 0, 则不进行异或操作。
这个过程将重复直到执行完 8 次移位。完成最后一次(第 8 次)移位及相关操作后,下一个 8 位字节与寄存器的当前值异或,然后又同上面描述过的一样重复 8 次。当所有报文中子节都运算之后得到的寄存器的最终值,就是 CRC。
根据给出的参考资料,无法得出具体的ModBus RTU代码是否正确的判断。ModBus RTU是一种通信协议,其中包含设备地址、功能代码、数据和CRC校验等部分。要确认代码是否正确,需要确保各个部分的格式和内容的正确性。
根据参考资料的段落7,我们可以看到一条典型的RTU数据帧的格式。首先,起始位和结束位用于分割不同的数据帧。然后是设备地址,用于确保通信的目标设备。再接下来是功能代码,用于指示需要执行的操作。最后是数据和CRC校验。
对于给出的ModBus RTU串口通信码"01 04 00 00 00 01 CRC",我们可以根据参考资料中的说明对其进行验证。
首先,第一个字节"01"是设备地址,用于指示通信的目标设备。根据参考资料的段落4中的说明,你需要在ModBus配置中设置正确的设备地址。检查你的配置中设备地址是否正确。
接下来,第二个字节"04"是功能代码,用于指示需要执行的操作。根据参考资料的段落7中的说明,你需要根据你的实际需求选择正确的功能代码。检查你的功能代码是否正确。
然后,接下来的"00 00"是数据部分,根据参考资料的段落7中的说明,根据你的实际需求填入正确的数据。
最后,最后两个字节"CRC"是CRC校验码,用于验证数据的正确性。根据参考资料的段落2中的CRC计算过程,你可以对整个数据帧进行CRC计算,然后检查计算结果和你的CRC校验码是否一致。
通过以上的验证步骤,你可以判断你的ModBus RTU串口通信码是否正确。如果在验证过程中发现任何错误或不确定之处,你可以参考更详细的ModBus RTU资料或咨询专业人士来解决问题。
逐步分析,首先是01,读取线圈,然后04,选择输入存储器,00 00 起始地址,00 01为线圈数量,
看样子应该是没有问题,要不你检查一下你的CRC
试试 01 04 00 00 00 02 CRC
不对呀返回的是DE 00
图文详解Modbus-RTU协议
可以参考下
https://blog.csdn.net/weixin_38275735/article/details/124945855
可能是因为净重数据的格式与串口助手的期望格式不匹配,导致无法正确解析数据。另外,如果仪表返回的数据一直是FF,可能是由于以仪表的串口通信设置与串口助手的设置不匹配,例如波特率、数据位、停止位等。请确保两者设置一致。
仪表的CRC校验设置可能不正确,导致数据传输出现问题。请检查仪表的CRC校验设置,确保与串口助手的期望设置一致。
可能是两边格式参数不匹配
以下答案参考newbing,回答由博主波罗歌编写:
根据您提供的信息,您正在使用Modbus RTU协议进行通信,并且尝试读取净重数据。根据您描述的序列,读取净重的Modbus RTU命令应为 01 04 00 00 00 01 CRC。然而,您说串口助手给您反馈的数据格式不正确,一直是FF。
首先,请确保以下几点:
如果确认以上几点没有问题,接下来可以尝试一些排查步骤:
关于代码方面,这里提供一个基于Python的Modbus RTU读取净重数据的示例代码,供您参考:
import serial
import struct
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
def read_weight(device_address):
# 创建串口连接
serial_port = serial.Serial(
port='/dev/ttyUSB0', # 根据实际情况修改串口号
baudrate=9600,
bytesize=8,
parity='E',
stopbits=1
)
# 创建Modbus RTU主站
master = modbus_rtu.RtuMaster(serial_port)
master.set_timeout(1.0)
try:
# 读取净重数据
response = master.execute(device_address, cst.READ_INPUT_REGISTERS, 0x0000, 1)
# 解析数据
weight = struct.unpack('!f', struct.pack('!HH', response[1], response[0]))[0]
return weight
except modbus_tk.modbus.ModbusError as e:
print(f"Modbus error: {e}")
finally:
serial_port.close()
# 指定仪表的Modbus地址
device_address = 0x01
# 读取净重数据
weight = read_weight(device_address)
print(f"Weight: {weight} kg")
请根据实际情况修改串口参数(如串口号、波特率等)以及设备地址,并确保安装了pyserial
和modbus-tk
库。
希望以上信息对您有帮助!如果问题仍然存在,请提供更多详细信息,以便更准确地定位问题所在。
如果我的回答解决了您的问题,请采纳!