TI CC2530 - Convert a float to uint8[] for sending and then convert back to float in reception

StackOverflow https://stackoverflow.com/questions/20410495

  •  29-08-2022
  •  | 
  •  

Question

I need to send some float numbers between some Texas Instrument CC2530 nodes. This architecture can only send an array of uint8.
What I already tried to do was to assign to an uint8 pointer the float pointer with a cast. Then I send these bytes and when received, they are copied in a uint8 array. In the end I create an another float pointer to which set a cast of the previously created array.
Actually, this trick works on my pc (using unsigned char instead of uint8) but not in the nodes, where the received number is always 0.

This is the part of the code used in the transmission event (there it creates the msa_Data1, that is the packet transmitted, where the number to send is valMed(a global variable)):

void Data_create(){
    uint8 *sends;
    sends = (uint8 *) &valMed;
    uint8 rec_index;
    for(rec_index=0; rec_index < sizeof(float); ++rec_index){
        msa_Data1[rec_index]= sends[rec_index];
    }
}

In the reception section I have:

uint8 receiveds[sizeof(float)];
uint8 rec_index;
    for(rec_index=0; rec_index < sizeof(float); ++rec_index){
        receiveds[rec_index]= pData->dataInd.msdu.p[rec_index];
    }
float *received= (float *)receiveds;

The data from the transmission is received by pData->dataInd.msdu.p[rec_index]

The simulation of the transmission I tried on a pc is:

main(){
    float send= -3.14;
    unsigned char *sends;
    sends = (unsigned char *)&send;
    printf("1:%d, 2:%d, 3:%d, 4:%d \nfloat sent:%f \n", sends[0], sends[1], sends[2], sends[3], send);
    unsigned char receiveds[sizeof(float)];
    int rec_index;
    for(rec_index=0; rec_index < sizeof(float); ++rec_index){
        receiveds[rec_index]= sends[rec_index];
    }
    float *received= (float *)receiveds;
    printf("float received:%f\n", *received);
} 

Output:

alex@aspire7738G ~/test $ ./test 
1:195, 2:245, 3:72, 4:192 
float sent:-3.140000 
float received:-3.140000

In this case I can see the test working well on the pc, but it does not on the nodes. What's wrong?

Thank you in advance for any help!

Alex

Was it helpful?

Solution

The code in the reception section is problematic. You copy bytes into receiveds and then use pointer conversions to treat it as a float. However, many C implementations use one-byte alignment for character/byte types (as receiveds likely is) and four-byte alignment for float types. Converting a uint8 pointer to a float pointer may result in a pointer with improper alignment.

Instead, you can do this:

float received;
… // Code that prepares receiveds goes here.
memcpy(&received, receiveds, sizeof received);

Additionally, if pData->dataInd.msdu.p is an array of or a pointer to bytes (char, unsigned char, or, likely, uint8 and uint8 is a character type in your C implementation), then you can omit using receiveds as an intermediate buffer and just copy directly:

float received;
// Omit the code that copied into receiveds.
memcpy(&received, pData->dataInd.msdu.p, sizeof received);

If that does not resolve the issue, then examine the actual bytes being copied into the send buffer and the bytes being copied from the receive buffer and ensure they are the same.

OTHER TIPS

Why not represent your numbers using fixed-point? Whenever I was working with the TI CC2530 I tried to avoid the overhead of floating-point and resorted to representing the numbers in fixed-point. These values are much more straight forward when sending them, but you have to be careful with your representation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top