我试图通过raspberrypi 3中的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()
上面的代码工作正常。但我想从下面给出的信息中得到一些信息
例如我正在尝试这样的事情
result = client.read_input_registers(0x3200,unit=1)
但是当我调用result.registers
时,它显示的输出为0
但我想得到D0到D15的值。
我怎样才能做到这一点?感谢
答案 0 :(得分:1)
我认为您缺少要读取的寄存器数量的值。我想你想读两个寄存器。所以命令就是
result = client.read_input_registers(0x3200, 2, unit=1)
答案 1 :(得分:1)
文档中的 description 告诉您如何解释值的每一位
pymodbus ' s read_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
这个值可以用二进制值转换:
print format(value1, '016b') # 1000000100100011
print format(value2, '016b') # 0010010010001111
这些位中的每一位都可以从0到15(从右到左)编制索引,然后我们可以按照文档中的描述拆分它们:
value1 D3-D0:0011
值1 D7-D4:0010
Value1 D8:1
Value1 D15:1
对于每个位子集,文档为我们提供了一个十六进制值的数字,每个十六进制值的数字可以用二进制转换:
D3-D0:
00H(箱子:0000)正常
01H(箱:0001)过电压
02H(bin:0010)Undervolt
03H(箱:0011)低压断开
04H(箱:0100)OverTemp
和其他套装一样......
如果集合只包含一位,我们会考虑True(1)/False(0)
行为。
将这些值与我们的套件进行比较,我们了解33059表示:低电压断开,低温,电池内部电阻异常,错误识别额定电压(灾难!)或在您的情况下, 0表示额定电压的正常,正常,正常,正确识别。
如果我们将其应用于value2
(9359),我们将理解:
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---|---|
显然你不想手工完成这一切:即使有很多方法来编写这项工作,我建议你使用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
这段代码的优化应该是显而易见的 如您所见,无论如何,我们正在获得我们期望的输出。