I'm working on developing both the client(C) and server(C++) side of an RF connection. I need to send a float value, but the way the architecture is set up I have to arrange my message in a struct that limits me to 3 uint8t parameters: p0, p1, p2. My solution was to break the float into an array of 4 uint8_ts and send in 2 separate messages and use p0 as an identifier whether the message contains the first or second half.
So far I have something like this:
Server (C++):
sendFloat(float f)
{
messageStruct msg1, msg2;
uint8_t* array = (uint8_t*)(&f);
msg1.p0 = 1; //1 means it's the first half
msg1.p1 = array[0];
msg1.p2 = array[1];
msg2.p0 = 0; //0 means it's the second half
msg2.p1 = array[2];
msg2.p2 = array[3];
sendOverRf(msg1);
sendOverRf(msg2);
}
Client(C):
processReceivedMessage (uint32_t id, uint32_t byteA, uint32_t byteB) //(p0,p1,p2) are routed here
{
static uint32_t firsHalfOfFloat;
uint32_t ondHalfOfFloat;
float combinedFloat;
if(id == 1) //first half
{
firstHalfOfFloat = (byteA << 8) | byteB;
}
else //second half
{
secondHalfOfFloat = (byteA << 8) | byteB;
combinedFloat = (float)((firstHalfOfFloat << 16) | secondHalfOfFloat);
}
writeFloatToFile(combinedFloat);
}
then on request the client must then send that float back
Client(C):
sendFloatBack(uint8_t firstHalfIdentifier) // is commanded twice by server with both 0 and 1 ids
{
messageStruct msg;
float f = getFloatFromFile();
uint8_t* array = (uint8_t*)(&f);
msg.p0 = firstHalfIdentifier;
if(firstHalfIdentifier == 1) //First half
{
msg.p1 = array[0];
msg.p2 = array[1];
}
else //Second half
{
msg.p1 = array[2];
msg.p2 = array[3];
}
sendOverRf(msg);
}
and finally the Server (C++) gets the value back:
retrieveFunc()
{
float f;
uint32_t firstHalf;
uint32_t secondHalf;
messageStruct msg = recieveOverRf();
firstHalf = (msg.p1 << 8) | msg.p2;
msg = receiveOverRf();
firstHalf = (msg.p1 << 8) | msg.p2;
f = (firstHalf << 16) | secondHalf;
}
but I'm getting really wrong values back. Any help would be great.
Unions are a very convenient way to disassemble a float
into individual bytes and later put the bytes back together again. Here's some example code showing how you can do it:
#include <stdio.h>
#include <stdint.h>
typedef union {
uint8_t _asBytes[4];
float _asFloat;
} FloatBytesConverter;
int main(int argc, char** argv)
{
FloatBytesConverter fbc;
fbc._asFloat = 3.14159;
printf("Original float value is: %f\n", fbc._asFloat);
printf("The bytes of the float are: %u, %u, %u, %u\n"
, fbc._asBytes[0]
, fbc._asBytes[1]
, fbc._asBytes[2]
, fbc._asBytes[3]);
// Now let's put the float back together from the individual bytes
FloatBytesConverter ac;
ac._asBytes[0] = fbc._asBytes[0];
ac._asBytes[1] = fbc._asBytes[1];
ac._asBytes[2] = fbc._asBytes[2];
ac._asBytes[3] = fbc._asBytes[3];
printf("Restored float is %f\n", ac._asFloat);
return 0;
}