2

我有一个太阳能项目和实时监视器,它使用 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 的十进制表示 - 但我不认为这是正确的。

对此的任何帮助将不胜感激!

马特

4

1 回答 1

1

你在正确的轨道上。而且很容易把这些碎片弄出来。就是这样:

16 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
                                           1  1  1

顶行是位位置,底行是值 7...假设您对位 2 感兴趣,从右边数第三个。让我们为那个位做一个位掩码,取 a1并随着n时间的推移移动它,n位的位置在哪里。所以我们要移动它2次:

整数掩码 = (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现在我们用 a而不是a 来屏蔽1

整数掩码 = (3 << 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

但是文档可能会说 bits: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:“浮动”

于 2017-06-25T12:11:20.097 回答