1

我希望使用 Minimal Modbus 通过 RS485-USB 适配器连接到我的太阳能逆变器 (GivEnergy)。不幸的是,Modbus 协议的实现反转了 CRC 字节,因此 Minimal Modbus 在 CRC 校验上失败。有没有办法在调用中反转 CRC 字节,可能带有选项标志,或者我可以手动构建 CRC 并注入我自己的?

4

1 回答 1

2

您不需要注入自己的 CRC,这实际上比解决您的问题更困难(当然,如果您愿意,您可以自由地这样做)。

只需在您的minimummodbus.py中更改此行

return _num_to_twobyte_string(register, lsb_first=True)

至:

return _num_to_twobyte_string(register, lsb_first=False)

您可以找到运行此命令的文件的位置:python -m site并查找site-packages文件夹。

在大多数带有 Python 3.x 的 Linux 发行版上,该文件夹是:

'/home/your_user_name/.local/lib/python3.x/site-packages'

如果您问为什么要弄乱代码,那么您并不孤单。当我自己在思考同样的问题时(在写完这个答案后,我发誓)我发现了这个问题

我想简短的回答是:您应该向设备的开发人员抱怨。

为了完整性:如果您不想编辑minimummodbus.py作为问题的答案建议您应该重载整个_calculate_crc_string(inputstring)函数,如我上面写的那样更改最后一行。

为了完整起见,我在上面的链接中添加了代码。要重载该函数,只需在导入 minimummodbus 后立即在 Python 脚本中再次编写其所有代码:

import minimalmodbus

def _calculate_crc_string(inputstring):
    """Calculate CRC-16 for Modbus.

    Args:
        inputstring (str): An arbitrary-length message (without the CRC).

    Returns:
        A two-byte CRC string, where the least significant byte is first.

    """
    minimalmodbus._check_string(inputstring, description="input CRC string")

    # Preload a 16-bit register with ones
    register = 0xFFFF

    for char in inputstring:
        register = (register >> 8) ^ minimalmodbus._CRC16TABLE[(register ^ ord(char)) & 0xFF]

    return minimalmodbus._num_to_twobyte_string(register, lsb_first=False)

minimalmodbus._calculate_crc_string = _calculate_crc_string

请注意函数外部的最后一行以重载_calculate_crc_string. 之后,您可以添加其余代码。

于 2021-05-04T14:18:29.153 回答