Binary is a base-2 numbering system that uses only two digits, 0 and 1, to represent all data and logic states in digital electronics. In a physical circuit, this abstract math translates directly into voltage thresholds: a logic '1' might be 3.3V, and a logic '0' might be 0V. Understanding this translation is what separates someone who just copies Arduino code from someone who can debug a frozen I2C bus with an oscilloscope. When you explain binary numbers to a fellow maker, you aren't just teaching math; you are teaching them how silicon interprets the physical world.
The Core Mechanism: Base-10 vs. Base-2
Humans use base-10 (decimal) because we have ten fingers. Each positional column is a power of 10 (1s, 10s, 100s). Digital silicon uses base-2 because a transistor only has two reliable, easily distinguishable states: fully off (cutoff) and fully on (saturation). Each positional column in binary is a power of 2.
Let's look at a worked numeric example to convert the decimal value 173 into an 8-bit binary number. We map out the powers of 2 from left (Most Significant Bit, MSB) to right (Least Significant Bit, LSB):
| Bit Position | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|
| Weight | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
| Subtract | 173-128=45 | 45<64 (0) | 45-32=13 | 13<16 (0) | 13-8=5 | 5-4=1 | 1<2 (0) | 1-1=0 |
| Binary Bit | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 1 |
The final binary string is 10101101. In C++ or Arduino IDE, you would write this as 0b10101101 or 0xAD in hexadecimal. If you send this byte to an 8-bit shift register like the 74HC595, pins Q7, Q5, Q3, Q2, and Q0 will output HIGH, while the others remain LOW.
Where You Meet This in Practice
You interact with binary numbers every time you manipulate hardware registers, configure communication buses, or set physical DIP switches. Here is where binary moves from theory to the workbench:
- GPIO Port Manipulation: Calling
digitalWrite(5, HIGH)on an ATmega328P takes roughly 50 clock cycles because the function has to parse the pin number and look up the port. WritingPORTD |= (1 << 5);directly sets the binary bit for pin D5 in a single clock cycle. This is critical for high-speed bit-banging protocols like WS2812B LED control. - I2C Addressing: Every I2C slave device has a 7-bit binary address. When the master initiates a transfer, it sends this 7-bit address followed by a 1-bit Read/Write flag, forming an 8-bit binary byte on the SDA line.
- Stepper Driver DIP Switches: Drivers like the TB6600 use physical switches to set microstepping and current limits. These switches are just physical inputs to an internal binary decoder. Setting S1=OFF, S2=ON, S3=ON might represent the binary sequence
100to the driver's logic gate, selecting 1/16 microstepping.
A binary '1' on a 3.3V ESP32 GPIO isn't exactly 3.300V. According to LVCMOS33 standards, any voltage above 2.0V is guaranteed to be read as a logic '1', and anything below 0.8V is a logic '0'. The gap between 0.8V and 2.0V is the noise margin. If your multimeter reads 1.5V on a pin that should be HIGH, your binary logic is in an undefined state and the microcontroller's behavior will be unpredictable.
Real-World Scenario Walkthrough: The I2C Address Collision
To truly explain binary numbers, we have to look at what happens when you misinterpret them in a real circuit. Here is a common bench failure involving binary address mapping.
The Setup: You are building a data logger using an ESP32 DevKit v1 and need to read 8 channels of analog sensors. Since the ESP32's internal ADC is notoriously noisy, you decide to use two external ADS1115 16-bit ADCs on the same I2C bus.
The Numbers: The first ADS1115 has its ADDR pin tied to GND, giving it the default I2C address of 0x48 (binary 1001000). The second ADS1115 needs a different address. You tie its ADDR pin to the SDA line, expecting it to take address 0x4B (binary 1001011) based on a misread forum post that assumed the addresses increment sequentially based on pin names.
The Outcome: You upload your code, but the serial monitor only shows data from the first ADC. The second ADC reads zero, and the I2C scanner sketch only finds one device at 0x48. Occasionally, the entire I2C bus locks up.
What Went Wrong: The binary address mapping for the ADS1115 ADDR pin is hardcoded in the silicon, and it does not follow a simple sequential binary count based on pin names. According to the Texas Instruments ADS1115 datasheet, the address mapping is strictly defined: GND = 0x48, VDD = 0x49, SDA = 0x4A, and SCL = 0x4B.
By tying the ADDR pin to SDA, you forced the chip's internal binary address to 0x4A (binary 1001010). However, your Arduino code was polling 0x4B (binary 1001011). When the ESP32 sent the address byte 1001011 over the bus, the second ADS1115 didn't recognize its own binary address. It remained silent, and the bus pulled high. The master eventually timed out or misinterpreted bus capacitance as a NACK (Not Acknowledged) bit, crashing the transaction. The fix was simply changing the Wire library address parameter from 0x4B to 0x4A.
Common Confusions: Binary vs. Hexadecimal vs. BCD
When people learn binary, they frequently confuse it with two related numbering formats used in embedded systems:
- Hexadecimal (Base-16): Hex is not a different physical logic state; it is simply a human-friendly compression of binary. Because 16 is a power of 2 ($2^4$), exactly four binary bits map to one hex digit. The binary string
1010 1101is much easier to read as0xAD. Microcontrollers don't "think" in hex; the compiler translates your hex back into binary before flashing the silicon. - Binary Coded Decimal (BCD): This is where hobbyists get trapped. BCD uses 4 binary bits to represent only the decimal digits 0 through 9. The binary states for 10 through 15 (
1010to1111) are considered invalid in BCD. Real-time clock (RTC) modules like the DS3231 store time in BCD. If you read the seconds register and get0x59in hex, that means 59 seconds. If you mistakenly treat0x59as pure binary/hex and convert it to decimal, your code will think it is the 89th second of the minute, breaking your time-stamp logic. You must use a BCD-to-decimal conversion function to parse it correctly.
FAQ: Binary in the Physical Circuit
What does binary actually change in a physical installation?
Binary dictates the noise margins and execution speed of your hardware. In a long wire run, a 5V binary '1' might suffer voltage drop and arrive at the receiver as 3.8V. Because the receiver's binary threshold for a '1' is typically 2.0V (for 5V TTL logic), the data survives. If you were using analog voltage levels to represent data, that 1.2V drop would corrupt the measurement. Binary makes digital circuits robust against physical degradation.
How do I verify binary logic states on a breadboard without an oscilloscope?
While an oscilloscope shows you the square wave transitions, you can verify static binary states with a standard multimeter using these steps:
- Set your multimeter to DC Voltage mode.
- Connect the black probe to the circuit's common GND rail.
- Touch the red probe to the GPIO pin or IC leg in question.
- If the reading is within 10% of VCC (e.g., ~3.2V on a 3.3V system), the binary state is HIGH (1).
- If the reading is below 0.5V, the binary state is LOW (0).
- If the reading is hovering in the middle (e.g., 1.6V), the pin is either floating, being driven by a PWM signal your multimeter is averaging, or the IC is damaged.
Why do some logic ICs use active-low binary inputs?
In many datasheets, you will see binary inputs labeled with a bar over the letter (e.g., $\overline{CS}$ for Chip Select) or a suffix like _n (e.g., RESET_n). This means the binary '0' (0V) is the active state. This is a legacy design choice from early TTL logic, where pulling a line to ground through an open-collector transistor was electrically stronger and more noise-resistant than pulling it up to VCC. Always check the truth table in the datasheet before wiring control pins.
Mastering binary numbers is the bridge between writing software and engineering hardware. Once you stop seeing 0b10101101 as just a math problem and start seeing it as eight distinct physical transistors turning on and off, debugging complex embedded systems becomes significantly more intuitive.






