Data compression for radio control

MMESSITER

Active member
Hi

I was so fascinated by the result of today’s effort I felt I ought to share it in case others find it useful or interesting. I’ll put the full (short) code at the end.

The issue was that my radio control model servos have a max resolution of about 1024 positions. (... I’m developing a radio control system. )
The data buffer for sending a packet of data to the receiver is only 32 bytes max. So I mustn’t waste any.

1024 is too big for one byte, and shamefully wasteful if occupying two. So I decided to use 12 bits per channel.
The 16 servo values are stored wastefully as 16 x uint16_t, but compressed to 12 for transmission, and decompressed back to 16 on arrival at the receiver.
This is possible because the high four bits aren’t used.

The reason I thought the result of today’s coding was interesting is because it works perfectly, it’s very very short, and works equally well with any number of channels as long as the number is divisible by 4 !

If you copy, paste, and run the code below you’ll see what I mean!


// ******************** RC COMPRESS ***************

#define ChannelCount 16
#define CompressedCount ChannelCount * 3 / 4


uint16_t OriginalValues[ChannelCount];
uint16_t CompressedData [CompressedCount];
uint16_t DecompressedValues[ChannelCount];


void setup() {
Serial.begin (115200);

for (int i=0;i<ChannelCount;i++) {
OriginalValues= 2001 + i;
}

Compress(CompressedData,OriginalValues,ChannelCount);
Decompress(DecompressedValues,CompressedData,ChannelCount);
Showall();
}


void loop() {
// nothing here
}

// **** Compresses cc x 16 BIT o values down to only cc*3/4 c by using just their low 12 BITS... cc must be divisble by 4! ********
void Compress(uint16_t *c, uint16_t *o, int cc){
int p=0,l=0;for (l=0;l<(cc*3/4);l+=3){c[l]=o[p]<<4|o[p+1]>>8;p++;c[l+1]=o[p]<<8|o[p+1]>>4;p++;c[l+2]=o[p]<<12|o[p+1];p++;p++;}}

// **** Decompresses cc*3/4 x 16 BIT values back up to cc loading only their low 12 BITS... cc must be divisible by 4! ******************
void Decompress(uint16_t *d, uint16_t *c,int cc){
int p=0,l=0;for (l=0;l<(cc*3/4);l+=3){d[p]=c[l]>>4;p++;d[p]=(c[l]&0xf)<<8|c[l+1]>>8;p++;d[p]=(c[l+1]&0xff)<<4|c[l+2]>>12;p++;d[p]=c[l+2]&0xfff;p++;}}



void Showall(){
int i;
Serial.println ("Original values:");
for (i=0;i<ChannelCount;i++) { Serial.print(i+1);Serial.print("="); Serial.println( OriginalValues);}
Serial.println (" ");Serial.println ("Compressed data:");
for (i=0;i<CompressedCount;i++) { Serial.print(i+1);Serial.print("="); Serial.println( CompressedData);}
Serial.println (" ");Serial.println ("De-Compressed values:");
for (i=0;i<ChannelCount;i++){ Serial.print(i+1);Serial.print("="); Serial.println( DecompressedValues);}
}
 
Back
Top