UNIT 01 · LESSON 3 OF 6

Resistors, Pull-Ups, and Pull-Downs

Why a resistor limits current, why an unconnected input has no defined value, and how a pull-up or pull-down gives a button a default state without wasting power.

INTERACTIVEA button with a pull resistor
Button input with a pull resistor to the microcontrollerVDD = 3.3 VR10 kΩSW1openMicrocontrollerGPIOinputreads HIGH3.3 Vno current: the node just sits at its default level
Button input with a pull resistor to the microcontrollerVDD = 3.3 VR10 kΩSW1openMicrocontrollerGPIOinputreads HIGH3.3 Vno current: the node just sits at its default level

Try this

Markers show the pressed-state current path; they are conceptual, not a measurement.
Pull-up, R = 10 kΩ, button open → node at 3.3 V, input reads HIGH (active-low). Current through R while pressed: I = VDD / R = 330 µA, P = I²R = 1.09 mW.

The resistor gives the input a definite level while the button is open; the button forces the other level when it is pressed. With a pull-up the pressed state reads LOW (active-low). With a pull-down it reads HIGH (active-high). Current only flows through the resistor while the button is pressed. Idealised: switch resistance zero, input leakage ignored.

What you will be able to do
  • Explain what a resistor does in a circuit and calculate the current it allows.
  • Describe why a floating input is undefined and what physically sets its voltage.
  • Wire a button with a pull-up or a pull-down and predict the logic level in both switch positions.
  • Distinguish active-low from active-high signals and read either correctly in firmware.
  • Choose a pull resistance by weighing current, leakage sensitivity and rise time.
Before you start
  • Ohm’s law and the closed loop (lesson 1).
  • VIL, VIH and the undefined band (lesson 2).
Steps in this lesson
  1. What a resistor does
  2. The floating input
  3. Pull-up and pull-down
  4. Worked example: current, power and the level
  5. The trade-off
  6. Internal pull resistors
  7. Drawing it correctly
  8. Common misconceptions

The puzzle

You wire a push button between a microcontroller pin and ground, write if (pin_is_low) …, and it works, sometimes. Left alone, the pin reports presses that never happened, or nothing at all, or something that changes when you bring your hand near the board. The missing part costs a fraction of a cent: a resistor. This lesson is about why it is there and how big it should be.

STEP 1

What a resistor does

A resistor is a component that obeys Ohm’s law on purpose: put a voltage VV across it and exactly I=V/RI = V/R flows, no more. That makes it the tool for limiting current. Put 3.3 V across a bare wire and the current is limited only by the supply’s ability to deliver it; put 3.3 V across 10 kΩ and the current is 330 µA, full stop.

The other thing a resistor does is set a default. Connect one end to a known voltage and the other end to a node with nothing else pulling on it, and that node drifts to the known voltage. Almost no current flows, because nothing is drawing any, but the connection is enough to hold the node in place. That second job is what pull-ups and pull-downs do.

STEP 2

The floating input

DIAGRAMA floating input has no opinion
An unconnected input pin: stray capacitance, leakage and coupling from a neighbouring traceMCUGPIOinputreads ?nothing connected herestraya few pFleakageMΩneighbouring trace, togglingcoupling
An unconnected input pin: stray capacitance, leakage and coupling from a neighbouring traceMCUGPIOinputreads ?nothing connected herestraya few pFleakageMΩneighbouring trace, togglingcoupling
No defined path sets the level. Stray capacitance, leakage and coupling decide, and none of them is under your control.

An input pin with nothing connected is a tiny capacitor, a few picofarads, joined to the rest of the world only by leakage paths of many megohms (drawn dashed). Whatever charge it happens to hold sets its voltage, and a neighbouring switching trace, a finger or humidity nudges it. It may sit steady for minutes or drift through the undefined band; either way your circuit does not define the reading.

A digital input is designed to draw as little current as possible: the RP2040 and ATmega328P datasheets both specify at most 1 µA of leakage. That is a virtue when the pin is driven, and a problem when it is not. With nothing connected, the pin is a tiny capacitor, a few picofarads, joined to the world only by leakage paths of megohms. Whatever charge it happens to hold sets its voltage. A neighbouring trace that toggles couples a little charge across; a finger nearby changes the capacitance; humidity changes the leakage.

The pin might sit at a clean 0 for an hour and then start reading 1. It might hover in the undefined band. It might follow your hand. None of that is “random toggling” in any predictable sense; it is simply not defined by anything you built. The fix is to define it.

STEP 3

Pull-up and pull-down

↑ This step uses the figure at the top of the page.

A pull-up is a resistor from the input node to the supply, with the button from the node to ground. Button open: nothing draws current through the resistor, so the node sits at the supply voltage and the input reads HIGH. Button pressed: the switch ties the node to ground; now the full supply voltage sits across the resistor, I=VDD/RI = V_{DD}/R flows through it into the switch, and the input reads LOW. The pressed state is the low one, so the signal is active-low.

A pull-down is the mirror image: resistor to ground, button to the supply. Open reads LOW, pressed reads HIGH: active-high.

Both are correct. Pull-ups are more common for buttons for practical reasons: many chips have internal pull-ups available on every pin, an open-drain output can share the same net, and a switch to ground is easy to route. What matters is that firmware and hardware agree on which level means “pressed”. An active-low button read as if it were active-high inverts every press and release.

STEP 4

Worked example: current, power and the level

With a 3.3 V supply and a 10 kΩ pull-up, the button is held for one second. How much current flows, and how much power does the resistor dissipate?

I=VDDR=3.3 V10 000 Ω=330 μAI = \frac{V_{DD}}{R} = \frac{3.3\ \text{V}}{10\,000\ \Omega} = 330\ \mu\text{A} P=V⋅I=3.3×0.00033=1.1 mWP = V \cdot I = 3.3 \times 0.00033 = 1.1\ \text{mW}

Negligible heat, and 330 µA is trivial next to a running microcontroller. But suppose the product sleeps at 5 µA and a lid switch is held closed for its entire life in the closed position: 330 µA through the pull-up would dominate the battery budget by a factor of sixty. That is when a 100 kΩ or 1 MΩ pull-up, or a pull-down arranged so that the usual state draws nothing, earns its place.

Now the level with leakage. If the input leaks 1 µA toward ground while the button is open, the pull-up drops 1 μA×10 kΩ=101\ \mu\text{A} \times 10\ \text{k}\Omega = 10 mV, leaving 3.29 V: still a solid HIGH. With a 1 MΩ pull-up the same leakage drops 1 V, leaving 2.3 V, which is above the 2.0 V VIHV_{IH} of a typical 3.3 V input but with far less margin, and a damp or contaminated board with 10 µA of leakage would drag it into the undefined band.

STEP 5

The trade-off

INTERACTIVEChoosing the pull resistor: three things that move together
Pull resistor trade-offs: pressed current, rise time and leakage droop against resistance1 kΩ10 kΩ100 kΩ1 MΩ1 µA10 µA100 µA1 mA10 mAPull resistanceCurrent while pressed330 µA1 kΩ10 kΩ100 kΩ1 MΩ10 ns100 ns1 µs10 µs100 µs1 ms10 msPull resistanceRise time 10–90 % (2.2·R·C)1.1 µs1 kΩ10 kΩ100 kΩ1 MΩ00.823.3Pull resistanceVoltage with leakageundefinedreads HIGH3.29 V
Pull resistor trade-offs: pressed current, rise time and leakage droop against resistance1 kΩ10 kΩ100 kΩ1 MΩ1 µA10 µA100 µA1 mA10 mAPull resistanceCurrent while pressed330 µA1 kΩ10 kΩ100 kΩ1 MΩ10 ns100 ns1 µs10 µs100 µs1 ms10 msPull resistanceRise time 10–90 % (2.2·R·C)1.1 µs1 kΩ10 kΩ100 kΩ1 MΩ00.823.3Pull resistanceVoltage with leakageundefinedreads HIGH3.29 V
R = 10 kΩ: pressed current 330 µA; rise time with 50 pF ≈ 1.1 µs; with 1 µA of leakage the open-button level sags to 3.29 V (still a clear HIGH for a 2.0 V threshold).

A smaller resistor wastes more current whenever the button is held, but recharges the pin faster and shrugs off leakage. A larger resistor saves power but lets small leakage currents drag the level, and with the pin and wiring capacitance it makes a slower edge. Rise time here is the 10–90 % time of an RC edge, 2.2·R·C. The leakage model is a constant current sink while the node remains positive; values clamped at 0 V indicate model saturation, not a predicted real voltage.

Three things move together when you change the resistor:

  • Current while pressed falls as RR rises. Smaller resistors waste more power whenever the button is held.
  • Sensitivity to leakage grows with RR. The level droops by Ileak⋅RI_{leak} \cdot R, so a large pull-up on a leaky node loses its margin.
  • Rise time grows with RR. When the button releases, the resistor has to recharge the pin capacitance and whatever wiring hangs on the node. Treated as an RC edge, the 10–90 % rise time is about 2.2 R C2.2\,R\,C. With 50 pF and 10 kΩ that is 1.1 µs, irrelevant for a button. With 1 MΩ and a long cable at 1 nF it is 2.2 ms, long enough to matter, and a slow edge is exactly what makes a plain input flicker.

Values from 4.7 kΩ to 100 kΩ cover most button and signal uses, and the choice is rarely critical for a button. It becomes critical on a shared bus. The I²C specification sizes its pull-ups by exactly this trade-off: the smallest value comes from the output’s ability to sink current, Rp(min⁡)=(VDD−VOL(max⁡))/IOLR_{p(\min)} = (V_{DD} - V_{OL(\max)}) / I_{OL} with VOL≤0.4V_{OL} \le 0.4 V at 3 mA, and the largest comes from the rise-time limit against the bus capacitance, Rp(max⁡)=tr/(0.8473 Cb)R_{p(\max)} = t_r / (0.8473\, C_b). At 3.3 V, 400 pF and a 300 ns Fast-mode rise time, that range is roughly 970 Ω to 885 Ω, which does not even overlap, so these assumed sink-current and capacitance limits leave no valid resistor range; stronger guaranteed sink capability or lower bus capacitance changes the result. The same formula tells you why a short, low-capacitance bus tolerates a lazy 10 kΩ pull-up and a long one does not.

STEP 6

Internal pull resistors

Most microcontrollers can enable a weak pull-up or pull-down inside the pin. The datasheets quote a range, not a value: 50–80 kΩ for the RP2040, 20–50 kΩ for the ATmega328P. That is fine for a button on the same board and often saves a part. It is a poor choice when the node is long or noisy, when the level must be defined before firmware has run (reset defaults and boot-time configuration depend on the particular pin and device), or when you need a known resistance for a bus. In those cases, fit an external resistor.

STEP 7

Drawing it correctly

DIAGRAMConnected or just crossing?
Wire crossings versus junction dotsCrossing, not connectedno dotT-junction: connecteddot at the joinFour wires: stagger themtwo clear junctions
Wire crossings versus junction dotsCrossing, not connectedno dotT-junction: connecteddot at the joinFour wires: stagger themtwo clear junctions
Dot = connected. No dot = crossing. Never four wires on one dot.

A dot means the wires join. No dot at a crossing means they pass over each other without touching. To avoid any doubt, good schematics never put four wires through one dot; they stagger the two junctions.

Pull-ups create junctions: the resistor, the switch and the pin all meet at one node. On a schematic, a dot marks that the wires join; two wires that cross without a dot do not touch. Careful drawings avoid four wires meeting in one dot, because a missing dot at such a crossing would be invisible; they stagger the two junctions instead. When you read a schematic, the dots are where the current can split, and the pull-up node is the first place to check that the button, the resistor and the pin are really on the same net.

MYTHS AND FACTS

Common misconceptions

A floating input toggles randomly

It is undefined: it may be steady, may drift, may follow a hand. The lesson is not that it is noisy but that nothing you built determines it.

Pull-ups are for buttons only

Any input that can be left undriven needs one: reset lines, chip-select lines, open-drain buses, unused inputs.

Bigger is always better because it saves power

Bigger also means more leakage sensitivity and slower edges. Pick the largest value that still gives you margin and speed.

The internal pull-up is a 47 kΩ resistor

It is a range that may span more than 2:1. Its reset state is device- and pin-specific; some pins have a pull enabled by default.

Active-low means the signal is broken or inverted

It is a convention: pressed = LOW. Read the schematic, then write the comparison to match.

Check yourself

Answer in your head, then open the card.

A 5 V system uses a 4.7 kΩ pull-up on a button. What current flows while the button is held, and what does the pin read?

I=5/4700≈1.06I = 5 / 4700 \approx 1.06 mA through the resistor and the switch. The pin is tied to ground by the switch, so it reads LOW (active-low).

The same button is rewired as a pull-down. What changes in the firmware?

The idle level is LOW and the pressed level is HIGH. The comparison inverts: pressed means the input reads 1. The current while held is the same 1.06 mA, now flowing from the supply through the switch and the resistor to ground.

A 1 MΩ pull-up holds an input that leaks 2 µA. Is the idle level still a guaranteed HIGH for a 3.3 V input with VIH = 2.0 V?

The droop is 2 μA×1 MΩ=22\ \mu\text{A} \times 1\ \text{M}\Omega = 2 V, leaving 1.3 V: inside the undefined band. Not guaranteed. Use a smaller pull-up or reduce the leakage.

Why can an internal pull-up not be relied on to hold a chip’s enable pin in a safe state at power-up?

Check the reset-state table and power-up behavior first: some internal pulls are enabled at reset, others are not. RP2040 ordinary GPIO pads, for example, reset with a pull-down enabled (PADS_BANK0 register description, §2.19.6). An external resistor is useful when the required default must be independent of firmware and the internal reset configuration.

Sources (4)
  1. Raspberry Pi Ltd, RP2040 Datasheet (build 2025-02-20), Table 625, pp. 615–616 — internal pull-up and pull-down resistance 50–80 kΩ; input leakage up to 1 µA
  2. Microchip, ATmega328P Data Sheet DS40002061B (Rev. B, 08/2020), Table 30-1, pp. 322–323 — I/O pin pull-up resistor RPU 20–50 kΩ; input leakage IIL and IIH up to 1 µA at VCC = 5.5 V
  3. NXP, UM10204 “I²C-bus specification and user manual”, Rev. 7.0 (1 October 2021), §7.1 “Pull-up resistor sizing”, p. 50; Tables 9 and 10 — Rp(min) = (VDD − VOL(max)) / IOL with VOL ≤ 0.4 V at 3 mA; Rp(max) = t_r / (0.8473 · Cb); rise time ≤ 1000 ns (Standard-mode) and ≤ 300 ns (Fast-mode); bus capacitance ≤ 400 pF
  4. Tony R. Kuphaldt, Lessons in Electric Circuits, Vol. I (DC), ch. 2 “Ohm’s Law” — current limiting with a series resistor follows directly from I = E/R