RaspberryPi 3中的Pymodbus

2024-07-05 12:15:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图通过raspberrypi3中的pymodbus从modbus设备获取数据

from pymodbus.client.sync import ModbusSerialClient as ModbusClient

client = ModbusClient(method = 'rtu', port = '/dev/ttyUSB0', baudrate = 115200)
client.connect()

result = client.read_input_registers(0x3100,6,unit=1)
solarVoltage = float(result.registers[0] / 100.0)
solarCurrent = float(result.registers[1] / 100.0)
batteryVoltage = float(result.registers[4] / 100.0)
chargeCurrent = float(result.registers[5] / 100.0)

# Do something with the data

client.close()

上面的代码运行良好。我想从下面的信息中得到一些信息

enter image description here

我正在尝试这样的事情

^{pr2}$

但是当我调用result.registers时,它显示的输出是0 但是我想得到D0到D15的值。 我怎么能做到呢?谢谢


Tags: fromimportclient信息assyncresultfloat
2条回答

我想您缺少要读取的寄存器数的值。我想你想读两个寄存器。所以命令应该是

result = client.read_input_registers(0x3200, 2, unit=1)

文档中的说明告诉您如何解释值的每一位。
pymodbusread_input_registers()为每个寄存器返回一个units16(unsigned int 2字节)(请参见official documentation),这意味着它可以是0到65535之间的值。在

result = client.read_input_registers(0x3200, 2, unit=1)
value1 = result.registers[0] # 33059
value2 = result.registers[1] # 9359

此值可以转换为二进制值:

^{pr2}$

这些位中的每一位都可以从0到15(从右到左)进行索引,然后我们可以按照文档中的说明拆分它们:

value1 D3-D0: 0011
Value1 D7-D4: 0010
Value1 D8: 1
Value1 D15: 1

对于每一位的子集,文档为我们提供了一个十六进制值的数字,并且每个十六进制值的数字都可以转换成二进制:

D3-D0:
00H (bin: 0000) Normal
01H (bin: 0001) Overvolt
02H (bin: 0010) Undervolt
03H (bin: 0011) Low Volt Disconnect
04H (bin: 0100) OverTemp
and same for other sets...

如果集合只包含一个位,我们考虑True(1)/False(0)行为。在

将此值与我们的设置进行比较,我们了解到33059意味着:低压断开、低温、蓄电池内阻异常、额定电压识别错误(灾难!)或在您的情况下,0表示额定电压的正常、正常、正常、正确标识。在

如果我们对value2(9359)应用相同的方法,我们将理解:

^{3}$

显然,您不希望手工完成所有这些工作:即使有许多方法可以编写这项工作,我建议您使用bitmask

# Define each mask as a tuple with all the bit at 1 and distance from the right:
D3_D0_mask = (0b1111, 0)
D7_D4_mask = (0b1111, 4)
D8_mask = (0b1, 8)
D15_mask = (0b1, 15)
# compare each mask to the value, after shifting to the right position:
print D3_D0_mask[0]&(value1>>D3_D0_mask[1]) == 4 # False, Fault
print D3_D0_mask[0]&(value1>>D3_D0_mask[1]) == 3 # True, Low Volt Disconnect
print D3_D0_mask[0]&(value1>>D3_D0_mask[1]) == 2 # False, Under Volt
print D3_D0_mask[0]&(value1>>D3_D0_mask[1]) == 1 # False, Overvolt
print D3_D0_mask[0]&(value1>>D3_D0_mask[1]) == 0 # False, Normal

print D7_D4_mask[0]&(value1>>D7_D4_mask[1]) == 2 # True, Low Temp
print D7_D4_mask[0]&(value1>>D7_D4_mask[1]) == 1 # False, Over Temp
print D7_D4_mask[0]&(value1>>D7_D4_mask[1]) == 0 # False, Normal

print D8_mask[0]&(value1>>D8_mask[1]) == 1 # True, Battery internal resistance abnormal

print D15_mask[0]&(value1>>D15_mask[1]) == 1 # True, Wrong identification for rated voltage

此代码的优化应该很明显。
正如你所见,不管怎样,我们得到了我们期望的输出。在

相关问题 更多 >