reading 32bit floating point reg

R

Thread Starter

ross henderson

Hi,

i have a Modbus interface that is rather limited in functionality (can't change it, need to work with it!) it can read 16 bit integers but not 32 bit floating points. so far i have the following to 'join' the two registers...<pre>
If ((reg1 * 65535) + reg2) > 2.14745e+009 then temp = -(((reg1 * 65535) + reg2) - 4.2949e+009) Else
temp = ((reg1 * 65535) + reg2)
endif
print temp</pre>
the end result is 'almost' right. can anyone please advise on the calculation. thanks.
 
C

Curt Jeffreys

Declare an unsigned long, shift the high order register into this then OR it with the lower register then type cast the result as a float.
 
B

bob peterson

look up IEEE floating point format.

part of the 32 bits is an exponent and part is the mantissa. just separate them out and it is easy to get the right number.

--
Bob
 
R

ross henderson

> Declare an unsigned long, shift the high order register into this then OR it
> with the lower register then type cast the result as a float.

the system i'm using has a very simple VB implementation (BMS system called continuum). i can't declare a point type in this way and am limited to manipulating the modbus values in the way i showed.

the (reg1 * 65535) is used to get the value of the high register then it is added to the low register. as a floating point (32bit) has 4294967295 values, the mid point (and so = 0) is 2147483647. or have i missed something fundamental here?

help appreciated.
 
It appears your calculation is attempting to convert two 16 bit unsigned integers into one 32 bit signed integer. If this is what you want, you should change 65535 to 2^16 = 65536, change 4.2949e+009 to 2^32 = 4294967296, and change
2.14745e+009 to (2^32)/2 = 2147483648. Exact numbers are required for it to work right.

If you truly want to convert the two 16bit integers to a 32bit floating point value, the calculation is shown in detail in this spreadsheet http://www.simplymodbus.ca/ieeefloats.xls
 
R

ross henderson

> If you truly want to convert the two 16bit integers to a 32bit floating point
> value, the calculation is shown in detail in this spreadsheet
> http://www.simplymodbus.ca/ieeefloats.xls

excellent. thank you for the detailed help. this is indeed what i am looking for.

got a bit of reading up to do now though

mantisa?.......

thanks again.
 
A trick I've done is to pass things fixed point (no fractional info) by using the multiply then divide method. For instance if you need 10e-3 precision you can take your float number on one end, multiply it by 1000 and then on the other end read it in, convert it from int to float, and then divide by 1000. This only works if your max value multiplied by your scaler is within the 2^32 limit (or +/- 2^31 if you are signed).

Whether or not you convert it to floating point depends on the capabilities of the system you are working with. If you can convert from signed 32 bit to float the above works easily.

Or you could work out the IEEE floating point routines as others have recommended which will handle all cases. I guess it depends on what you want to do.

KEJR
 
Top