Home/Blog/Logic Levels & Electrical Signals - How Bits Become Voltage
March 30, 2026
9 min read
6 views
πŸ‡ΊπŸ‡Έ English

Logic Levels & Electrical Signals - How Bits Become Voltage

Before any protocol can work, bits must become voltages. Learn about 3.3V vs 5V logic, signal integrity, pull-up resistors, and level shifting.

EmbeddedElectronicsSPII2CCANUARTRS-485Protocols
Published in Technology
Logic Levels & Electrical Signals - How Bits Become Voltage

Logic Levels & Electrical Signals. How Bits Become Voltage

Before UART, SPI, I2C, or any other protocol matters, there's something more fundamental: a wire is either at a high voltage or a low voltage. That's it. Everything else is built on top of that physical reality.

This sounds obvious until you connect a 5V Arduino to a 3.3V ESP32 for the first time. If you're lucky, nothing happens. If you're less lucky, you've just killed an input pin. sometimes the whole chip. So let's get this layer right before moving up.


What a Logic Level Actually Is

A logic level isn't a single voltage. it's a range. A system reads anything in the HIGH range as a 1, anything in the LOW range as a 0, and anything in between as... undefined. That middle zone exists on purpose; it's the noise margin.

SystemLogic LOWLogic HIGHSupply
5V TTL0. 0.8 V2.0. 5.0 V5 V
3.3V CMOS0. 0.8 V2.0. 3.3 V3.3 V
1.8V CMOS0. 0.35 V1.17. 1.8 V1.8 V
code
5.0 V  ─ ─────────────── HIGH valid zone
2.0 V  ─ - - - - - - - - HIGH threshold
       β–‘  ← don't go here
0.8 V  ─ - - - - - - - - LOW threshold
0.0 V  ─ ─────────────── LOW valid zone

Notice that 3.3V CMOS outputs can drive 5V TTL inputs just fine. 3.3V sits well inside the HIGH valid zone for 5V TTL (which only requires 2.0V minimum). The reverse doesn't work: a 5V output driving a 3.3V input sends it straight past its maximum rated voltage.


Pull-up resistors. and why the value matters more than you'd expect

Some bus lines are open-drain: the chip can only pull the line LOW, never actively drive it HIGH. I2C is the classic example. A pull-up resistor sits between the supply and the line, providing the default HIGH state passively.

mermaid
Rendering diagram...

The resistor value is not arbitrary. Pick it too small. say 100Ξ©. and you're burning 33mA every time the line is pulled low. Pick it too large. 100kΞ©. and the rise time becomes so sluggish that edges blur into each other at any real speed. For I2C at 100kHz, 4.7kΞ© is the standard. At 400kHz, come down to 2.2kΞ©. At 1MHz, 1kΞ© or lower.

I've seen I2C buses that "almost work" at 100kHz with a 10kΞ© pull-up. it looks fine on the logic analyser until the PCB gets warm and the stray capacitance increases slightly. Then it stops working. The correct pull-up fixes it permanently.


Signal integrity. what happens at speed

Even a 5cm PCB trace has resistance, capacitance, and inductance. At low speeds (UART at 9600 baud) none of this matters. At SPI running at 40MHz, it can mean the difference between a working board and one that fails intermittently.

code
Ideal edge        Real edge on a long trace

1 ─┐              1 ─┐~~_
   β”‚                  β””~~~
0 β”€β”˜              0 ──────
                       ↑ ringing. that dip can look like a spurious LOW

Short lines, matched impedance (50Ξ© is typical for PCB traces), and a small series resistor (33–100Ξ©) near the driver output all help. The series resistor damps the ringing without affecting the steady-state voltage.


Mixing 3.3V and 5V devices

The safest approach is to never do it. In practice you usually have no choice. There are three real options:

  • Resistor divider: works fine for a unidirectional signal where you're stepping 5V down to 3.3V. Fast, cheap, zero components. But it's passive, so you can't use it on bidirectional lines.
  • MOSFET-based shifter (BSS138 circuit). handles bidirectional lines like I2C. Works well up to a few hundred kHz.
  • Dedicated level-shift IC (TXS0102, TXB0108). faster and more reliable for SPI and anything above 1MHz. Costs a bit more.
mermaid
Rendering diagram...

Don't skip this step. The "it works on my desk" phase of a direct 5V→3.3V connection sometimes lasts for months before it starts causing bit errors or silently damages the input ESD structure. By then you've forgotten you ever did it.

Getting the physical layer right isn't glamorous, but every debugging session that starts with "SPI randomly drops bytes" or "I2C freezes after a few minutes" is really a symptom of something broken at this level.

Last updated: July 9, 2026

Get notified of new posts

No spam, unsubscribe anytime.