I am polling a sensor that outputs data in 32-bit IEEE 754 binary-encoded floats. When reading this with Arduino, I read this bytewise (Serial.read), so I construct a char array of 4 bytes and a null terminator. My question is- how can I convert this char array into a floating point by IEEE 754?
For example, if I had the array
C/¡[
I need to convert each character to its binary equivalent
01000011001011111010000101011011
Then I can use the IEEE 754 encoding to get a floating point number
What would be the best way to accomplish this on the Arduino?
Why would you pretend the array contained printable data?
A union of bytes (in an array) and a float would seem to be a starting point. Create an instance of the union, populate the byte array, and read the float part.
What PaulS said. Which I made an example of while he was typing:
void setup ()
{
Serial.begin (115200);
union
{
unsigned long a;
byte b [4];
float f;
} temperature;
temperature.a = 0x432fa15b;
Serial.print ("temperature is: ");
Serial.println (temperature.f);
} // end of setup
void loop () { }
Output:
temperature is: 175.63
To read from the device you would read into temperature.b [ 0 ] through to temperature.b [ 3 ] (I'm not sure of the order) and then access temperature.f.
I didn't know that union structs existed- I am able to read into a byte array as part of a union, and I can confirm that the bytes are correct with Serial.write. However, the actual floating point number is not correct- it randomly outputs as either "0.00", "-0.00", "ovf", or sometimes an extremely high number such as "-267668512.00". I'm not really sure what this means. I'll post my code, but I don't know how much help it will be since it's polling data that you guys don't have.
union {
byte b[4];
float f;
} yaw;
/*char pitch[4];
char roll[4];*/
void setup(){
//begin serial comms
Serial.begin(57600);
//disable the constant output stream, set mode binary, clear buffer
Serial.print("#o0");
Serial.print("#ob");
Serial.flush();
while (Serial.read() != -1);
}
void loop(){
while (Serial.read() != -1); //clear buffer before starting each loop
Serial.println();
Serial.println("#f"); //poll the Razor
int i=3;
while(i>=0){
if(Serial.available()){
yaw.b[i] = Serial.read();
i = i-1;
}
}
/*
int j=3;
while(j>=0){
if(Serial.available()){
pitch[j] = Serial.read();
j = j-1;
}
}
int k=3;
while(k>=0){
if(Serial.available()){
roll[k] = Serial.read();
k = k-1;
}
}*/
Serial.print("binary: ");
Serial.write(yaw.b,4);
Serial.println();
Serial.print("float: ");
Serial.println(yaw.f);
delay(1000);
}
That was indeed the problem- I was doing it that way because the bytes are sent from the sensor in little-endian, so for me to manually perform the conversion its easier to reconstruct it as big-endian. I guess the conversion to float needs it in little-endian as well. Thanks to all three of you. :>