我有一个太阳能项目和实时监控器,它使用EpSolar Tracer充电控制器和Raspberry Pi通过MODBUS读取能源数据。
当它们是简单的整数时,我很容易读取输入寄存器,如下所示 -
# Request the range of registers that hold the solar/battery realtime data (3100 - 3105)
result = client.read_input_registers(0x3100,6,unit=1)
# Solar voltage is register 3100, divide by 100
sV = float(result.registers[0] / 100.0)
..但我无法理解如何读取输入寄存器,其中每个位代表不同的东西。特别是,我想读一个“充电状态”寄存器,它包含12条不同的信息 -
当我读到这个寄存器(0x3201)时,我得到的全部是数字7.如何读取该寄存器中的12个不同数据?我想也许7是0000000000000111的十进制表示 - 但我认为这不对。
对此有任何帮助将不胜感激!
马特
答案 0 :(得分:0)
你走在正确的轨道上。这些比特很容易搞清楚。方法如下:
16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
1 1 1
顶行是位位置,底线是值7 ...让我们说你对第2位感兴趣,第3位是右边。让我们通过1
并将其移位n
次来为该位做一个掩码,其中n
是位的位置。所以我们想把它换两次:
int mask =(1<<< 2);
这将产生:
16 15 14 13 12 11 10 09 09 07 06 05 04 03 02 01 00
1 0 0
现在我们所做的就是确定第二位是否设置为AND
值和掩码
16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
1 1 1 value
1 0 0 mask
--------------------------------------------------
1 0 0 ANDed result
所以,在C:
int value = 7; // or any 16-bit value
int mask = (1 << 2); // == 4
if ((value & (1 << 2)) == mask)
// bit is set
else
// bit is not set
现在,有时您想要提取多个位。这是一个如何提取两位组合的示例。首先,让我们规定两个位11
是值3(一个1
和一个2
)。所以现在要做一个类似的过程从同一个值中提取两个比特(7)。
16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1
现在我们使用3
代替1
:
int mask =(3&lt;&lt; 2);
这将产生:
16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
现在我们所做的就是确定第二位是否设置为AND
值和掩码
16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 value
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 mask
--------------------------------------------------
0 1 0 0 ANDed result
但文档可能会说比特:3-2是“状态x”。价值观 -
00 - a
01 - b
02 - c
03 - d
所以现在我们必须从上面的AND
ed结果中获取最终值0100,并将它向右移动两个以获得这些可能的值:
result = (old_result >> 2);
0100 >> 2 == 01
由于结果为01,十进制1,十六进制1,因此结果为b
。
编辑:
现在是python中的最终计算:
>>> value = 0x0007
>>> mask = (3 << 2)
>>> result = value & mask
>>> print (result)
4
>>> shifted_result = result >> 2
>>> print (shifted_result)
1
相同的结果,位3-2等于1,这意味着(根据您的数据表)诊断结果是:
第0位:“正在运行” 第1位:“错误” 第3-2位:“浮动”