Hi all,
I’ve been trying for the past few days to decode GPS latitude and longitude values for my application.
I’m using MicroPython on an Heltec Lora 32 V2 board, current sending:
cpu_temp_pack = struct.pack('h', int(cpu_temp))
bat_pack = struct.pack('h', int(bat))
lat_pack = struct.pack('f', float(lat))
lon_pack = struct.pack('f', float(lon))
payload = (bat_pack + cpu_temp_pack + lat_pack + lon_pack)
Here’s an (fake obviously) example of the bytes I’m sending:
00 00 2D 00 5F 06 31 43 7E 8D 12 C2
And the lat/long values from the above bytes should be:
Latitude: -36.638176
Longitude: 177.024887
My payload function is:
function Decoder(bytes, port) {
var decoded = {};
// Based on https://stackoverflow.com/a/37471538 by Ilya Bursov
function bytesToFloat(bytes) {
// JavaScript bitwise operators yield a 32 bits integer, not a float.
// Assume LSB (least significant byte first).
var bits = bytes[3]<<24 | bytes[2]<<16 | bytes[1]<<8 | bytes[0];
var sign = (bits>>>31 === 0) ? 1.0 : -1.0;
var e = bits>>>23 & 0xff;
var m = (e === 0) ? (bits & 0x7fffff)<<1 : (bits & 0x7fffff) | 0x800000;
var f = sign * m * Math.pow(2, e - 150);
return f;
}
if (port === 1)
{
decoded.bat = (bytes[1] << 8) | bytes[0];
decoded.cpu_temp = (bytes[3] << 8) | bytes[2] ;
decoded.lat = bytesToFloat(bytes.slice(4, 7));
decoded.lon = bytesToFloat(bytes.slice(8, 11));
}
return decoded;
}
Which returns:
{
“bat”: 0,
“cpu_temp”: 45,
“lat”: 2.162256779794837e-39,
“lon”: 1.5634889524811644e-39
}
I’m able to put either of the 4 bytes for lat or long into an online converter like the following:
And the correct value is identified as ‘Float - Little Endian (DCBA)’.
If I am to send my ‘cpu_temp’ as a float (using the same struct.pack(‘f’, blahblah)), the bytesToFloat function taken from stackoverflow.com works fine.
Any idea what I’m doing wrong here?