我试图通过raspberrypi 3中的pymodbus从modbus设备获取数据
从pymodbus.client.sync导入ModbusSerialClient作为ModbusClient
client = ModbusClient(method =‘rtu’,port =’/ dev / …
该 描述 在文档中告诉您如何解释您的值的每个位。 pymodbus 的 read_input_registers() 返回一个 units16 每个寄存器的(unsigned int 2个字节)(参见 官方文件 ),这意味着它可以是0到65535之间的值。
read_input_registers()
result = client.read_input_registers(0x3200, 2, unit=1) value1 = result.registers[0] # 33059 value2 = result.registers[1] # 9359
此值可以使用二进制值进行转换:
print format(value1, '016b') # 1000000100100011 print format(value2, '016b') # 0010010010001111
这些位中的每一位都可以从0到15(从右到左)编制索引,然后我们可以按照文档中的描述拆分它们:
value1 D3-D0:0011 值1 D7-D4:0010 Value1 D8:1 值1 D15:1
对于位的每个子集,文档为我们提供了十六进制值的数字,并且十六进制值中的每个数字都可以以二进制形式转换:
D3-D0: 00H(箱子:0000)正常 01H(箱:0001)过压 02H(bin:0010)Undervolt 03H(箱:0011)低压断开 04H(bin:0100)OverTemp 和其他套装一样......
如果该集仅包含一位,我们考虑 True(1)/False(0) 行为。
True(1)/False(0)
将这些值与我们的设备进行比较,我们了解33059意味着:低电压断开,低温,电池内部电阻异常,额定电压的错误识别( 灾难! )或在您的情况下,0表示额定电压的正常,正常,正常,正确识别。
如果我们应用相同的 value2 (9359),我们将理解:
value2
1 D0----|---Standby 1 D1----|---Fault 1 D2----|---|---Equalization 1 D3----|---| 0 D4----|---ok 0 D5----|---// 0 D6----|---// 1 D7----|---The load is short 0 D8----|---ok 0 D9----|---ok 1 D10---|---Input is over current 0 D11---|---ok 0 D12---|---ok 1 D13---|---Charging MOSFET is short 0 D14---|---|---Normal 0 D15---|---|
显然你不想手工完成这一切:即使有很多方法来编写这项工作,我建议你使用一个 位掩码 :
# 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
这段代码的优化应该是显而易见的。 如您所见,无论如何,我们正在获得我们预期的输出。
我想你错过了要读取的寄存器数量的值。我想你想读两个寄存器。所以命令就是
result = client.read_input_registers(0x3200, 2, unit=1)