30 Days Lost in Space → Help Center

Coding Concepts

Bits, Bytes, and Bitwise Operations

Binary makes more sense once you see it as light switches. This is your guide to binary counting, bitwise operators, hex notation, and the practical patterns you need for shift registers and reading inputs.

Think of It as Light Switches

Imagine 8 light switches on a wall. Each switch is OFF or ON. That row of 8 switches is a byte. Each switch is a bit.

Switch:   7   6   5   4   3   2   1   0
State:  OFF OFF OFF OFF OFF OFF OFF  ON
Binary:   0   0   0   0   0   0   0   1

That pattern, 00000001, is the number 1 in binary. Flip switch 1 on too and you get 00000011, which is 3. With 8 switches you can make 256 different patterns (0 through 255).

Binary Counting

| Decimal | Binary | Which bits are on | |---------|--------|-------------------| | 0 | 0000 | none | | 1 | 0001 | bit 0 | | 2 | 0010 | bit 1 | | 3 | 0011 | bits 0, 1 | | 4 | 0100 | bit 2 | | 5 | 0101 | bits 0, 2 | | 6 | 0110 | bits 1, 2 | | 7 | 0111 | bits 0, 1, 2 | | 8 | 1000 | bit 3 | | 15 | 1111 | bits 0, 1, 2, 3 |

Each bit position has a value that doubles going left:

Bit:     7     6     5     4     3    2    1    0
Value:  128   64    32    16     8    4    2    1

To convert binary to decimal, add up the values of the ON bits. 00001011 = 8 + 2 + 1 = 11.

Why This Matters on Arduino

When you call digitalWrite() on 8 pins, you are setting 8 bits one at a time. A shift register lets you set all 8 at once by sending a single byte:

// Without shift register: 8 lines, 8 pins
digitalWrite(2, HIGH);
digitalWrite(3, LOW);
// ...6 more lines...

// With shift register: 1 line, 1 byte
shiftOut(dataPin, clockPin, MSBFIRST, 0b10000001);

Bitwise Operators

These work on individual bits. They are different from &&, ||, and ! which work on true/false.

<< Left Shift (target a specific bit)

1 << 0  =  00000001  =  1     (bit 0 on)
1 << 1  =  00000010  =  2     (bit 1 on)
1 << 3  =  00001000  =  8     (bit 3 on)
1 << 7  =  10000000  =  128   (bit 7 on)

Think of 1 << n as "create a byte where only bit n is on."

>> Right Shift

Slides bits right. Shifting right by n is the same as dividing by 2^n.

| OR (turn bits ON)

If either bit is 1, the result is 1.

byte leds = 0b00000001;       // LED 0 on
leds = leds | (1 << 3);       // Also turn on LED 3
// leds is now 0b00001001

OR never turns bits off. It can only turn them on.

& AND (check or mask bits)

Result is 1 only if both bits are 1.

byte switches = 0b00001010;

if (switches & (1 << 3)) {
  // bit 3 is set (result is 00001000, non-zero = true)
}

~ NOT (flip all bits)

byte leds = 0b00001111;
leds = leds & ~(1 << 2);    // Turn off bit 2
// ~(1 << 2) = ~00000100 = 11111011
// 00001111 & 11111011 = 00001011

^ XOR (toggle bits)

Result is 1 if bits are different.

leds = leds ^ (1 << 2);  // Flip bit 2
leds = leds ^ (1 << 2);  // Flip it back

Quick Reference

| Goal | Code | |------|------| | Turn on bit n | value | (1 << n) | | Turn off bit n | value & ~(1 << n) | | Toggle bit n | value ^ (1 << n) | | Check if bit n is on | value & (1 << n) | | All bits on | 0xFF | | All bits off | 0x00 |

Hexadecimal

Hex is base-16. Each hex digit maps to exactly 4 binary digits.

| Hex | Binary | Hex | Binary | |-----|--------|-----|--------| | 0x0 | 0000 | 0x8 | 1000 | | 0x1 | 0001 | 0x9 | 1001 | | 0x2 | 0010 | 0xA | 1010 | | 0x3 | 0011 | 0xB | 1011 | | 0x4 | 0100 | 0xC | 1100 | | 0x5 | 0101 | 0xD | 1101 | | 0x6 | 0110 | 0xE | 1110 | | 0x7 | 0111 | 0xF | 1111 |

A full byte is two hex digits: 0xFF = 11111111 = 255.

Binary Literals

Arduino supports 0b notation. Great for visualizing LED patterns:

byte pattern = 0b10101010;  // every other LED on
byte edges   = 0b10000001;  // first and last only

Shift Register Patterns

1 << n               // one specific LED on
0xFF                  // all on
0x00                  // all off
0x0F                  // first 4 on (00001111)
0xF0                  // last 4 on  (11110000)
0xAA                  // alternating (10101010)

// Build up a pattern
byte p = 0;
p = p | (1 << 0);    // turn on LED 0
p = p | (1 << 3);    // turn on LED 3
p = p | (1 << 7);    // turn on LED 7
// p is now 10001001

Common Mistakes

| Mistake | What Happens | Fix | |---------|-------------|-----| | Confusing | with || | Logical OR gives 0 or 1, not a bit pattern | Use single-character operators for bits | | Off-by-one (bits count from 0) | 1 << 3 is the 4th bit, not the 3rd | Check your wiring to see which end is bit 0 | | byte wrapping | 200 + 100 = 44 (wraps past 255) | A byte holds 0 to 255, nothing more | | Shifting by 8 on a byte | Pushes the 1 completely out, result is 0 | Max shift for a byte is 7 | | Forgetting to latch | Variable changes but LEDs stay the same | Send the byte to the shift register after every change |