Minimalmodbus,随机生成错误的crc

问题描述

我目前正在使用 RaspBerryPi 进行数据采集项目。当我启动我的请求脚本时,有时(很少但经常)我的从站(计算机)检测到 CRC 错误或无效长度。我猜这个错误可能来自这样一个事实,因为我的脚本速度很快并且在几秒钟内要求数百个注册,有时消息不完整,我的奴隶将其检测为错误消息。我想知道是否有可能 minimodbus 的时间不正确,有时会发送错误或部分请求(不完整)。

从站返回错误

invalid request: Invalid CRC in request

当奴隶不知道该回答什么时,这是我在主人身上遇到的典型错误

  error = SLAVE_ERRORS[str(e)]
KeyError: "Checksum error in rtu mode: '\\x8aÿ' instead of '\\x8fF' . The response is: '4ÿ\\x07$Ê\\x8aÿ' (plain response: '4ÿ\\x07$Ê\\x8aÿ')"**

我在从站上使用 modbus_tk 来模拟 modbus 从站。接下来通常是我的代码的一部分,从依赖于值的类型请求值。

    try:
        try:
            var_register = file_var[i]['varRegister']
            var_type = file_var[i]['varType']
            var_use = file_var[i]["varUse"]
            var_name = file_var[i]["varName"].strip()

            if '#' in var_register:
                continue
            elif var_type=='U16' or var_type=='I16' or var_type=='S16':

                value = inst.read_register(
                    int(var_register),3,not bool(file_var[i]['varSigned'])
                ) 

            elif var_type=='U32' or var_type=='I32' or var_type=='S32':

                value = inst.read_long(
                    int(var_register),not bool(file_var[i]['varSigned'])
                ) 

因为我的第一个猜测是时间问题,我随机插入了“time.sleep”来为我的请求计时,但错误仍然出现。而且它是完全随机的,有时它会在我的第一个 CRC 错误之前工作 5 分钟,有时仅几秒钟。你知道我应该去哪里调查吗?预先感谢您的帮助!

编辑:我的 PC 充当从站,具有模拟多个从站的 modbus_tk 脚本。 RPI 是请求寄存器及其值的主机。从设备都配置为在这些特定寄存器中具有值,以避免 IllegalAddress 错误。物理连接是 USB 到 RS485 转换器,RPI 配备了处理 RS485 输入/输出的 HAT。所以它实际上是一种 ModBus RTU 通信。当请求进来时,从设备循环并发送应答。

EDIT2:所以我进一步调查了一下,发现了一些有趣的东西。我收到一个错误(这次是在主站上),从站显然发送了错误的校验和......在查看它时,我发现 modbus_tk 生成的校验和很好,但主站收到的答案不一样。看起来有些字节在路上发生了变化,这很奇怪。那可能是从哪里来的?硬件问题?仅在轮询多个寄存器时才会出现此错误(一次超过 2 个)。如果要求的寄存器数量为 1 或 2,则所有其他请求都可以。

解决方法

听起来您的问题可能是模拟奴隶使用的 byte order

,

不,这并不奇怪,确实可能是噪音或其他硬件问题。

这正是 CRC 存在的原因,以确保您在主站上收到与从站发送的相同值。

你很可能有:

  1. 未将 GND 连接在一起
  2. 非常糟糕的电源
  3. 电线很乱
  4. 有大型电动机或任何其他来源或噪音的环境

我的赌注是 1:您认为 RS485 是两线制的(您只有 A 和 B 或 + 和 - 连接,对吗?)。

我不会在这里详细介绍,因为您应该能够找到数千甚至数百万的参考资料和帖子,这些参考资料和帖子从一开始就一直在进行。可以说,如果您的总线只有两条线时遇到问题,您可能会通过添加第三条将两个设备上的 GND 连接在一起来解决问题。当一台或两台设备依靠电池运行或具有隔离电源时,通常会出现这种情况。

如果您想了解更多信息,可以阅读this document。关于您的问题的一些特别有趣的段落:

在具有良好屏蔽和接地的优质电缆上运行 RS-422/485 几乎没有错误。然而,这不是人们使用 RS-422/485 的目的。任何电信号 运行超过 1000 米的电线(例如 3300+ 英尺的天线)会拾取噪声。差速器 RS-422/485 的双绞线特性有助于减少这种噪声的影响,但您必须假设 每天很少发生通信错误。这意味着运行较长的 RS-422/485 线路仅 适用于包含正确错误检测(CRC 或块校验和)的协议。

和:

不幸的是,RS-422/485 的接地是串行接口最容易被误解的方面之一。 通讯。许多人认为 RS-422/485 不需要接地。一个神话是 加号 (+) 和减号 (-) 信号就像一个电流回路并完成电路 通过他们自己。另一个误区是差分信号只是比较两个电压而没有 参考共同点。但最大的罪魁祸首是 RS-422/485 有线没有 正确接地似乎有效。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...