JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

Logic Levels, Open-Drain, and Pull-Ups

A comparator gives a clean yes-or-no, but a digital chip only believes certain voltages. This guide pins down what a 1 and a 0 really are, the noise margin that protects them, how to shift between the 5 V and 3.3 V worlds, and the quietly brilliant open-drain output whose missing half you supply with a single pull-up resistor.

What a 1 and a 0 really are

In guide 1 the comparator slammed its output toward one rail or the other the instant its inputs crossed, and in guide 2 the Schmitt trigger gave that swing a deadband so it snapped cleanly instead of chattering. Now the output has to talk to a digital chip — and here is the first surprise: a digital input does not look for one exact voltage. It reads a whole band of voltages as a 1, another band as a 0, and treats a no-man's-land between them as undefined.

From the input's point of view there are two thresholds. Any voltage above VIH (the input-high threshold) is guaranteed to be read as a 1; anything below VIL (the input-low threshold) is guaranteed a 0. The span between VIL and VIH is the forbidden zone — feed a voltage in there and the chip may decide either way, may wobble, or may even oscillate. These bands are what we mean by logic levels, and they are exactly why a slow, drifting edge is dangerous: it loiters in the forbidden zone, the very problem the Schmitt trigger's hysteresis was built to fix.

Noise margin: the moat around each level

The trick that makes digital robust is that the output side over-delivers. A driving gate promises that its 1 will sit no lower than VOH (which is above VIH) and its 0 no higher than VOL (below VIL). The gap between what is sent and what is merely required is the noise margin — the moat around each level. Spelled out: the high-side margin is NMH = VOH - VIH, and the low-side margin is NML = VIL - VOL. Any noise spike smaller than the moat lands harmlessly; the receiver still reads the right bit.

Put numbers on two classic families. Old bipolar TTL guarantees VOH = 2.4 V, VIH = 2.0 V, VOL = 0.4 V, VIL = 0.8 V, so both moats are a thin NMH = 2.4 - 2.0 = 0.4 V and NML = 0.8 - 0.4 = 0.4 V. A 5 V CMOS gate rails almost fully: VOH ~= 4.95 V, VIH ~= 3.5 V, VOL ~= 0.05 V, VIL ~= 1.5 V, giving fat moats of about 1.45 V on each side. That difference is enormous in practice: a half-volt of ground bounce or coupled crosstalk that CMOS shrugs off would flip a TTL gate straight through its 0.4 V margin.

This is why family matters when chips talk to each other. CMOS draws essentially no static input current and swings nearly rail-to-rail, so it is both low-power and generous with noise margin; older bipolar logic sinks real input current and lives with thin margins. The catch comes at the boundaries — a CMOS output may not meet a TTL input's current needs, and worse, two parts on different supply rails may not agree on where the thresholds even are. That mismatch is the whole reason for the next idea.

Level shifting between voltage worlds

A modern board is a patchwork of rails — a 5 V sensor here, a 3.3 V microcontroller there, a 1.8 V processor core deeper in. You cannot just wire them together. Drive a 5 V signal into a 3.3 V input and you may push it past its absolute-maximum rating, forcing current backward through its on-chip protection diodes and slowly cooking the pin. Go the other way and a 3.3 V high might not even clear a 5 V part's VIH. Bridging these domains safely is level shifting.

For a slow signal going down (5 V to 3.3 V) a plain voltage divider is enough: pick R1 = 1 k on top and R2 = 2 k to ground and the output is 5 times 2/(1+2) = 3.33 V — comfortably a valid 3.3 V high. But a divider is one-directional, wastes a trickle of current, and the chip's input capacitance plus those resistors form a low-pass that smears fast edges. Going up (3.3 V to 5 V) a divider cannot help at all — you need active lifting.

The workhorse for both directions is the single MOSFET level shifter: one small N-channel transistor with its gate tied to the lower rail (3.3 V), and a pull-up on each side to its own rail. When the 3.3 V side is pulled low, the MOSFET turns on and drags the 5 V side low too; when the 3.3 V side floats high, the MOSFET stays off and the 5 V side's pull-up lifts it cleanly to 5 V. It is bidirectional, fast enough for buses, and — notice — it is really just a transistor that can only pull down plus a resistor that pulls up. Hold that picture; it is exactly the circuit the rest of this guide is about.

Open-drain and the pull-up resistor

Most outputs you have met are push-pull (or totem-pole): a transistor on top to actively pull the line high and one on the bottom to actively pull it low, firmly driving both directions. An open-drain output throws away the top transistor and keeps only the bottom one. It has just two moves: pull the line hard to ground, or let go entirely and float. It can drive a 0; it can never drive a 1. (Built from a bipolar transistor the same idea is called open-collector — the LM393 comparator from guide 1 has exactly this kind of output, which is why its swing was never a clean logic high on its own.)

The missing half is your job, and it is one resistor: a pull-up resistor from the line to whatever rail you choose. Whenever no transistor is pulling down, the pull-up gently lifts the line to a high. This buys two lovely things. First, you pick the high voltage by picking the pull-up rail — so an open-drain output is a built-in level shifter: tie a 5 V comparator's open-collector output through a pull-up to your 3.3 V rail and out comes a clean 3.3 V logic high, no extra parts. Second, it lets several outputs share one wire — which is the next trick.

            +3.3 V  (or +5 V -- your choice sets the HIGH level)
              |
             | |   pull-up R   (you add this)
             | |
   shared     |
   line  o----+------+------+------+----->  to logic input(s)
                     |      |      |
                   |/     |/     |/    three open-drain outputs:
               ----|   ---|   ---|     each is a bottom NMOS that pulls
                   |>     |>     |>    the line to GND, or floats (off).
                     |      |      |
                    GND    GND    GND

   All transistors OFF   -> pull-up R lifts the line HIGH.
   ANY one transistor ON -> the line is yanked LOW  (wired-OR, active low).
Open-drain outputs sharing one pull-up. Each output is only a bottom transistor to ground; the single pull-up supplies every high. The line is high only when all transistors are off, and any one of them can pull it low.

Sizing the pull-up, and wired-OR

Sizing that one resistor is a real design choice — a tug-of-war captured by its RC time constant. Make it too large and the line rises sluggishly, because the pull-up has to charge the bus capacitance through a big resistor; make it too small and it burns current continuously while the line is low, and the bottom transistor may not be able to sink enough to hold a valid VOL. The honest design walks between those two walls:

  1. Find R_min from the sink current. The bottom transistor must hold the line below VOL while sinking R's current. On a 3.3 V rail with a 3 mA sink budget at VOL = 0.4 V, R_min = (3.3 - 0.4)/0.003 ~= 1 k — never go below this.
  2. Find R_max from the rise time. The line climbs through RC against the bus capacitance; the 10-to-90 percent rise is about 2.2 times R times C. With C = 100 pF and a 1 us rise budget, you need R below roughly 4.5 k.
  3. Pick inside the window. For a 100 kHz I2C bus, 4.7 k sits right in it: tau = 4.7 k times 100 pF = 470 ns, a rise of about 1 us, and only 3.3/4.7k ~= 0.7 mA of pull-down current. For a 400 kHz bus the rise budget shrinks to 300 ns, so drop to about 1.8 k.
  4. Respect the tradeoff. Smaller pull-ups mean faster, more noise-immune lines but more current and sharper edges; larger pull-ups mean lower power but slower, softer transitions. There is no single right value — only the right value for your speed and power budget.

Now the payoff of sharing a wire. Tie several open-drain outputs to one pull-up and the line floats high only when every transistor is off; the instant any one turns on, it yanks the whole line low. With active-low signalling that reads as 'any device may assert the line' — which is wired-OR logic done with nothing but transistors and a resistor. It is how a shared interrupt line, an I2C or 1-Wire bus, and many 'data ready' signals work. You could never do this with push-pull outputs: one driving high while another drives low is a direct short from rail to ground — bus contention that overheats both drivers. Open-drain makes sharing not just possible but safe.

Why mixed-signal is genuinely hard

End on an honest note, because this rung's whole reason to exist is that putting fast digital next to sensitive analog on one board is hard. Every clean logic edge is a step of volts in a nanosecond or two, and that steepness is itself a noise source. The fast dV/dt drives current spikes through every stray capacitance, and the fast di/dt in the return path drops voltage across trace inductance — the infamous ground bounce. Those spikes do not stay polite: they land on your comparator's reference, your ADC's input, your sensor's tiny millivolt node, exactly where you can least afford them.

The defenses are the subject of the next rung, but the headline habits are simple. Put a decoupling capacitor right at every chip's supply pin — a local tank so the long power trace never sags when the chip gulps current on an edge. Give the board a solid ground plane and keep noisy digital return currents out of the quiet analog ground. Physically separate the analog and digital sections. And do not make any edge faster than it needs to be — a slow signal that still meets timing is a quiet signal.