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