This was a question I encountered recently – how to take a stream of bytes and break them into parts – not just individual bytes, but bits of bytes.
In this case, the code was 2 nybbles in a byte (yes, really, nybbles, where a nybble is 4 bits).
A simple solution is to use bit operators to split out the code:
unsigned int a = (data>>4) & 0xF; // top 4 bits unsigned int b = data & 0xF; // bottom 4 bits
Why “& 0xF” in the first line? Because if your data is more than 8 bits, you want to remove the higher ones from the result (called masking), leaving only the single nybble of 4 bits.
The alternative is to use a union and a struct to combine the two:
union convertor { struct { byte type: 4; byte number: 4; } pieces; byte whole; };
Here, the union is between pieces and whole. whole is a byte (unsigned char, or 8 bits) and pieces is a structure of 4 bits (type) then 4 bits (number).
Because the values in a union share the same physical space, you just pop data in one end, and get it out the other:
union convertor data; data.whole=215; unsigned int a=data.pieces.type; // the type of each entry unsigned int b=data.pieces.number; // the number of each entry
It works the other way, too:
union convertor data; data.pieces.type=1; data.pieces.number=15; unsigned int result=data.whole; // type/number now one byte
Where unions and structs work well together is with complicated bitfield layouts. For example, say you have a 32 bit value that needs to swap nybbles in each byte (perhaps reading from an unusual data format). Then you could create a union for the whole thing, and swap very easily.
One option is this:
union convertor2 { struct { byte a1: 4; byte a2: 4; byte b1: 4; byte b2: 4; byte c1: 4; byte c2: 4; byte d1: 4; byte d2: 4; } nybble; unsigned long whole; }; union convertor2 temp, data; temp.whole=91303134; data.nybble.a1 = temp.nybble.a2; data.nybble.a2 = temp.nybble.a1; data.nybble.b1 = temp.nybble.b2; data.nybble.b2 = temp.nybble.b1; data.nybble.c1 = temp.nybble.c2; data.nybble.c2 = temp.nybble.c1; data.nybble.d1 = temp.nybble.d2; data.nybble.d2 = temp.nybble.d1;
data now contains the swapped values.
The result? unions provide a simple way to translate from one data entry to another – so give them a try.
Hi. Please tell me which IDE you are using for Arduino.
The IDE from arduino: https://www.arduino.cc/en/Main/Software
Nice trick .. thanks for sharing.