How To: Sending float to C++ program on PC

Hi all,

I’ve found that there have been a variety of posts regarding the transmission of floats over serial to a PC. They’ve all been done differently and none worked correctly for my application so I wanted to post this code as an FYI. Most examples revolved around C interface, whereas I’m retrieving data for display in a C++ windows forms application.

There are probably hundreds of ways to do it differently but here you go:

Arduino side:

void sendFloat(float f){
  byte * b = (byte *) &f;
  Serial.print("f:");
  Serial.write(b[0]);
  Serial.write(b[1]);
  Serial.write(b[2]);
  Serial.write(b[3]);
  Serial.print(68); //Send nonsense.. Else serial drops offline??
  Serial.flush();
  return;
}

Note the “send nonsense” line. I have no idea why, but if I did not include a Serial.print() command at the end of the series of Serial.write() commands, the communication would seize. Maybe someone can enlighten me on that.

C++ Application Side

		try
		{
			char inByte = serialArduino->ReadByte(); //serialArduino is a COM object
			if (inByte == 'f') 
			{
				serialArduino->ReadChar();  //Dispose of ":"
				byte indata[4] = { 0 };
				indata[0] = serialArduino->ReadByte();
				indata[1] = serialArduino->ReadByte();
				indata[2] = serialArduino->ReadByte();
				indata[3] = serialArduino->ReadByte();

				float g;
				memcpy(&g, &indata, sizeof(g));

			else
			{
				serialArduino->DiscardInBuffer();
				return;
			}

		catch (InvalidOperationException^ exception)
		{
			std::cout << "error" << "\n";
		}
  Serial.write(b[0]);
  Serial.write(b[1]);
  Serial.write(b[2]);
  Serial.write(b[3]);

Why notSerial.write (b, 4);?

AWOL:

  Serial.write(b[0]);

Serial.write(b[1]);
  Serial.write(b[2]);
  Serial.write(b[3]);


Why not`Serial.write (b, 4);`?

Good point - I did try that, and it would not initiate communication with the PC. It would send 1 byte then drop offline. Probably something basic I'm missing, so any insight would be appreciated.

C++ Application Side

All of it? I find that a tiny bit hard to believe.

PaulS:
All of it? I find that a tiny bit hard to believe.

Nope, didn’t say it was. For this particular application I used Windows forms, so I just added a serial port object to my project. Not much to show there, but if someone were interested in the specifics of how to open up a port they could refer to the following page:

Float Variable over Serial

where the author does show the opening of a port and a different method of piecing the float value back together.

Figured more information for people to learn from is never a bad thing.

import processing.serial.*;

Serial myPort;  // Create object from Serial class


void setup() 
{
  //size(600, 600);
  myPort = new Serial(this, "/dev/ttyUSB0", 9600);
}

void draw() {
  if(myPort.available() > 0) {
    char inByte = myPort.readChar();
    if(inByte == 'f') {
      // we expect data with this format f:XXXX
      myPort.readChar(); // discard ':'
      byte [] inData = new byte[4];
      myPort.readBytes(inData);
      
      int intbit = 0;
      
      intbit = (inData[3] << 24) | ((inData[2] & 0xff) << 16) | ((inData[1] & 0xff) << 8) | (inData[0] & 0xff);
      
      float f = Float.intBitsToFloat(intbit);
      println(f);
    }
  }
}
      intbit = (inData[3] << 24) | ((inData[2] & 0xff) << 16) | ((inData[1] & 0xff) << 8) | (inData[0] & 0xff);

What happens when you shift an 8 bit value 24 places? 16 places? 8 places? What fills the bits on the right?

PaulS:

      intbit = (inData[3] << 24) | ((inData[2] & 0xff) << 16) | ((inData[1] & 0xff) << 8) | (inData[0] & 0xff);

What happens when you shift an 8 bit value 24 places? 16 places? 8 places? What fills the bits on the right?

I didn’t go this route, but I can appreciate any constructive lessons.

I’d initially say, based on what I’ve learned in the past, it would fill with zeros. But that’s assuming you meant left shift as specified in the code snippet. Shifted 24 times the unsigned char would become an int as well I believe.

Shifted 24 times the unsigned char would become an int as well I believe.

Get out a checkerboard. Put 8 checkers on it, in the rightmost 8 spots on one row. Move them all 24 spaces to the left. What is the value of those 8 checkers that fell off the edge of the board?

When you shift an 8 bit value more than 8 places, the value is 0. If you cast the 8 bit value to a 32 bit value, THEN you can shift the 8 bits 24 places without any of them dropping off the edge.