Sending a float across a serial connection

14 Jan 2013

Hi all...

I'm messing about with the btserial, (serial across a bluetooth dongle) library

and it has putc and getc and they work just fine.

I want to send a float,.. 1 hour of googling and playing later... I have this. (lots people saying it can be done like this, and it appears to work on an arduino?)

float f = pot1.read(); 
printf("Value: %f", pot1.read());   //displays 0.9

char * b = (char *) &f;

//split it up and send the 4 bytes.
outgoing->putc(b[0]);
outgoing->putc(b[1]);
outgoing->putc(b[2]);
outgoing->putc(b[3]);
       
//surely this should just reconstitute a float into z?
//if it works, I'll sort out the receive on the other mbed                       

float * z = (float *) &b;
printf("Recon: %f", z);

I basically.. split it into 4 bytes, send them across, and see them arrive the other side, but it doesn't reconstitute into a float. I just get 0.0000

So.. I thought I'd just reconstitute and print out on the sending side. That doesn't work though. So it's nowt to do with the transmission, it's to do with the reconstitution.

any help gratefully received, as I thought it'd be simple.

14 Jan 2013

The second cast should be float z = *(float *)b;, since b is already a pointer. But this approach is rather prone to errors anyway, it's probably better to use a union:

http://mbed.org/forum/helloworld/topic/2053/

14 Jan 2013

Thankyou sir ! you are a genius.

That now works with the correct cast, and I have one mbed talking to another across those little bluetooth dongles, and shortly one will be controlling the brightness of LED's on the other one. (before the application becomes a bit more serious)

Built on the shoulders of giants from here...

http://mbed.org/forum/mbed/topic/2269/

Now I shall go and read the other thread you posted, I promise I searched the forum before I started, I must have missed that.

15 Jan 2013

Byte order and floating point formats vary. there is an IEEE standard, if both ends adhere. Not sure if the two ends match? Send the float as text (ASCII string).

17 Jan 2013

Hi

Sending floats as text is also full of problems. Decimal and thousand separator character vary by country. I had my fair share of these bugs but still send floats as text. But it requires some adaption of code on the other side of the commlink when parsing the text.

regards wvd_vegt

18 Jan 2013

yes, comma, period, and so on by country. still, dealing with these not needed if you are both sender and receiver. Otherwise, dealing with comma/period is far easier than sending binary floating point data... Text is far easier than binary Binary is ambiguous as to format, byte order, number of bytes, IEEE or ISO standard or no standard, etc.

The argument for binary is if the efficiency of binary is justified, i.e., many transfers per second.

21 Jan 2013

How's this for lateral thinking.

I was just trying to send a value read from an analogIn across a comms link. I didn't need high precision. 8 bit was fine.

So, I did

uint8_t aValue = 255.0 * pot.read()

I then sent that 1 byte across,

and at the other end, I extracted it back out with

float f = aValue / 255

I was however then advised to use 6 bits, not 8, so that it keeps it in the ASCII range, I'll have to have a look and see if I can understand the code snippet I was sent !

22 Jan 2013

Huh? Truncating a float (255.0) to 8 bits and sending one byte.. of course that works. But why would one be using a float for a small integer?

The 6 bit advice is wrong. ASCII is 7 bits without Unicode. It's easy to send 8 bit bytes as well.

It's not easy to send the byte stream for a, say, 4 byte float (single precision) unless you are both sender and receiver and the floating point libraries are identical on both ends. This is, as said earlier, because there are varyious ways those 8 bytes depict floating point numbers, depending on the libraries used and the CPU's underlying byte ordering. On each end.

So simplest is to just convert the float to a string like "-3.1415925" and send that. Do the reverse on the other end. Unless you want higher speed transfers.

22 Jan 2013

Hi Steve,

yep, I was just trying to send the float that I get from the pot read across. (0.0 - 1.0) I spent ages messing about trying to send it as 4 bytes, cos every now and then I dropped a byte and then everything went haywire, and I wanted a very simple send and receive protocol without lots of checking.

Then I realised 8 bits was enough, so I normalised/truncated it to an 8 bit integer. and sent that across. I needed it back to a float the other end to set the brightness of an LED. I suppose the moral of the story is, I stopped thinking I needed to send a float, and thought about what I actually needed to send.

Thanks for pointing out 7 bits is fine.

I'm not a C programmer by trade, so the low level stuff gets me, I've not touched it in years as I'm Java these days. (I've been told not to say the J word on this forum though ;-) )

cheers,

Dave.

27 Jan 2014

I'm trying to do something very similar at the moment and I'm getting very frustrated.

Should something like this work?

Serial pc(USBTX, USBRX); pc.printf("(%f)", 123.456);

I'd expect to see "(123.456)" at the other end of this serial connection but instead all I get is "()".

How can I get this float or double value across the serial connection??