Python 最小 Modbus CRC 字节顺序

Python Minimal Modbus CRC byte order

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

你不需要注入你自己的CRC,那会比实际解决你的问题更困难(如果你想的话,你可以自由地做当然)。

只需在 minimalmodbus.py 中更改 this line:

return _num_to_twobyte_string(register, lsb_first=True)

至:

return _num_to_twobyte_string(register, lsb_first=False)

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

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

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

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

我想简短的回答是:你应该向你的设备的开发者投诉。

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

为了完整起见,我在上面的 link 上添加了代码。要重载该函数,只需在导入 minimalmodbus:

后立即在 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。之后,您可以添加其余代码。