Reputation: 31
My question would be Arduino specific, although if you know how to do it in C it will be similar in the Arduino IDE too.
So I have 5 integer variables:
r1, r2, r3, r4, r5
Their value either 0 (off) or 1 (on). I would like to store these in a byte variable let's call it relays, not by adding them but setting certain bits to 1/0 whether they are 0 or 1. For example:
1, 1, 0, 0, 1
I would like to have the exact same value in my relay's byte variable, not r1+r2+r3+r4+r5 which in this case would be decimal 3, binary 11.
Thanks!
Upvotes: 3
Views: 14530
Reputation: 2827
I recommend using a UNION of a structure of bits. It adds a clarity and makes it readily portable. You can specify single or any size of adjacent bits. Along with quickly rearranging them.
union {
uint8_t BAR;
struct {
uint8_t r1 : 1; // bit position 0
uint8_t r2 : 2; // bit positions 1..2
uint8_t r3 : 3; // bit positions 3..5
uint8_t r4 : 2; // bit positions 6..7
// total # of bits just needs to add up to the uint8_t size
} bar;
} foo;
void setup() {
Serial.begin(9600);
foo.bar.r1 = 1;
foo.bar.r2 = 2;
foo.bar.r3 = 2;
foo.bar.r4 = 1;
Serial.print(F("foo.bar.r1 = 0x"));
Serial.println(foo.bar.r1, HEX);
Serial.print(F("foo.bar.r2 = 0x"));
Serial.println(foo.bar.r2, HEX);
Serial.print(F("foo.bar.r3 = 0x"));
Serial.println(foo.bar.r3, HEX);
Serial.print(F("foo.bar.r4 = 0x"));
Serial.println(foo.bar.r5, HEX);
Serial.print(F("foo.BAR = 0x"));
Serial.println(foo.BAR, HEX);
}
Where you can expand this UNION to be larger than bytes
Note uint8_t is the same as byte.
You can even expand the union to an array of bytes and then send the bytes over serial port or clock them out individual as one long word, etc... see a more extensive example.
Upvotes: 2
Reputation: 21213
How about:
char byte = (r1 << 4) | (r2 << 3) | (r3 << 2) | (r4 << 1) | r5;
Or the other way around:
char byte = r1 | (r2 << 1) | (r3 << 2) | (r4 << 3) | (r5 << 4);
Upvotes: 1