Modbus Float to Dynamic C Float conversion.

Good Day,
I have bit of a problem converting a 32-bit Float number from a Modbus slave into a Dynamic C float with the correct Value.:confused:

xmem float ET107_FLOATTEST(void)
auto char msg[4];
float f;

//Below msg array is a simulation of a part of a Modbus packet coming in from a weather station as a response to Modbus F03. Since the 32bit message is made up of two 16 bit Holding registers it will have to be read in the following order msg[2]msg[3]msg[0]msg[1], or 0x4156E147. the correct deci value should be 13.429…


//SHIFT and UNIT the 8 bit binary packets into a 32 bit bit floating value of //‘\B01000001010101101110000101000111’ = 13.429


return f;

auto float crntValue;
auto char buff1[7]

    sprintf(buff1, "%.1f", crntValue);

I know I should be geting 13.429 or 13.4 (%1f) but i keep on getting -7849.0 instead??
I wonder can anybody point out my error in this logic? I’m sure its in the ET107_FLOATTEST() function.


Modbus uses the IEEE single precision floating point format sent :

1st byte : Exponent (technically sign bit plus 7 most significant bits of exponent)
2nd byte : MSB of mantissa (technically lsb of exponent plus the 7 next-most significant bits of mantissa with msb of mantissa assumed to be a ‘1’ unless all other bits are ‘0’ - i.e. the place occupied by the lsb of the exponent)
3rd byte : Middle of mantissa
4th byte : LSB of mantissa

In short your bytes are swapped around. Easier is to declare a union :

(3rd edit - re-reading your op leaves me a bit confused. in any event…)

union { float f; unsigned char b[4]; } u;
IF your rx buffer really is : msg[0]=0xE1;
then :

u.b[3] = msg[2];
u.b[2] = msg[3];
u.b[1] = msg[0];
u.b[0] = msg[1];


u.f == 13.429;

'hope this helps (though I suspect you’ve found this out by now!