views:

113

answers:

3

I have one microcontroller sampling from a lot of ADC's, and sending the measurements over a radio at a very low bitrate, and bandwidth is becoming an issue.

Right now, each ADC only give us 10 bits of data, and its being stored in a 16-bit integer. Is there an easy way to pack them in a deterministic way so that the first measurement is at bit 0, second at bit 10, third at bit 20, etc?

To make matters worse, the microcontroller is little endian, and I have no control over the endianness of the computer on the other side.

EDIT: So far, I like @MSN's answer the best, but I'll respond to the comments

@EvilTeach: I'm not sure if the exact bit pattern would be helpful, or how to best format it with text only, but I'll think about it.

@Jonathan Leffler: Ideally, I'd pack 8 10-bit values into 10 8-bit bytes. If it makes processing easier, I'd settle for 3 values in 4 bytes or 6 values in 8 bytes (although the 2 are equivalent to me, same amount of 'wasted' bits)

+3  A: 

You can use bitfields, but the ordering within machine words is not defined:

That said, it would look something like:

struct adc_data { 
unsigned first :10;
unsigned second :10; 
unsigned third :10; 
};

EDIT: Corrected, thanks to Jonathan.

Matthew Flaschen
Surely it would be more like '`struct { unsigned first :10; unsigned second :10; unsigned third :10; } adc_data;`'? You don't want 1 bit assigned and 9 bits unassigned; you want three sets of 10 bits assigned, don't you - or doesn't the questioner.
Jonathan Leffler
You're right. I misunderstood the question.
Matthew Flaschen
+3  A: 

Use bit 0 and 31 to determine endianness and pack 3 10-bit values in the middle. One easy way to test matching endianness is to set bit 0 to 0 and bit 31 to 1. On the receiving end, if bit 0 is 1, assert that bit 31 is 0 and swap endianness. Otherwise, if bit 0 is 0, assert that bit 31 is 1 and extract the 3 values.

MSN
A: 

The simplest thing to do about endian-ness is to simply pick one for your transmission. To pack the bits in the transmission stream, use an accumulator (of at least 17 bits in your case) in which you shift in 10 bits at a time and keep track of how many bits are in it. When you transmit a byte, you pull a byte out of the accumulator, subtract 8 from your count, and shift the accumulator by 8. I use "transmit" here loosely, your probably storing into a buffer for later transmission.

For example, if transmission is little endian, you shift in your 10 bits at the top of the acccumator (in its MS bits), and pull your bytes from the bottom. For example: for two values a and b:

Accumulator     Count
(MS to LS bit)   
aaaaaaaaaa      10      After storing a
aa              2       After sending first byte
bbbbbbbbbbaa    12      After storing b
bbbb            4       After sending second byte

Reception is a similar unpacking operation.

ergosys