FLOAT to INT and back again.

For questions and comments on programming in general. And for any items that don't fit into the forums below.

Moderators: Benj, Mods

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

FLOAT to INT and back again.

Post by Kisen »

Hi,
I have found myself facing a problem.

I have a device performing some calculations where the outputs of those calculations are floating point variables.
I need to send those variables via UART to a radio device where the information will be received by a webserver.

If i were keeping the readings internal and displaying on an LCD i would first convert the float to string, pull the string apart into integer and end up with 2 bytes, Number and Decimal. These can then be output to the display with a decimal point added in manually.
However in this case i would like the device to send the actual float value and then i can decide how best to handle it when its on the server.

I know a little about how a float value is constructed, although i cannot claim to fully understand it.
I know that a Float is a 32bit value and knowing this i can split it into 4 bytes once i have the 32bit value. Much easier for me to send over UART. This can then be converted back to a float again on the server side API, where i can manipulate and display it however i want to.

I am aware that converting a float2int will give me only the whole number part of the float and omit the decimal. Not what i am after in this case.

So, is this possible in flowcode to see the "bit data" of a floating point so that i can shift it out into 4 bytes?

Thanks

User avatar
Benj
Matrix Staff
Posts: 14948
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Contact:

Re: FLOAT to INT and back again.

Post by Benj »

Hello,

Yes this is possible, are you using Flowcode and if so which version are you using.

In Flowcode 8 there is a component that will do the conversion for you called type conversions available from the Data component category.

For older versions you will have to use a C code icon to acheive the same thing.

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

Re: FLOAT to INT and back again.

Post by Kisen »

Hi Benj,

I am just using the evaluation 30 day version of V8.

So i assume i just feed my float value into the component and it spits out a 32bit value?

If i wanted to do this in C how would it be done? I only ask as i see that each of the different modules cost when purchasing to a full license. So if i can do it all without the use of custom components it appears that it will be a more cost effective solution...

User avatar
Benj
Matrix Staff
Posts: 14948
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Contact:

Re: FLOAT to INT and back again.

Post by Benj »

If you wanted to convert floats to 4 bytes then you would use the SetFloat function to load in the float and then call the GetByte function four times with indexes 0-3.

The icon of the component on the panel should show how the values interrelate.
Type.jpg
Type.jpg (27.23 KiB) Viewed 2131 times
This topic should help if you want to do the code yourself using C.
viewtopic.php?f=28&t=12561&p=49907&hili ... oat#p49907

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

Re: FLOAT to INT and back again.

Post by Kisen »

Thanks Ben for the link to the C version.

I have followed this and have also found other C examples in the forum.
In my case the values being written to the bytes are all zero. Even if i preload the byte with a value it is overwritten by the C code to zero.

Any ideas why this is?

mnf
Valued Contributor
Valued Contributor
Posts: 864
Joined: Wed May 31, 2017 11:57 am
Contact:

Re: FLOAT to INT and back again.

Post by mnf »

See this thread viewtopic.php?f=7&t=21470&hilit=float where a different approach is used (taking the address of the number and writing/reading the value)

But, please, can you post your code that is not working?

Martin

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

Re: FLOAT to INT and back again.

Post by Kisen »

Hi

Here is the code i am using.

Supplementary Code:

Code: Select all

typedef union
{
  MX_FLOAT AsFloat;
  MX_UINT8 AsByte[4];
} MX_FloatUnion;

MX_FloatUnion FloatUnion;
Main Code:

Code: Select all

FloatUnion.AsFloat = FCV_FLOATTOBYTE;
FCV_F0 = FloatUnion.AsByte[0];
FCV_F1 = FloatUnion.AsByte[1];
FCV_F2 = FloatUnion.AsByte[2];
FCV_F3 = FloatUnion.AsByte[3];
These values always return zero. Even if i pre load them immediately prior to the C code.

I am using an STM32 if that changes anything.
Although the code compiles without any issues, can you see any problems here?

User avatar
Benj
Matrix Staff
Posts: 14948
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Contact:

Re: FLOAT to INT and back again.

Post by Benj »

Hello,

Please can you post your project that demonstrates this problem and we will have a look for you. STM32 shouldn't cause any problems regarding Floats and byte conversion.

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

Re: FLOAT to INT and back again.

Post by Kisen »

Hi,

I have attached the file for the program i am working on.
Attachments
Flowcode Test Pad.fcfx
(94.76 KiB) Downloaded 61 times

User avatar
Benj
Matrix Staff
Posts: 14948
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Contact:

Re: FLOAT to INT and back again.

Post by Benj »

Hello,

I might start with checking that the float calculations are producing what you expect. Maybe convert the float to a string and send the string via the serial connection as a sanity check.

This type of calculation could be causing problems.
.T_FLOAT = fdiv (.T_DATA,65536)
.T_FLOAT = fmul (175, .T_FLOAT)
// ACTUAL TEMPERATURE
.T_FLOAT = fadd (-45, .T_FLOAT)

//2^16 = 65536
.RH_FLOAT = fdiv (.RH_DATA,65536)
.RH_FLOAT = fmul (100, .RH_FLOAT)
Might be worth changing the integer values to float values to force the compilers hand when doing the calc.
.T_FLOAT = fdiv (.T_DATA,65536.0)
.T_FLOAT = fmul (175.0, .T_FLOAT)
// ACTUAL TEMPERATURE
.T_FLOAT = fadd (-45.0, .T_FLOAT)

//2^16 = 65536
.RH_FLOAT = fdiv (.RH_DATA,65536.0)
.RH_FLOAT = fmul (100.0, .RH_FLOAT)

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

Re: FLOAT to INT and back again.

Post by Kisen »

The outputs from those calculations are all outputting as expected.
I already convert these to strings and output them on the UART to verify them.

User avatar
LeighM
Matrix Staff
Posts: 2093
Joined: Tue Jan 17, 2012 10:07 am
Contact:

Re: FLOAT to INT and back again.

Post by LeighM »

The float is a double, so it’s 8 bytes.
Not sure if that explains the 0, but might be worth printing all 8 bytes

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

Re: FLOAT to INT and back again.

Post by Kisen »

LeighM wrote:The float is a double, so it’s 8 bytes.
Not sure if that explains the 0, but might be worth printing all 8 bytes
That has confused me a little.
A float is a 32bit value is it not?

If the float is a double then it would surely contain data in the first 4 bytes since this is where the sign bit and 11 bits of exponent data would be.
I can only assume that you are suggesting that the float is a double holding only a 32bit float value.

In this case how should i get the other 4 bytes? Do i just add more bytes to the code and supplementary code??

User avatar
LeighM
Matrix Staff
Posts: 2093
Joined: Tue Jan 17, 2012 10:07 am
Contact:

Re: FLOAT to INT and back again.

Post by LeighM »

If the float is a double then it would surely contain data in the first 4 bytes since this is where the sign bit and 11 bits of exponent data would be.
I think the F4 is little-endian

Yes, just add another 4 bytes to the union.

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

Re: FLOAT to INT and back again.

Post by Kisen »

I have added the other 4 bytes to the Union, to give me this.

Code: Select all

typedef union
{
  MX_FLOAT AsFloat;
  MX_UINT8 AsByte[8];
} MX_FloatUnion;

MX_FloatUnion FloatUnion;

Code: Select all

FloatUnion.AsFloat = FCV_FLOATTOBYTE;
FCV_F0 = FloatUnion.AsByte[0];
FCV_F1 = FloatUnion.AsByte[1];
FCV_F2 = FloatUnion.AsByte[2];
FCV_F3 = FloatUnion.AsByte[3];
FCV_F4 = FloatUnion.AsByte[4];
FCV_F5 = FloatUnion.AsByte[5];
FCV_F6 = FloatUnion.AsByte[6];
FCV_F7 = FloatUnion.AsByte[7];
I am getting a result now but not one that is understandable.

Results i get are as follows.

Float Value: 22.694473
Float Hex Value : 0x41B58E48
Binary Value: 01000001 10110101 10001110 01001000

Results from Union:
Decimal: 201 177 54 64
Hex Equivalent: C9 B1 36 40
Binary Values: 11001001 10110001 00110110 01000000

In all the tests i have done so far with a temperature sensor, the last 2 figures have stayed the same, so i assume the outputs to be backwards.

So we can re-write this as.

01000000 00110110 10110001 11001001

Which is a floating point value of 2.8546011

Do you have any further ideas?

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

Re: FLOAT to INT and back again.

Post by Kisen »

OK, This is interesting, But i dont know what to do with the information...

The Original value of 22.694473 Which has a bit code like this.

01000001101101011000111001001000

This is the bit code that i get from my outputs:

01000000001101101011000111001001

They look different and give a different value when converted to float.

But, if i shift my output to the left 3 spaces i get this

Original: 01000001101101011000111001001000
Mine: 01000000001101101011000111001001
Bits 8,9 and 10 need to be removed and put on the end to make this correct.

So the data appears to be there, Its just messed up somehow.
My brain cannot process what i am seeing in order to correct it.

Surely i shouldnt have to mess with the data coming from the Union to make it legible?

kersing
Valued Contributor
Valued Contributor
Posts: 1953
Joined: Wed Aug 27, 2008 10:31 pm
Location: Netherlands
Contact:

Re: FLOAT to INT and back again.

Post by kersing »

You added 4 bytes and read 8 into byte sized variables but your samples still show just 4 bytes worth of bits. Shouldn’t you look at 8 bytes and print the value of all 8?
“Integrity is doing the right thing, even when no one is watching.”

― C.S. Lewis

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

Re: FLOAT to INT and back again.

Post by Kisen »

The previous posts say that the float is a double containing only a 32 bit float value. So the first 4 bytes are all zero. So i read them, but i dont use them for anything as they just contain zero's

mnf
Valued Contributor
Valued Contributor
Posts: 864
Joined: Wed May 31, 2017 11:57 am
Contact:

Re: FLOAT to INT and back again.

Post by mnf »

Hi Kisen,

Try this - works AOK on Arduino and hopefully on ARM too....

Note the reversal of the bytes in FloatToByte...
float_to_byte.fcfx
(12.39 KiB) Downloaded 55 times
Note - if the floats are 64bit) - then extend the byte array to 8 bytes. If it is only 32bit then the last 4 bytes may be 'random' data

Martin

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

Re: FLOAT to INT and back again.

Post by Kisen »

kersing wrote:You added 4 bytes and read 8 into byte sized variables but your samples still show just 4 bytes worth of bits. Shouldn’t you look at 8 bytes and print the value of all 8?
So following your comment i thought it a good idea to actually see if there was data in the first 4 bytes. Turns out there is and it does indeed output correctly :) Thanks for the prompt.

Problem is that it is 8 bytes of data and not the 4 that i thought it would be, since the floating values seem to be double precision.

I need to figure out now how to make a double precision value into a standard float (32 bit) There will be too much data for my application using 8 bytes per value.

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

Re: FLOAT to INT and back again.

Post by Kisen »

Thanks Martin for the example.

Seems that your floats are converting on the assumption they are 32bit. I wonder why mine are double floating point? I was under the impression they were 32bit until Leigh said they were Doubles.

Is it because i am using ARM do you think??

I am pleased i have it outputting the individual bytes now, just i have more of them than i bargained for.

mnf
Valued Contributor
Valued Contributor
Posts: 864
Joined: Wed May 31, 2017 11:57 am
Contact:

Re: FLOAT to INT and back again.

Post by mnf »

If they are 64 bit then change byte array to 8 bytes (and the loop in FloatToByte)

If the values are 32 bit the last 4 bytes will be junk...

Martin

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

Re: FLOAT to INT and back again.

Post by Kisen »

mnf wrote:If they are 64 bit then change byte array to 8 bytes (and the loop in FloatToByte)

If the values are 32 bit the last 4 bytes will be junk...

Martin
At first I thought that to be the case. But it seems they arent junk. They are actually 64bit values.

So the Union works for me and does as it should.

I'm now looking for a way to convert the 64bit values to 32bit values

Kisen
Posts: 69
Joined: Fri Jan 24, 2020 10:38 am
Contact:

Re: FLOAT to INT and back again.

Post by Kisen »

I just found this on the matrix wiki.

A floating point value can represent a much wider range of values than an integer can, but at a loss of accuracy over large ranges. Floating point values when downloaded will be 64-bit if the target supports them, or 32-bit if it does not.

Seems that's why I am getting 64bit float values, simply because the target supports them.
Makes sense I suppose. Although where they are supported it would in my case be great to choose no to use 64bit as 32bit is more than enough.

mnf
Valued Contributor
Valued Contributor
Posts: 864
Joined: Wed May 31, 2017 11:57 am
Contact:

Re: FLOAT to INT and back again.

Post by mnf »

So - you want to convert the value to a 32bit integer (rather than a 32bit float)?

What range of values are you working with and how many points of accuracy do you need?

Taking the byte 'values' of the fp number isn't the way to go here (it would be possible - but difficult)

Could you - for example - use

Code: Select all

.UL = .x * 1000
(and let the compiler take the strain)

Which converts (in my example above) .x (a float) to 1234 (.UL an unsigned long)

There was an interesting piece in stackoverflow about how the number of bits in the exponent and mantissa was decided upon - can't just find the link at the moment.

The Flowcode wiki describes floats as representing numbers from -infinity to +infinity - and while this is true - it might need a few more bits to hold all the numbers accurately? :D

Martin

Post Reply