Bytearray() and structures for floating point values
-
I am getting to grips with my FiPy and PySense. Just started sending LoRa packages and used the following code to send the battery voltage.
vt = py.read_battery_voltage() print("Battery voltage: " + str(py.read_battery_voltage())) data = bytearray(2) data = bytearray(struct.pack("f", vt)) s.send(data) # send buffer to TTNThe voltage was 4.420753 and the byte array I received was 61 d2 8c 40
I used javascript to decode this at the other end using a standard library function but it says the value is 8.1085 e -315If I use https://gregstoll.dyndns.org/~gregstoll/floattohex/ as a resource to convert from float to hex is comes out as 40 8d 76 cf so the reverse of my number. If i swap endianness it converts 40 8d 76 cf as 4.42075 so that seems to be the problem.
What is the JavaScript I should use to unpack my payload to read the correct value?
thanks
-
-
@smbunn given that you transmitted 4 bytes, you could as well send a 4 byte ascii string, tellung the value in millivolt and still being precise enough for the purpose.
-
@robert-hh
True but this is a general question and some of my values will be over vastly different ranges. So it is really a question on float to 4 byte array back to float. I am working on the unpacking now guided by https://stackoverflow.com/questions/29879009/how-to-convert-python-struct-unpack-to-java and will let everyone know how I get on.
From my limited understanding it seems that Python has a great pack and unpack function but JavaScript doesn't so you have to write your own. -
False path. The hyperlinked example is in Java. Almost none of the structures used exist in JavaScript which does not support ByteBuffer as a type. So after an hour I have realized I am wasting my time trying to patch something together.
Anyone else got any ideas? It seems like it should be easy :-)
-
@smbunn
look then maybe here
https://github.com/ronniebasak/JStruct
possibly here if above not work
http://www.jython.org/javadoc/org/python/modules/struct.html -
I found an answer. The function in Python by default packs the four bytes in little endian format. JavaScript expects big endian. By merely changing
data = bytearray(struct.pack("f", vt))to
data = bytearray(struct.pack(">f", vt))the unpack at the other end was simple.
Java Script
function decodeFloat(data1) { var binary = parseInt(data1, 16).toString(2); if (binary.length < 32) binary = ('00000000000000000000000000000000'+binary).substr(binary.length); var sign = (binary.charAt(0) == '1')?-1:1; var exponent = parseInt(binary.substr(1, 8), 2) - 127; var significandBase = binary.substr(9); var significandBin = '1'+significandBase; var i = 0; var val = 1; var significand = 0; if (exponent == -127) { if (significandBase.indexOf('1') == -1) return 0; else { exponent = -126; significandBin = '0'+significandBase; } } while (i < significandBin.length) { significand += val * parseInt(significandBin.charAt(i)); val = val / 2; i++; } return sign * significand * Math.pow(2, exponent); } // example use data = '408df220' // is floating point value 4.43580627441406255 value = decodeFloat(data); log.console('Value=', value);The code above is from https://stackoverflow.com/questions/4414077/read-write-bytes-of-float-in-js
From a great website application at https://gregstoll.dyndns.org/~gregstoll/floattohex/ I produced the image below

Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login