首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >RaspberryPi 3中的Pymodbus

RaspberryPi 3中的Pymodbus
EN

Stack Overflow用户
提问于 2017-10-27 13:20:17
回答 2查看 2.4K关注 0票数 1

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

代码语言:javascript
运行
复制
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()

上面的代码运行良好。但是我想从下面给出的信息中得到这些信息

我正在尝试像这样的东西

代码语言:javascript
运行
复制
result = client.read_input_registers(0x3200,unit=1)

但是,当我调用result.registers时,输出显示为0,但我希望将D0的值转换为D15。我怎么能这么做?谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-23 10:19:25

文档中的描述告诉您如何解释每一个值。

pymodbus的read_input_registers()为每个寄存器返回一个units16 (无符号int 2字节)(参见正式文件),这意味着它可以是0到65535之间的值。

代码语言:javascript
运行
复制
result = client.read_input_registers(0x3200, 2, unit=1)
value1 = result.registers[0] # 33059
value2 = result.registers[1] # 9359

这个值可以转换为二进制值:

代码语言:javascript
运行
复制
print format(value1, '016b') # 1000000100100011
print format(value2, '016b') # 0010010010001111

这些比特中的每一个都可以从0索引到15 (从右到左),然后我们可以将它们拆分,如文档中所述:

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

对于位的每个子集,文档为我们提供了一个十六进制值的数字,十六进制值中的每个数字可以用二进制格式转换:

D3-D0: 00H (垃圾桶: 0000)正常 01H (垃圾桶: 0001)过伏 02H (箱号: 0010) 03H (箱: 0011)低压断开 04 H (bin: 0100) OverTemp 其他组也一样..。

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

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

如果我们对value2(9359)应用同样的方法,我们将了解到:

代码语言:javascript
运行
复制
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---|---|

显然,您不想手工完成所有这些工作:即使有许多方法来编写这项工作的程序,我建议您使用位掩码

代码语言:javascript
运行
复制
# 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

对此代码的优化应该是显而易见的。

正如你所看到的,无论如何,我们得到了我们期望的输出。

票数 2
EN

Stack Overflow用户

发布于 2017-10-27 21:42:46

我认为您缺少要读取的寄存器数量的值。我猜你想读两个寄存器。所以命令是

代码语言:javascript
运行
复制
result = client.read_input_registers(0x3200, 2, unit=1)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46976051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档