pymodbus read_coils 返回丢失的 1 字节 CRC

问题描述 投票:0回答:1

我正在尝试通过 pymodbus 控制 EX-PS 5080 电源。我正在尝试读取远程状态。 Modbus 地址 = 402;功能码 = 01 读取线圈;数据类型 = uint(16);数据长度(以字节为单位)= 2;寄存器数量 = 1

这是一个简化的代码:

from pymodbus.client import ModbusSerialClient
import pymodbus
import logging
from pymodbus.constants import Endian

logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG)

COM = ModbusSerialClient(method='rtu',port='com4',baudrate=9600, timeout= 5, parity= 'N', stopbits=1, bytesize=8)
COM.connect()
output =  COM.read_coils(address = 402, bit = 2000, count = 1, slave =0)
COM.close()

调试输出是

DEBUG:pymodbus.logging:Current transaction state - IDLE
DEBUG:pymodbus.logging:Running transaction 1
DEBUG:pymodbus.logging:SEND: 0x0 0x1 0x1 0x92 0x0 0x1 0x5c 0xa
DEBUG:pymodbus.logging:Resetting frame - Current Frame in buffer - 
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG:pymodbus.logging:RECV: 0x0 0x1 0x2 0x0 0x0 0x84
DEBUG:pymodbus.logging:Processing: 0x0 0x1 0x2 0x0 0x0 0x84
DEBUG:pymodbus.logging:Frame - not ready
DEBUG:pymodbus.logging:Getting transaction 0
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"

输出中没有任何返回。 我注意到“RECV:0x0 0x1 0x2 0x0 0x0 0x84”的长度不正确。 CRC 中似乎缺少一个字节。

EA PS5000还有一个官方软件,可以检查原始代码。这里我发送了

[TX] 0x0 0x1 0x1 0x92 0x0 0x1 0x5c 0xa
我有
[RX] 0x0 0x1 0x2 0x0 0x0 0x84 0x3c

enter image description here

我尝试在 pymodbus 中检查 CRC:


from pymodbus.utilities import computeCRC, checkCRC
crc = computeCRC(b'\x00\x01\x01\x92\x00\x01\x5c\x0a')
print(hex(crc))

返回的是 0x0,我期望的是 0x84 0x3c

为什么 CRC 计算会给出意想不到的结果?

python crc16 pymodbus
1个回答
0
投票

从屏幕截图和代码记录的差异来看,您似乎没有收到最终字节(3C),导致 pymodbus 无法解码消息。

也许串行总线的参数不正确(奇偶校验、停止位)?

在您的 CRC 计算中,您似乎误解了 CRC 的计算和添加位置: CRC 是根据您发送的消息计算的,并附加为最后 2 个字节:

>>> crc = computeCRC(b'\x00\x01\x01\x92\x00\x01')
>>> print(hex(crc))
0x5c0a

因此总消息变为:

0x0 0x1 0x1 0x92 0x0 0x1 0x5c 0xa

由于一些时髦的数学计算,(再次)附加 CRC 的消息的 CRC 将始终为 0。

收到消息的 CRC 确实是 0x84 0x3C,计算公式为:

>>> crc = computeCRC(b'\x00\x01\x02\x00\x00')
>>> print (hex(crc))
0x843c
© www.soinside.com 2019 - 2024. All rights reserved.