Pull up resistor question

Like many others I'm in software so apologies in advance if the question sounds dumb. I watched some videos, read some articles and also read some answers here, such as: Pull-up resistor clarification but still don't quite get it.

1. When switch is open, how come the voltage at pin is Vcc. Wouldn't it drop a bit from the pull-up resistor?
2. In this example (picture 3 on the right):

Is it assumed that the MCU is also connected to ground? When the switch is closed, is the pin considered in parallel with the switch? If it's in parallel isn't voltage the same in all branches so shouldn't it be VCC at the pin as well? How come it's 0? I don't really understand how the path of least resistance relates to circuits in series and parallel and voltage.

• how can you have Vcc on a pin that is connected to GND through the switch? Commented Sep 5 at 14:19
• Codefast, I'm not intending on writing a response at this time but it is wonderful to see you asking questions like this. There are nuances and some very useful new ways to think in your question for a software person moving towards embedded programming. Step in right directions. So +1! Very nice. I hope you continue well. Commented Sep 5 at 16:39
• re. that third scenario, the linked answer should say "There's practically no voltage loss over the resistor", since there's very little current going in the input port. For most practical purposes, just forget that current even exists. Re. ground connection on the MCU, yes, you'd need that to have a common voltage reference across the different parts of the circuit. The MCU's power pin is also not shown. (I know the guy who wrote that answer, and I think he tried to give a somewhat simplified answer, perhaps glossing over some details. I'll try to see if I can get him to clarify it.) Commented Sep 7 at 8:28
• Think of R1 as a very weak spring pulling the voltage at P1 up to Vcc. Think of the switch (when operated) as a very heavy weight pulling P1 down to GND. The heavy weight always 'wins' against the spring, but without the weight the voltage at P1 'floats' up to Vcc. The purpose is to make sure that the voltage at P1 is in a known state (except for transitions, of course). Commented Sep 7 at 22:58

Look for the bold block of text near the end, for the TLDR.

This "path of least resistance" stuff drives me bonkers. There's only one way to describe this situation properly, and it's using Kirchhoff's Voltage Law (KVL), Kirchhoff's Current Law (KCL), and Ohm's law. Once you have applied and understood those, this question will never come up again. Bare with me, this will be worth it.

simulate this circuit – Schematic created using CircuitLab

Applying KCL to this is trivially simple. At junction X, current $$\I_1\$$ comes in from above, and can leave either right, $$\I_0\$$, or down, $$\I_2\$$. Just like water in a junction of pipes, what goes in must come out:

$$I_1 = I_0 + I_2$$

The MCU input has an extremely high impedance, drawing no current at all, so:

$$I_0 = 0$$

This means that $$\I_1\$$ and $$\I_2\$$ are equal:

\begin{aligned} I_1 &= I_0 + I_2 \\ \\ I_1 &= 0 + I_2 \\ \\ I_1 &= I_2 \\ \\ &= I \end{aligned}

In other words, current through those two resistors is the same, and I shall call it $$\I\$$.

Now we apply KVL, which states that the voltages across R1 and R2 must add up to equal the voltage source (power supply) Vs:

$$V_{R1} + V_{R2} = V_S$$

Using Ohm's law we can find $$\V_{R1}\$$ and $$\V_{R2}\$$:

\begin{aligned} V_{R1} = I \times R_1 \\ \\ V_{R2} = I \times R_2 \\ \\ \end{aligned}

Combining those with the KVL equation from before:

\begin{aligned} V_{R1} + V_{R2} &= V_S \\ \\ IR_1 + IR_2 &= V_S \\ \\ I(R_1 + R_2) &= V_S \\ \\ I &= \frac{V_S}{R_1 + R_2} \\ \\ \end{aligned}

Keep that last line in mind for later, we'll be using it a lot to find current in all three of your scenarios.

Lastly our output is the potential at X (also named OUT), which by KVL is higher than ground (0V) by an amount equal to the voltage $$\V_{R2}\$$ across R2:

\begin{aligned} V_{OUT} &= V_X \\ \\ &= 0V + V_{R2} \\ \\ &= V_{R2} \\ \\ &= IR_2 \\ \\ V_{OUT} &= IR_2 \\ \\ \end{aligned}

That last line is also critically important, and is directly related to your question. Maybe you see why already.

Alternatively, using KVL again, we can state that node X is lower in potential than node CC, by amount $$\V_{R1}\$$:

\begin{aligned} V_{OUT} &= V_{CC} - V_{R2} \\ \\ &= V_{CC} - IR_2 \\ \\ \end{aligned}

That's saying the same thing, really, but it will be useful when analysing your second and third scenarios.

Our super-important-equations are therefore:

\begin{aligned} I &= \frac{V_S}{R_1 + R_2} \\ \\ V_{OUT} &= IR_2 \\ \\ V_{OUT} &= V_{CC} - IR_1 \\ \\ \end{aligned}

Let's examine your first (left) scenario, replacing those two resistors with an open gap and a switch which can have 0Ω resistance, or infinity (∞Ω), depending on its state:

simulate this circuit

On the left, switch open, current $$\I\$$ and output potential $$\V_{OUT}\$$ are:

\begin{aligned} I &= \frac{V_S}{R_1 + R_2} \\ \\ &= \frac{5V}{\infty\Omega + \infty\Omega} \\ \\ &= 0A \\ \\ V_{OUT} &= IR_2 \\ \\ &= 0A \times \infty \Omega \\ \\ &= \rm{undefined} \end{aligned}

The output node OUT is just floating in space, not connected to anything. That's where we get the term "floating" from. There's no current anywhere, and no clearly defined potential at OUT, which is bad, as you noted already, but not destructive.

In practice, this floating situation turns node OUT into an antenna, which is capacitively coupled to any source of changing potential elsewhere, such as nearby digital signal lines, mains power cabling etc. That makes the potential tend to flap up and down uncontrolled, which is bad.

Above right you have this scenario, where the switch is closed:

\begin{aligned} I &= \frac{V_S}{R_1 + R_2} \\ \\ &= \frac{5V}{\infty\Omega + 0\Omega} \\ \\ &= 0A \\ \\ V_{OUT} &= IR_2 \\ \\ &= 0A \times 0\Omega \\ \\ &= 0V \\ \\ \end{aligned}

That's well defined, not problematic in any way.

simulate this circuit

This is slightly more interesting, because we can't use $$\V_{OUT}=IR_2\$$ (try it), but we can use $$\V_{OUT}=V_{CC}-IR_1\$$. On the left:

\begin{aligned} I &= \frac{V_S}{R_1 + R_2} \\ \\ &= \frac{5V}{0\Omega + \infty\Omega} \\ \\ &= 0A \\ \\ V_{OUT} &= V_{CC} - IR_1 \\ \\ &= 5V - 0A \times 0\Omega \\ \\ &= +5V \\ \\ \end{aligned}

On the right (switch closed):

\begin{aligned} I &= \frac{V_S}{R_1 + R_2} \\ \\ &= \frac{5V}{0\Omega + 0\Omega} \\ \\ &= \infty A \\ \\ \end{aligned}

Obviously that's bad, and incorrect since in reality supply impedance and wiring and switch resistance will limit maximum current, but something will break. There's no point even trying to find $$\V_{OUT}\$$.

Now the last scenario, with a resistor:

simulate this circuit

On the left, with the switch open:

\begin{aligned} I &= \frac{V_S}{R_1 + R_2} \\ \\ &= \frac{5V}{10k\Omega + \infty\Omega} \\ \\ &= 0A \\ \\ V_{OUT} &= V_{CC} - IR_1 \\ \\ &= 5V - 0A \times 10k\Omega \\ \\ &= +5V \\ \\ \end{aligned}

There it is, right there, mathematical proof that the "pull-up" resistor is causing $$\V_{OUT}=V_{CC}=+5V\$$ when the switch is open. With no current through it, that resistor has no potential difference across it. Therefore there is no difference in potential between its two ends, nodes CC and OUT.

On the right, switch closed:

\begin{aligned} I &= \frac{V_S}{R_1 + R_2} \\ \\ &= \frac{5V}{10k\Omega + 0\Omega} \\ \\ &= 500\mu A \\ \\ V_{OUT} &= IR_2 \\ \\ &= 500\mu A \times 0\Omega \\ \\ &= 0V \\ \\ \end{aligned}

Or, we get the same $$\V_{OUT}\$$ like this:

\begin{aligned} V_{OUT} &= V_{CC} - IR_1 \\ \\ &= 5V - 500\mu A \times 10k\Omega \\ \\ &= 0V \\ \\ \end{aligned}

• Thank you, really appreciate your answer. Commented Sep 5 at 21:21

When switch is open, how come the voltage at pin is Vcc. Wouldn't it drop a bit from the pull-up resistor?

You can model an MCU's input GPIO (i.e. GPIO configured as input) as a simple resistor (Note: this is for GPIO only. For ADCs it's different.):

simulate this circuit – Schematic created using CircuitLab

We can't know the exact value of this resistor. Theoretically, it's infinite; practically, it's in megaohms (can be extracted from the input currents for certain conditions).

So, your pull-up Rpu (which is usually a few kiloohms only) and this input resistance form a voltage divider whose output is quite close to the input voltage:

$$V_{GPIO}=V_{CC} \frac{R_i}{R_i+R_{pu}} \approx V_{CC}; \ \ R_i >> R_{pu}$$

1. Due to the presence of the input resistance mentioned above, it's expected to stay at logic-low (0). This also answers your question: Is it assumed that the MCU is also connected to ground?. Practically, the input is floating so it's prone to the outside world's electrical noise. If the noise is strong enough you can see random state changes. However, some MCUs have configurable (enabled/disabled by the software) internal pull-up resistor so you don't need the external pull-up Rpu. The basic idea is still the same. So if you enable the internal pull-up then you can safely do the config shown in (1).
2. If you press the button you'll short the supply. Avoid using this config.
3. This is what I tried to explain above. If you press the button you'll short the Ri resistance so the GPIO will see 0. The supply will not be shorted as in (2) because there's a resistor along the way. I thought in parallel voltage would be the same on all branches? that's true. By pressing the button you put a very low resistor (switch's resistance which can be assumed zero) in parallel with the GPIO input resistor Ri, making the effective resistor really low (theoretically zero but quite close to 0 in practice). Therefore, you can put Ri = 0 in the equation above and see the divider's output becomes zero.
• Right, thank you for your answer. Why is voltage 0 when switch is closed. I thought in parallel voltage would be the same on all branches? Commented Sep 5 at 12:57
• @codefast See my updated answer. I put further explanation in item 3. above. Commented Sep 5 at 12:58
• Got it. Thank you for the clarification. Why would Ri be 0 when I thought its very high? Commented Sep 5 at 13:10
• @codefast again, see my answer. Basically, the button is in parallel with Ri. The button exhibits infinite resistance in parallel with Ri so the effective resistance doesn't change. When the button is pressed, the effective resistance becomes zero (or close to zero) because the switch exhibits zero (or close to zero) resistance so becomes in parallel with Ri. Zero in parallel with anything is zero. So the divider can be simplified to Ri = 0. Commented Sep 5 at 13:12
• To clarify, in #2: "Avoid using" is a nice way of saying "do not use" because it will: A: trip your power supply's overcurrent protection B: brown-out systems on your board C: break your switch and/or weld it shut; or D: all of the above
– vir
Commented Sep 5 at 20:52

When switch is open, how come the voltage at pin is Vcc. Wouldn't it drop a bit from the pull-up resistor?

In theory, yes. In reality, current draw for a digital input will typically be something like 1 uA or less (at least with something like CMOS--with something like TTL, it'll be much higher, like 10 mA for "low" and 40 mA for "high--which is part of why you'd normally use a pull-down instead of pull-up with TTL). That being the case, the voltage drop is extremely minimal.

From a purely steady-state analysis, the pull-up resistor could be any value low enough that the voltage drop left the pin at a logic 1. Just to pick a concrete example, let's look at the specs in the ATmega48PB/88PB/168PB Data Sheet:

Let's assume Vcc = 3.3 volts. So, the minimum voltage we need to maintain on the input pin is 0.7*3.3 = 2.31 volts. That means the maximum voltage drop is 3.3-2.31 volts. The maximum current draw is 1 uA.

R = E/I, so the largest resistor we could tolerate would be: (3.3-2.31)/0.000001 = 990K.

Note, however, that it actually calls for a much smaller pull-up resistor (a maximum of 50K). There are a couple of reasons for that. First of all, in real life, components have tolerances, so we don't want to require a 1% tolerance on a pull-up to assure the circuit works. Second, this isn't actually a steady state circuit. Third, the input impedance isn't pure resistance (or even close to it).

As soon as something quits pulling that input low, we want it to transition to high within a single clock cycle (or actually less). From a steady state DC viewpoint, we could look at the input pin as just a resistor to ground:

simulate this circuit – Schematic created using CircuitLab

...but from an AC viewpoint with transitions between low and high voltage, it's something more like this:

simulate this circuit

Let's assume we were driving this input at 20 MHz. That means our pull-up resistor has to allow enough current to flow to charge the capacitor to a "high" voltage in less than 50 ns (we'd have to look at timing diagrams to figure out how much less, but something like a quarter to half that wouldn't be too outrageous a first guess). Unfortunately, we don't know exact values for those components, though the inductor, capacitor and R1 are all "small", and R2 is "large".

Fortunately, making the pullup resistor smaller only means that when something is pulling that input low, it'll sink more current. We just need to keep the resistor large enough to keep that current "reasonable". Even with the smallest recommended pull-up resistor (20K), with Vcc = 3.3, that current = 3.3/20K = 0.165 mA (or actually less, since what's pulling it low will also have some resistance).

1. No voltage drop because no current flows. Thus, resistance with no current drops no voltage.

2. Yes, assumption is that MCU is connected to ground in order to work at all. A MCU with only one input for pushbutton and no supply or ground pins would not make much sense. When you push the button, both button terminals short together. So if one terminal of button is 0V, pushing it makes both terminals 0V. Ideally zero ohm pushbutton will make pin 0V, becaue there is non-zero resistance to supply. You can use voltage divider equation to prove this but 0 ohms divided by 10 kohms is still 0.

• I mean, even with a reasonable leakage current into a pin - in the range of 0.1-1 µA, would only give a few mV across a 10k ohm. Commented Sep 5 at 12:49
• I think for a CMOS input a reasonable leakage at room temperature is more in the 10 nA range :D Commented Sep 6 at 7:00
• @VladimirCravero I just looked at a modern STM32 datasheet and chose a representative leakage current level range from there Commented Sep 7 at 15:37

Think of the pull up resistor as a resistor which makes the voltage at its end equal to bias voltage when the switch is open. Assuming this wire is connected to the GPIO of a MCU, the MCU sees the input voltage as high (5V or 3.3V or anything else) digital input. When the switch is closed, current flows through the circuit and voltage at the end of pull up resistor is much lower than the bias voltage. and hence the GPIO reads the input as digital low.

Here is a schematic of a GPIO pin a typical MCU.

Source: MSP430FR2676: GPIO Block Diagram at https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/975583/msp430fr2676-gpio-block-diagram