将两个原始值转换为 32 位 IEEE 浮点数

Convert two raw values to 32-bit IEEE floating point number

我正在尝试通过 TCP modbus 解码来自 Shark 100 功率计的一些数据。我已经成功地取下了我需要的寄存器,并从寄存器中留下了两个原始值,如下所示:

[17138, 59381]

根据手册,我知道我需要将这两个数字转换成一个32位的IEEE浮点数。我还从手册中知道“低地址寄存器是 高阶一半(即包含指数)。”上面显示的列表中的第一个数字是地址较低的寄存器。

使用 Python(如果需要,任何库都可以),我将如何获取这两个值并将它们变成 32 位 IEEE 浮点值。

我曾尝试使用各种在线转换器和计算器来找出一种非编程的方法来执行此操作,但是,我尝试过的任何方法都得到了超出范围的结果(我正在阅读伏特情况下,最终结果应该是上面提供的值的 120-122 左右)。

以下代码有效:

import struct
a=17138
b=59381
struct.unpack('!f', bytes.fromhex('{0:02x}'.format(a) + '{0:02x}'.format(b)))

给出

(121.45304107666016,)

改编自Convert hex to float and

更新 Python 3.6+ (f-strings)。

不知道为什么@B.Go的回答只有2。另外,由于字节顺序是 big-endian,我将其硬编码为这样。

import struct
a = 17138
b = 59381
struct.unpack('>f', bytes.fromhex(f"{a:0>4x}" + f"{b:0>4x}"))[0]

输出:121.45304107666016

我看了评论,@Sanju 发布了这个link:https://github.com/riptideio/pymodbus/blob/master/examples/common/modbus_payload.py

对于任何使用 pymodbus 的人来说,BinaryPayloadDecoder 非常有用,因为它是内置的。传递 result.registers 非常容易,如示例所示。此外,它还集成了 logging,因此您可以帮助调试转换不起作用的原因(例如:错误的字节顺序)。

因此,我为这个问题做了一个工作示例(使用 pymodbus==2.3.0):

from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder


a = 17138
b = 59381
registers = [a, b]
decoder = BinaryPayloadDecoder.fromRegisters(registers, byteorder=Endian.Big)
decoder.decode_32bit_float()  # type: float

输出:121.45304107666016