Dzung Nguyen Dzung Nguyen - 1 year ago 90
C Question

Represent float using integer

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 Source

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 averagedata, then the answer is yes - in theory, else you are SOL.