Dzung Nguyen - 10 months ago 59

C Question

The limit size of a BLE packet is 20 bytes. I need to transfer the following data over it:

`struct Data {`

uint16_t top;

uint16_t bottom;

float accX;

float accY;

float accZ;

float qx;

float qy;

float qz;

float qw;

};

Size of Data is 32 bytes. The precision of floats can not be sacrificed, since they represent accelerometers and quaternions, and would create a huge drift error if not represented precisely (data would be integrated over time).

I don't want to send 2 packets as well, as it's really important that whole data is taken at the same time.

I'm planning to take advantage of the range instead.

- Accelerometer are IEEE floats in the range of [-10, 10]
- Quaternions are IEEE floats in the range of [-1, 1]. We could remove w, as x^2 + y^2 + z^2 + w^2 = 1
- Top, and bottom are 10-bit each.

Knowing this information, how can I serialize Data using at most 20 bytes?

Answer

Assuming binary32, code is using 2*16 + 7*32 bits (256 bits) and OP wants to limit to 20*8 bits (160).

Some savings:

1) 10 bit `uint16_t`

,

2) reduced exponent range saves a bit or 2 per `float`

- would save a few more bits if OP stated the _minimum exponent as well. (estimate 4 bits total)

3) Not coding `w`

.

This make make for 2*10 + 6*(32-4) = 188 bits, still not down to 160.

OP says "The precision of floats can not be sacrificed" implying the 24 bit (23- bits explicitly coded) significand is needed. 7 `float`

* 23 bits is 161 bits and that is not counting the sign, exponent nor 2 `uint16_t`

.

So unless *some* pattern or redundant information can be eliminated, OP is outta luck.

Suggest taking many samples of `data`

and try compressing it using LZ or other compression techniques. If OP ends up with significantly less than 20 bytes per average`data`

, then the answer is yes - in theory, else you are SOL.

Source (Stackoverflow)