...
int a = -6; // binary: 1000000000000110
When we are interested at in working on a binary level, it's sometimes helpful to use hexadecimal values, which are a bit like an intermediary between binary and decimal.
...
When we look at it this way, we see that in a a 2-byte integer, we could for example store a an RGBA color colour value (Red, Green, Blue, Alpha). This could be really helpful , if we say wanted to send color colour values from a computer to an Arduino in the form of integers. This could in some cases be much is principle faster than sending 4 values independently. In the next section, we will see how it’s done.
Bit Shifting Operators
The three bit shifting operators are as follows:
<<
the left shift operator>>
the (signed) right shift operator.
Note, that we are using unsigned numbers here to keep things simple, refer to the Arduino reference page if you need to work with signed numbers.
Shift right:
Code Block | ||
---|---|---|
| ||
unsigned int a = 32356; // binary: 0111111001100100
unsigned int b = a>>8 // binary: 0000000001111110 |
Shift left:
Code Block | ||
---|---|---|
| ||
unsigned int a = 32356; // binary: 0111111001100100
unsigned int b = a<<8 // binary: 0110010000000000 |
In both the above cases, some of the bits have been shifted into oblivion, and 0s have filled the new spaces
If you want, you can also set values in c++ as hexadecimal or binary. The three variables below all have exactly the same value:
Code Block | ||
---|---|---|
| ||
unsigned int RGBAvalue1 = #FF00FF16
unsigned int RGBAvalue2 = B11111111000000001111111100010101;
unsigned int RGBAvalue3 = 4278255382; |
Putting it to use
So we can move bits around, but how do we extract sets of values out of one variable? One solution is to bracket the values we need into smaller variables with a specific length.
...
Here we have our colour values stored as binary in one variable:
11111111000000001111111100000000
11111111 00000000 11111111 00000000
red | green | blue | alpha
Each block is 8 bits or one byte. So we will use the byte variable chop off and keep the last 8 bits:
Code Block | ||
---|---|---|
| ||
unsigned int RGBAvalue = #FF00FF16 // binary: 11111111000000001111111100010101
byte ALPHA = RGBAvalue; // binary: 00010101 |
We can repeat this process, in combination with the shift right operator to extract all the values:
Code Block | ||
---|---|---|
| ||
// In reality, we might get the RGBAvalue value from serial or BLE
unsigned int RGBAvalue = #FF00FF16 // binary: 11111111000000001111111100010101
byte RED = RGBAvalue >> 24; // binary: 11111111
byte GREEN = RGBAvalue >> 16; // binary: 00000000
byte BLUE = RGBAvalue >> 8; // binary: 11111111
byte ALPHA = RGBAvalue; // binary: 00010101 |
P5js / javascript code
But how do will combine the values to start with, before we seperate them on the Arduino? Here we are assuming that you want to do that on your computer, in a P5js web application that might use serial, BLE, or wifi to communicate with Arduino.
Code Block | ||
---|---|---|
| ||
const buffer = new ArrayBuffer(4); // create a 4 byte buffer to store values
const view = new DataView(buffer); // dataview allows reading and writing without having to care about the platform's endianness.
view.setUint8(0, Red);
view.setUint8(1, Green);
view.setUint8(2, Blue);
view.setUint8(3, Alpha);
let bufferToSend = view.getUint32();
|