Ieee 754
Ronen
Posts: 55
I know this subject have been discussed in other threads:
http://www.amxforums.com/showthread.php?t=2809&highlight=floating
but my question is different (i think...)
I'm getting a 32bit hex code that represents a temperature.
I need to convert it to a float number. i have been told that i need to use IEEE754.
Any idea or example?
http://www.amxforums.com/showthread.php?t=2809&highlight=floating
but my question is different (i think...)
I'm getting a 32bit hex code that represents a temperature.
I need to convert it to a float number. i have been told that i need to use IEEE754.
Any idea or example?
0
Comments
If it really is an IEEE 754 32-bit ("single precision") value, here is some code to convert it. It does not handle INF, NaN, or any other "denormalized" numbers, but hopefully you won't encounter those from your thermostat unless somebody's been playing with set_outdoor_temperature again. Code is verbose to help you understand it and to help the NetLinx compiler understand it -- it seems to throw a fit about multiple type_casts on a line.
jweather,
I have tested the function and it gives the correct values as the thermostats.
Thanks for the help, saved me a big headache, and the best thing is that I learned something
new
Thank you
Forgot to link this last time: http://en.wikipedia.org/wiki/IEEE_754 has some nice step-by-step explanations of the conversion process, and should help the code above to make more sense.
The Company is located here in Israel and is called "Dalkina" and the product name is "UniSense", its not a normal thermostat as you can understand... it also watches water boiler temp, pool temp and presures in the pipes around the house, also Rack room voltage and Amp usage.
You can speak with the Unisense CPU with Modbus Tcp which is pretty easy, but, you have to use hex values, that's why they used this Ieee thingy.
i can show on the amx panel almost everything that is going on in the house with this system... pretty cool.
If you want more details about the company just tell me.
You may need to change the byte order of outp if the device wants big-endian values.
I'm not sure if there's an easy way to put a long into a string as four bytes. Here's how I would do it:
send_string DevDV, "outp>>24, (outp>>16)&$FF, (outp>>8)&$FF, (outp&$FF)";
Or if it wants big-endian byte order:
send_string DevDV, "(outp&$FF), (outp>>8)&$FF, (outp>>16)&$FF, outp>>24";
Again, remember the online IEEE754 converter tool for testing your inputs and outputs (new URL): http://people.rit.edu/meseec/eecc250-winter99/IEEE-754hex32.html
Thanks for posting your code to deal with IEEE-754 conversions.
I'm in the process of writing a module to control an HVAC system called Cylon, which within its protocol uses IEEE-754 to send and receive analog values (primarily temperature).
Within a standard data string, alongside hex values for 'site number', 'unit address' etc, there will be 4 hex numbers which are the IEEE-754 representation of the temperature as a float data type.
I've checked some example values the HVAC system sends to me using IEEE-754 website tool you referenced and it's definitely IEEE-754.
I'm a little confused how I would take the 4 hex values I am receiving as a string, and pass them into your first function "parseFloat", as it requires a LONG data type....
Thanks
You might be interested in some of the encoding/decoding functions from the NetLinx Common Libraries math library. It takes advantage of the string_to_variable internal function for the IEEE-754 conversion so it all takes place outside of NetLinx land. Check out the the raw_be_to_long function for conversion from the byte array to a long before decoding the floating point value.
Where does this code come from? Is it in the public domain for all to use?
Paul
That is a very useful math library, I'll test it out later today.
I wrote it, translating the Wikipedia entry on IEEE754, which is based on the spec. Public Domain works for me.
Each of the four bytes is 8 bits of the 32-bit LONG value, so you just need to shift them into position and bitwise OR them together:
when i receive a 32bit Long value below 2 (i havent fully checked the range here, but Long values of 2 and above seem to work ok!), if I run it through the "parseFloat" function, the returning Float value is always 0 (zero).
Example, I receive my 32bit Long value in hex form: $3F,$80,$00,$00
After shifting each of the 4 bytes together I get:
Binary : 111111100000000000000000000000
Decimal: 1065353216
Yet running this Long value through the "parseFloat" function returns 0.
any ideas?
Yup, you found a bug with the special case of exponent=127, which is how you encode a value of 1. I will edit the code above to correct this in case anybody else runs into it, but where it used to read: "if (exp == 127) return 0.0;" change it to "if (exp == 127) return 1.0;" Because 2^0 == 1, not 0.
much appreciated
First, thank you very much to JWeather for posting these conversion functions. I compared the values I was receiving from the Daikin and the IEEE 754 converter URL, then I ran through an example calculating all of it by hand following through the code he posted below and my hand calculations came up the same. I'm still programming my Daikin code, but the temperature conversions were definitely a hurdle. And this code was quite helpful.
Here's how I handled that:
lSP = encodefloat(fSP)
cB1 = lSP % $100
cB2 = lSP / $100 % $100
cB3 = lSP / $10000 % $100
cB4 = lSP / $1000000
Then if you want big endian you just order the bytes in descending order. But Daikin uses little endian.