The binary system is a base-2 numeric framework that represents all data and logic states using only two symbols, 0 and 1, which map directly to the physical off and on voltage states of electronic switches. While software engineers treat binary as abstract math, for hardware builders and electrical technicians, understanding how the binary system works is fundamentally about understanding voltage thresholds, register allocations, and signal integrity. In a real circuit, binary dictates your microcontroller's ADC resolution, defines the exact voltage boundaries for logic gates, and determines how memory addresses are routed across communication buses like I2C and SPI.
The Core Math and Hardware Mapping
At the bench, we rarely count past 15 in raw binary unless we are looking at a logic analyzer trace. Instead, we group binary digits (bits) into 4-bit nibbles or 8-bit bytes, mapping them to hexadecimal for readability. Think of an 8-bit microcontroller register like a bank of 8 physical light switches; each switch represents a power of 2, from $2^0$ (1) on the far right to $2^7$ (128) on the far left.
To bridge the gap between abstract math and physical wiring, you need to know how these binary values translate to actual voltages. The physical voltage representing a binary '1' or '0' depends entirely on your logic family (e.g., 5V TTL vs. 3.3V CMOS). Below is a data-dense reference mapping 4-bit binary states to their decimal, hex, and physical voltage equivalents for the two most common hobbyist and industrial logic levels.
| Decimal | 4-Bit Binary | Hex | 3.3V CMOS Logic State (e.g., ESP32) | 5V TTL Logic State (e.g., 74HC Series) |
|---|---|---|---|---|
| 0 | 0000 | 0x0 | 0.0V (GND) | 0.0V (GND) |
| 3 | 0011 | 0x3 | Bits 0,1 at ~3.3V; Bits 2,3 at 0V | Bits 0,1 at ~5.0V; Bits 2,3 at 0V |
| 5 | 0101 | 0x5 | Bits 0,2 at ~3.3V; Bits 1,3 at 0V | Bits 0,2 at ~5.0V; Bits 1,3 at 0V |
| 10 | 1010 | 0xA | Bits 1,3 at ~3.3V; Bits 0,2 at 0V | Bits 1,3 at ~5.0V; Bits 0,2 at 0V |
| 15 | 1111 | 0xF | All 4 bits at ~3.3V (VCC) | All 4 bits at ~5.0V (VCC) |
Worked Numeric Example: 10-Bit ADC Conversion
Let's look at how the binary system works when translating the analog world into digital registers. Suppose you are using an Arduino Uno (ATmega328P) to read a temperature sensor outputting 2.1V. The Uno's default analog reference (VREF) is 5.0V, and its Analog-to-Digital Converter (ADC) has a 10-bit resolution.
A 10-bit resolution means the microcontroller divides the 5.0V range into $2^{10} = 1024$ discrete steps (numbered 0 to 1023). To find the binary value the microcontroller actually stores in its hardware registers, we calculate the decimal step first:
Decimal Value = (Input Voltage / VREF) × 1023
Decimal Value = (2.1V / 5.0V) × 1023 = 429.66
The ADC rounds this to the nearest integer: 430. Now, the microcontroller must store 430 in binary across two 8-bit hardware registers: ADCL (low byte) and ADCH (high byte). Converting 430 to a 10-bit binary string:
- $256$ (Bit 8) = 1
- $128$ (Bit 7) = 1
- $64$ (Bit 6) = 0
- $32$ (Bit 5) = 1
- $16$ (Bit 4) = 0
- $8$ (Bit 3) = 1
- $4$ (Bit 2) = 1
- $2$ (Bit 1) = 1
- $1$ (Bit 0) = 0
The resulting 10-bit binary value is 01 1010 1110. By default, the ATmega328P right-adjusts this result. The lower 8 bits (1010 1110) are stored in the ADCL register, and the remaining 2 bits (01) are padded with zeros and stored in the ADCH register as 0000 0001. If you were to read this directly via port manipulation instead of using the analogRead() function, you would have to bit-shift ADCH left by 8 and OR it with ADCL to reconstruct the 16-bit integer. (For deeper register-level details, refer to the official Arduino ADC documentation).
Where You Meet Binary in Practical Circuits
Beyond basic math, binary is the physical language of component addressing and bus communication. Here is where you will actively manipulate binary states on the jobsite or workbench:
1. I2C Addressing and the R/W Bit
When you wire up an SSD1306 OLED display, the datasheet tells you its I2C address is 0x3C. In 7-bit binary, 0x3C is 011 1100. However, the I2C protocol actually transmits an 8-bit byte. The microcontroller appends a Read/Write (R/W) bit to the end of the 7-bit address. If the ESP32 wants to write data to the display, it appends a '0', making the transmitted binary byte 0111 1000 (Hex 0x78). If it wants to read, it appends a '1', yielding 0111 1001 (Hex 0x79). This is why I2C scanner tools sometimes show addresses shifted by one bit depending on how the software library formats the output (see the NXP I2C-bus specification UM10204 for the exact protocol framing).
2. Direct Port Manipulation
If you need to toggle 8 GPIO pins simultaneously without the microsecond delay of digitalWrite(), you write a binary byte directly to the port register. On an Arduino Uno, writing PORTD = B10101010; instantly sets pins D7, D5, D3, and D1 HIGH, while pulling D6, D4, D2, and D0 LOW. This is critical in high-speed applications like driving LED matrices or generating custom RF carrier waves.
3. DIP Switches and Pull-Up Resistors
Physical binary inputs, like a bank of 4 DIP switches used to set a motor controller's baud rate, rely on hardware pull-up or pull-down resistors. If the switches connect the GPIO pins to GND when closed, you must enable internal pull-up resistors in software. A closed switch reads as a binary '0' (0V), and an open switch reads as a binary '1' (pulled up to VCC). Failing to understand this physical-to-logical inversion is a primary cause of 'my DIP switches are doing the exact opposite of what I want' troubleshooting tickets.
The Most Common Confusion: Binary Math vs. Physical Logic Levels
The most frequent mistake hobbyists make is assuming that a binary '1' always means exactly 5.0V, and a binary '0' means exactly 0.0V. In physical electronics, binary states are defined by threshold windows, not absolute voltages.
According to the Texas Instruments SN74HC00 datasheet for standard 5V CMOS logic gates, the Input High Voltage ($V_{IH}$) is guaranteed at a minimum of 3.15V, and the Input Low Voltage ($V_{IL}$) is guaranteed at a maximum of 0.9V. This means any voltage between 3.15V and 5.0V is interpreted as a binary '1'. Any voltage between 0.0V and 0.9V is a binary '0'.
Furthermore, a disconnected (floating) GPIO pin is not a binary '0'. It is a high-impedance antenna that will pick up ambient electromagnetic interference, causing the microcontroller's input buffer to rapidly toggle between binary '1' and '0'. This rapid toggling causes shoot-through current in the silicon, leading to unexplained microcontroller resets and brownouts.
Frequently Asked Questions
Why do we use 8-bit bytes instead of 10-bit or 12-bit?
While ADCs often use 10-bit or 12-bit resolutions internally, data is stored and transmitted in 8-bit bytes because $2^8$ (256) aligns perfectly with early memory addressing architectures and ASCII character encoding. Hardware designers pad 10-bit ADC readings into 16-bit (two-byte) integers for software processing because memory is byte-addressable.
Can binary represent analog signals?
Binary itself is strictly discrete, but through Pulse Width Modulation (PWM), we use binary states (rapidly switching between 0V and VCC) to simulate analog voltages. A PWM duty cycle of 50% on a 5V pin switches the binary state high and low so quickly that, when filtered through a simple RC low-pass filter, it yields a smooth 2.5V analog output.
How does binary apply to 3-phase AC power?
In industrial motor control, a Variable Frequency Drive (VFD) uses binary logic to trigger IGBTs (Insulated-Gate Bipolar Transistors). The microcontroller generates six binary PWM signals (two for each of the three phases) to synthesize a 3-phase sine wave, proving that even heavy industrial AC machinery is ultimately driven by base-2 logic gates.






