The One-Sentence Definition and Why It Matters on the Bench

Binary notation is a base-2 numbering system that uses only two digits, 0 and 1, to represent all numerical values and logical states. In a physical circuit, binary notation changes how we interface with silicon: it is the exact translation layer between abstract mathematics and physical voltage, dictating how a microcontroller interprets a 3.3V logic HIGH and a 0V logic LOW to process data, route memory, and toggle GPIO pins.

Makers frequently confuse binary notation (the mathematical representation of a value) with binary logic (the physical voltage thresholds, like TTL vs. CMOS, that define a 1 or 0). Another common trap is treating hexadecimal as a completely separate numbering system, rather than what it actually is—a human-readable shorthand designed specifically to compress long strings of binary digits into manageable chunks for programmers.

Translating Voltages to Numbers: A Worked Numeric Example

Let us look at an 8-bit shift register, like the ubiquitous 74HC595, or an 8-bit microcontroller port register. When you write a byte to these pins, you are sending eight distinct voltage states simultaneously. Suppose your logic analyzer captures the following physical states on pins 7 through 0 (where HIGH = 1 and LOW = 0):

Binary Value: 10110010

To understand what this means to the silicon, we convert it to base-10 (decimal) by multiplying each bit by its positional weight (powers of 2, starting from 0 on the right):

  • Bit 7 (MSB): 1 × 2^7 = 128
  • Bit 6: 0 × 2^6 = 0
  • Bit 5: 1 × 2^5 = 32
  • Bit 4: 1 × 2^4 = 16
  • Bit 3: 0 × 2^3 = 0
  • Bit 2: 0 × 2^2 = 0
  • Bit 1: 1 × 2^1 = 2
  • Bit 0 (LSB): 0 × 2^0 = 0

Summing the active bits: 128 + 32 + 16 + 2 = 178. In hexadecimal, this is 0xB2. If this register controls a resistor-ladder DAC (Digital-to-Analog Converter), that binary notation directly dictates the analog output voltage step. If it controls a shift register, it means pins Q7, Q5, Q4, and Q1 are sourcing current, while the others are sinking or floating.

Bench Tip: When debugging with a multimeter, do not try to measure the 'number'. Measure the physical voltage on each pin relative to GND. A reading of ~3.3V (on a 3V3 logic board) confirms a '1', while <0.4V confirms a '0'. Reconstruct the binary notation on paper, then convert it to hex to match against your serial monitor output.

Where You Meet Binary Notation in Practice

You will rarely write raw binary math by hand unless you are configuring hardware registers or debugging a protocol. Here is where it physically manifests on your workbench:

  1. DIP Switches on Motor Drivers: Stepper drivers like the TB6600 use physical toggle switches to set microstepping and current limits. The silkscreen on the PCB maps switch combinations (e.g., ON-ON-OFF) directly to binary notation, which the internal logic decodes to set the current reference voltage.
  2. I2C and SPI Addressing: When multiple sensors share an I2C bus, their hardware address pins (A0, A1, A2) act as physical binary inputs. The state of these pins constructs the binary notation of the device's slave address.
  3. Direct Port Manipulation: In high-speed Arduino or ESP32 code, using digitalWrite() is too slow. Instead, you write directly to the port register using bitwise operators (e.g., PORTD |= (1 << 3)), which forces the 3rd bit of the binary register to a 1 without disturbing the other seven bits.

Real-World Scenario Walkthrough: The I2C Address Collision

Understanding binary notation is critical when scaling up embedded projects. Here is a real-world failure mode involving I2C addressing.

The Setup: You are building a 16-channel relay controller using an ESP32 and two NXP PCF8574 8-bit I/O expanders. The I2C bus requires 4.7kΩ pull-up resistors on the SDA and SCL lines. The PCF8574 has a fixed 4-bit internal prefix (0100) and three external address pins (A2, A1, A0) that you must configure.

The Numbers: The base 7-bit I2C address is formed by combining the fixed prefix with the A-pins.
Chip 1: A2=GND(0), A1=GND(0), A0=GND(0). Binary address: 0100000 (Hex: 0x20).
Chip 2: A2=GND(0), A1=GND(0), A0=GND(0). Binary address: 0100000 (Hex: 0x20).

The Outcome: You upload your code and command the ESP32 to turn on Relay 1 (connected to Chip 1, Pin P0). Instead of just Relay 1 clicking, Relays 1 and 9 (connected to Chip 2, Pin P0) both fire simultaneously. The serial monitor shows no errors, but your hardware is behaving erratically.

What Went Wrong: Because both chips were hardwired to the exact same binary notation address (0100000), an I2C bus collision occurred. When the ESP32 broadcasted the command to 0x20, both chips acknowledged (ACK'd) the address and executed the payload simultaneously. In a system with mixed loads, this can cause massive current spikes, brownouts, or blown traces.

The Fix: You must alter the binary notation of the second chip's address by changing its physical pin states. By wiring the A0 pin on Chip 2 to VCC (Logic 1), the address becomes 0100001 (Hex: 0x21). The ESP32 can now independently target 0x20 and 0x21 without collision.

Quick-Reference: 4-Bit Binary to Hex Mapping

Memorizing the full 8-bit table is unnecessary. Instead, memorize this 4-bit (nibble) mapping. When reading an 8-bit binary string like 10110010, split it in half (1011 and 0010), map each half using this table, and combine them (B and 2 = 0xB2).

Binary (4-bit) Hexadecimal Decimal Practical Hardware Example
000000All GPIO pins LOW (0V)
000111LSB pin HIGH (e.g., LED on Pin 0)
001022Pin 1 HIGH, Pin 0 LOW
001133Pins 0 and 1 HIGH
010044Pin 2 HIGH
010155Pins 0 and 2 HIGH
011066Pins 1 and 2 HIGH
011177Pins 0, 1, and 2 HIGH
100088Pin 3 HIGH (MSB of nibble)
100199Pins 0 and 3 HIGH
1010A10Pins 1 and 3 HIGH
1011B11Pins 0, 1, and 3 HIGH
1100C12Pins 2 and 3 HIGH
1101D13Pins 0, 2, and 3 HIGH
1110E14Pins 1, 2, and 3 HIGH
1111F15All 4 pins HIGH (Max value)

Frequently Asked Questions

Why do we use hexadecimal instead of just writing binary in code?

Human cognitive load. Reading a 32-bit memory register written as 11111111000000001010101001010101 is highly error-prone. Grouping those bits into 4-bit nibbles and converting them to hex yields 0xFF00AA55. The microcontroller still processes it as binary, but the hex notation allows the programmer to instantly recognize byte boundaries and specific bit masks.

Does binary notation apply to analog circuits?

Not directly. Analog circuits deal with continuous voltage and current ranges governed by Ohm's and Kirchhoff's laws. However, the bridge between analog and digital—such as Analog-to-Digital Converters (ADCs) and Pulse Width Modulation (PWM)—relies entirely on binary notation. An ADC samples an analog voltage and outputs a binary number (e.g., a 12-bit ADC outputs a value from 000000000000 to 111111111111) that represents that specific voltage step.

How do I read binary notation for bitwise operations in C++?

According to the Arduino bitwise reference, you can manipulate binary notation using shift (<<, >>) and logical (&, |, ^) operators. To check if the 3rd bit of a variable is a 1, you use a bitmask: if (myVar & (1 << 3)). This isolates that specific binary position without altering the rest of the byte.