请帮我看一下 ModBus RTU 写的是不是有错误

img


我读取净重 01 04 00 00 00 01 CRC 但是串口助手给我反馈数据格式不对 ,为什么仪表给我反馈的数据一直是FF啊

  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7779175
  • 这篇博客你也可以参考下:Modbus-RTU查表法的CRC校验
  • 除此之外, 这篇博客: Modbus 协议基本原理中的 5.1.2、RTU模式的CRC校验 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 在 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协议讲解及实现课程中的 Modbus RTU帧格式小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    根据给出的参考资料,无法得出具体的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。

首先,请确保以下几点:

  1. 确认您使用的串口助手与Modbus RTU协议兼容,并正确设置了通信参数(如波特率、数据位、停止位等)。
  2. 确认您所使用的设备地址(01)是正确的,与仪表的Modbus地址一致。
  3. 确认CRC校验计算是否正确。

如果确认以上几点没有问题,接下来可以尝试一些排查步骤:

  1. 检查通信线路是否正常连接,包括串口线缆、仪表的通信接口等。
  2. 尝试使用其他Modbus RTU设备或软件进行通信测试,验证是否仅限于此仪表的问题。
  3. 联系仪表设备制造商寻求技术支持,咨询是否存在设备配置或特殊处理要求。

关于代码方面,这里提供一个基于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")

请根据实际情况修改串口参数(如串口号、波特率等)以及设备地址,并确保安装了pyserialmodbus-tk库。

希望以上信息对您有帮助!如果问题仍然存在,请提供更多详细信息,以便更准确地定位问题所在。
如果我的回答解决了您的问题,请采纳!