我使用python库“minimalmodbus”与modbus设备进行通信:
import minimalmodbus
from minimalmodbus import Instrument
minimalmodbus.BAUDRATE = 9600
m = Instrument('com2', 1)
m.debug=True
print m.read_long(4156)
结果:
MinimalModbus debug mode. Writing to instrument (expecting 9 bytes back): '\x01\x03\x10<\x00\x02\x00\xc7'
MinimalModbus debug mode. No sleep required before write. Time since previous read: 1422431606124.0 ms, minimum silent period: 4.01 ms.
MinimalModbus debug mode. Response from instrument: '\x01\x03\x04\x00\x01\x00\x00\xab\xf3' (9 bytes), roundtrip time: 28.0 ms. Timeout setting: 50.0 ms.
65536
响应数据为65536,十六进制为0x00010000。但我已经确切知道数据应为1,0x00000001为十六进制。原因很明显:minimalmodbus解释响应数据'\ x00 \ x01 \ x00 \ x00'为0x00010000,而我的modbus设备应该为0x00000001。我已经参考了我看到的文档(http://minimalmodbus.sourceforge.net/#known-issues):
对于涉及多个寄存器(float,long等)的数据类型,不同制造商使用的字节顺序存在差异。浮点值1.0被编码(单精度)为3f800000(十六进制)。在此实现中,数据将作为'\ x3f \ x80'和'\ x00 \ x00'发送到两个连续的寄存器。确保测试它对您的仪器有意义。如果任何人需要其他字节顺序,那么更改此代码非常简单(参见支持部分)。
我想问:有没有人遇到同样的问题,发现一个简单快捷的方法(如作者所说)改变minimalmodbus的默认字节顺序?
修改 我找到了解决这个问题的方法,但我不知道它是否是最简单的:
def _performCommand(self, functioncode, payloadToSlave):
'''
reimplement the _performCommand function in subclass of minimalmodbus.Instrument
'''
payloadFromSlave = Instrument._performCommand(self, functioncode, payloadToSlave)
if functioncode in [3, 4]:
#reorder data in response while reading multiple registers
return payloadFromSlave[0] + self._restructure(payloadFromSlave)
else:
return payloadFromSlave
def _restructure(self, byteCode):
'''
reorder byte code for my device, e.g.:
'\x00\x01\x00\x02' --->'\x00\x02\x00\x01'
(byte order may differ for different manufacturers,refer to http://www.simplymodbus.ca/FAQ.htm#Order)
'''
newByteCode = ''
for i in range(len(byteCode)-2, -1, -2):
newByteCode += byteCode[i:i+2]
return newByteCode