我正在尝试使用Python中的Little-endian字节交换将数据从本机Modbus寄存器(带符号)转换为32位浮点数,但我似乎无法正确进行转换。我尝试了几种不同的方法,但到目前为止都没有奏效,我不确定问题出在我的方法还是数据本身。
在我的参考中,初始数据类型是“本机 Modbus 寄存器 - 带符号”。我试图实现的转换是从这种类型到“32 位浮点 - Little-endian 字节交换”。以下是输入值和预期输出值的示例:
SlewEncoder_input_and_output = [
(2100, -1533, -601.2821),
(2100, -1533, -3395.887),
(1592, -1502, 19834.04),
(-305, 1807, -106.4646),
(-463, -1566, -1045.991)
]
我还有一个不同的参考,其中包含一些示例数据,这些数据似乎采用 32 位浮点数 - 小尾数字节交换格式(结果)。但是,我并不完全确定初始数据类型;它看起来与前一个(本机 Modbus 寄存器 - 带符号)类似,但合并为单个带符号寄存器值:
SlewEncoder_input_and_output = [
(1505910957, -0.963)
]
这是我尝试过的最后一件事(没有成功,输出只是一个非常巨大的值):
upper = 2100
lower = -1533
int_value = ((upper & 0xFFFF) << 16) | (lower & 0xFFFF)
# Convert the integer to bytes
bytes_value = int_value.to_bytes(4, byteorder='little', signed=True)
# Interpret the bytes as a float (little-endian)
import struct
reading_value = struct.unpack('<f', bytes_value)[0]
print(reading_value) # 147925204992.0
非常欢迎任何帮助,谢谢。
您的测试数据有误。我作弊并将 -601.2821 转换为两个 16 位值,发现您的数据缺少最低数字(21006 和 -15338)。然后我只是玩你的代码,直到它工作(我必须交换上限和下限),一旦你使用位而不是整数设置
signed=False
,这样Python就不用担心符号位。
这是工作代码:
lower = 21006
upper = -15338
int_value = ((upper & 0xFFFF) << 16) | (lower & 0xFFFF)
# Convert the integer to bytes
bytes_value = int_value.to_bytes(4, byteorder='little', signed=False)
# Interpret the bytes as a float (little-endian)
import struct
reading_value = struct.unpack('<f', bytes_value)[0]
print(reading_value) # -601.2821044921875