1

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

Alex Pacini
  • 314
  • 4
  • 14
  • Can the receiving end get "out-of-phase" such that it is receiving the end bytes form 1 packet and the beginning byte of a following packet? If this is possible, your packets needs to increase in size to include something to insure proper aligned during communication. – chux - Reinstate Monica Dec 05 '13 at 23:29
  • The packet size should be enough for that scope, I have 20 byte packet while the float is just 4 byte. Moreover, the packet is created setting the data in the proper location of the array to send, this removes even the problem of inverse reordering (a classical problem with serial communications). Thanks! – Alex Pacini Dec 06 '13 at 09:03

2 Answers2

2

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.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Thank you for your answer: the test on the pc (compiled by gcc) worked as well (obviously). Tomorrow I will test it on the CC2530 and I will see what happens. What I didn't see was the possible different alignment. This makes sense for a memory limited system as is the CC2530. – Alex Pacini Dec 05 '13 at 22:00
  • It works perfectly! Just used `osal_memcpy` that is provided by TI. Thank you again. – Alex Pacini Dec 06 '13 at 13:36
1

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.

bblincoe
  • 2,393
  • 2
  • 20
  • 34
  • You are perfectly right in the sense of the overhead, but for the application I am building I need the use of float to keep a certain precision. Since for this application the overhead is not important, I didn't wanted to deal with pre multiplications and division to keep that precision constant. Furthermore, I think it can have the same problem when copying as the float, cause the alignment (8 bit is not enough, though). Thank you! – Alex Pacini Dec 05 '13 at 22:53