[英]Reading the longitude [28:0] from a 4 byte hexadecimal number
I am receiving a longitude and accuracy as a 4 byte hexadecimal string: 99054840
I'm trying to extract a longitude from this value.我收到一个 4 字节十六进制字符串的经度和准确度:
99054840
我正在尝试从该值中提取经度。
The specs tell me the following:规格告诉我以下内容:
Bits [28:0]: signed value λ, little-endian format, longitude in ° = λ ÷ 1,000,000位 [28:0]:有符号值 λ,little-endian 格式,以° 为单位的经度 = λ ÷ 1,000,000
Bits [31:29]: unsigned value α, range 0-7, a measure for accuracy位 [31:29]:无符号值 α,范围 0-7,精度度量
My device is located physically at a longitude of 4.7199.我的设备实际位于经度 4.7199。 So I now what the result of the conversion should be.
所以我现在转换的结果应该是什么。
To read the value of the longitude I currently do (with incorrect result):要读取我当前所做的经度值(结果不正确):
def get_longitude(reading):
# split in different bytes
n=2
all_bytes = [reading[i:i+n] for i in range(0, len(reading), n)]
# convert to binary
long_bytes_binary = list(map(hex_to_binary, all_bytes))
# drop the accuracy bits
long_bytes_binary[3] = long_bytes_binary[3][0:5]
# little endian & concatenate bytes
longitude_binary = ''.join(list(reversed(long_bytes_binary)))
# get longitude
lon = binary_to_decimal(int(longitude_binary))/1_000_000
Which comes to 138.93.达到 138.93。 So totally different from the 4.7199 (expected outcome)
与 4.7199 完全不同(预期结果)
Here are the helper methods以下是辅助方法
def hex_to_binary(payload):
scale = 16
num_of_bits = 8
binary_payload = bin(int(payload, scale))[2:].zfill(num_of_bits)
return binary_payload
def binary_to_decimal(binary):
binary1 = binary
decimal, i, n = 0, 0, 0
while(binary != 0):
dec = binary % 10
decimal = decimal + dec * pow(2, i)
binary = binary//10
i += 1
return decimal
What am I doing wrong?我究竟做错了什么? How can I correctly read the value?
如何正确读取值? Or is my device broken:)
还是我的设备坏了:)
The OP code dropped the last 3 bits instead of the first 3 bits for accuracy.为了准确,OP 代码丢弃了最后 3 位而不是前 3 位。 This change fixes it:
此更改修复了它:
# drop the accuracy bits
long_bytes_binary[3] = long_bytes_binary[3][3:]
But the calculation can be much more simple:但计算可以简单得多:
def hex_to_longitude(x):
b = bytes.fromhex(x) # convert hex string to bytes
i = int.from_bytes(b,'little') # treat bytes as little-endian integer
return (i & 0x1FFFFFFF) / 1e6 # 29-bitwise AND mask divided by one million
x = '99054840'
print(hex_to_longitude(x))
4.720025
I'm cheating a little bit here by using struct
to do the endian swap, but you get the idea.我在这里使用
struct
进行字节序交换有点作弊,但你明白了。
import struct
val = 0x99054840
val = struct.unpack('<I',struct.pack('>I',val))[0]
print(hex(val))
accuracy = (val >> 29) & 7
longitude = (val & 0x1ffffff) / 1000000
print(accuracy,longitude)
Output: Output:
C:\tmp>x.py
0x40480599
2 4.720025
C:\tmp> ```
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.