将 16 位有符号 (x2) 转换为 32 位无符号
convert 16 bits signed (x2) to 32bits unsigned
我的 modbus 设备有问题:
设备以modbus协议发送数据。
我从 modbus 通信中读取了 4 个代表压力值的字节
我必须将这 4 个字节转换为无符号 32 位整数。
有 modbus 文档:
COMBINING 16bit REGISTERS TO 32bit VALUE
Pressure registers 2 & 3 in SENSOR INPUT REGISTER MAP of this guide are stored as u32 (UNSIGNED 32bit INTEGER)
You can calculate pressure manually :
1) Determine what display you have - if register values are positive skip to step 3.
2) Convert negative register 2 & 3 values from Signed to Unsigned (note: 65536 = 216 ):
(reg 2 value) + 65536* = 35464 ; (reg 3 value) + 65536 = 1
3) Shift register #3 as this is the upper 16 bits: 65536 * (converted reg 3 value) = 65536
4) Put two 16bit numbers together: (converted reg 2 value) + (converted reg 3 value) = 35464 + 65536 = 101000 Pa
Pressure information is then 101000 Pascal.
我不是很清楚...例如,我们没有给出这个计算的 4 个字节。
因此,如果有人有将我的字节转换为 32 位无符号整数的公式,那将非常有帮助
您应该能够以某种类型表示(十六进制、十进制、二进制、十进制...)读取字节
假设您收到以下字节帧:
十六进制:
0x00, 0x06, 0x68, 0xA0
在垃圾箱中:
0000 0000, 0000 0110, 0110 1000, 1010 0000
所有这些都是相同 4 字节值的不同表示。
您应该知道的另一件事是字节位置(字节顺序):
如果你的帧是在 big endian 中传输的,你将按照你拥有的顺序读取字节(所以 0x00, 0x06, 0x68, 0xA0
是正确的).
如果帧以little endian传输,则需要进行如下操作:
将前 2 个字节与后 2 个字节交换:
0x68, 0xA0, 0x00, 0x06
然后在第一和第二个字节和第三和第四个字节之间切换位置:
0xA0, 0x68, 0x06, 0x00
因此,如果您的帧是 little endian,则正确的帧将是 0xA0, 0x68, 0x06, 0x00
.
如果您不知道字节顺序,请假设它是 大端。
现在您只需要'put'您的价值观:
0x00, 0x06, 0x68, 0xA0 will become 0x000668A0
或
0000 0000, 0000 0110, 0110 1000, 1010 0000 will become 00000000000001100110100010100000
获得十六进制或二进制后,您可以convert your bin to an integer or convert your hex to an integer
Here你可以找到一个有趣的工具,将 HEX 转换为 float、unit32、int32、int16 的所有字节序。
TL;DR
如果你可以使用python,你应该使用struct:
import struct
frame = [0x00, 0x06, 0x68, 0xA0] # or [0, 6, 104, 160] in dec or [0b00000000, 0b00000110, 0b01101000, 0b10100000] in bin
print struct.unpack('>L', ''.join(map(chr, frame)))[0]
我的 modbus 设备有问题:
设备以modbus协议发送数据。
我从 modbus 通信中读取了 4 个代表压力值的字节
我必须将这 4 个字节转换为无符号 32 位整数。
有 modbus 文档:
COMBINING 16bit REGISTERS TO 32bit VALUE
Pressure registers 2 & 3 in SENSOR INPUT REGISTER MAP of this guide are stored as u32 (UNSIGNED 32bit INTEGER)
You can calculate pressure manually :
1) Determine what display you have - if register values are positive skip to step 3.
2) Convert negative register 2 & 3 values from Signed to Unsigned (note: 65536 = 216 ):
(reg 2 value) + 65536* = 35464 ; (reg 3 value) + 65536 = 1
3) Shift register #3 as this is the upper 16 bits: 65536 * (converted reg 3 value) = 65536
4) Put two 16bit numbers together: (converted reg 2 value) + (converted reg 3 value) = 35464 + 65536 = 101000 Pa
Pressure information is then 101000 Pascal.
我不是很清楚...例如,我们没有给出这个计算的 4 个字节。
因此,如果有人有将我的字节转换为 32 位无符号整数的公式,那将非常有帮助
您应该能够以某种类型表示(十六进制、十进制、二进制、十进制...)读取字节
假设您收到以下字节帧:
十六进制:
0x00, 0x06, 0x68, 0xA0
在垃圾箱中:
0000 0000, 0000 0110, 0110 1000, 1010 0000
所有这些都是相同 4 字节值的不同表示。
您应该知道的另一件事是字节位置(字节顺序):
如果你的帧是在 big endian 中传输的,你将按照你拥有的顺序读取字节(所以 0x00, 0x06, 0x68, 0xA0
是正确的).
如果帧以little endian传输,则需要进行如下操作:
将前 2 个字节与后 2 个字节交换:
0x68, 0xA0, 0x00, 0x06
然后在第一和第二个字节和第三和第四个字节之间切换位置:
0xA0, 0x68, 0x06, 0x00
因此,如果您的帧是 little endian,则正确的帧将是 0xA0, 0x68, 0x06, 0x00
.
如果您不知道字节顺序,请假设它是 大端。
现在您只需要'put'您的价值观:
0x00, 0x06, 0x68, 0xA0 will become 0x000668A0
或
0000 0000, 0000 0110, 0110 1000, 1010 0000 will become 00000000000001100110100010100000
获得十六进制或二进制后,您可以convert your bin to an integer or convert your hex to an integer
Here你可以找到一个有趣的工具,将 HEX 转换为 float、unit32、int32、int16 的所有字节序。
TL;DR
如果你可以使用python,你应该使用struct:
import struct
frame = [0x00, 0x06, 0x68, 0xA0] # or [0, 6, 104, 160] in dec or [0b00000000, 0b00000110, 0b01101000, 0b10100000] in bin
print struct.unpack('>L', ''.join(map(chr, frame)))[0]