Electronic – What are the mechanisms at work in a pull-up or pull-down resistor circuits with a push-buttons and a GPIO

buttongpioinputresistors

I have a question regarding the GPIO (from a Arduino board for example). How does it work exactly when you use it as an input pin? What are the mechanisms at work when you use it in a pull-up and pull-down resistor circuits with an push-buttons? I have read a few tutorials but they don’t give a deep explanation of the mechanisms, or I completely missed the points they were making. Most tutorials say things like (in a pull-up example), “When the button is pressed, it connects the input pin directly to ground. The current flows through the resistor to ground, thus the input pin reads a low state” (https://learn.sparkfun.com/tutorials/pull-up-resistors ). But in a pull-down resistor circuits with push-buttons, the input pin is also connected to ground when the button is pushed and the input is high in that case.

Also a baseline explanation would not work seem to work, because in case of a the pull-up example how does it know what the high/low value is when you have pushed in the button before connecting the power supply.
Even a threshold explanation doesn't seem to explain it entirely, the voltage on the circuit as a whole seems to me to be above 2.5 V in both pushed and non-pushed state, when a 5V Vcc and 10kOhm resistor is used or is there an error in my thinking about this?

Explanations of electrodes that only travel through the pathway of least resistance also does seem to be right. Even if this was true this doesn’t explain the behaviour in the pull-down circuit, because there would never be any input when you would connect a 10 kOhm resistor to the ground (before the push button). Since this is lower than the impedance of the input pin (100k-1MΩ). Components divide the current according to their reciprocal resistances (I1 / I2 = R2 / R1). You can even see it when you connect a LED to the ground site of the circuit, which is on when you push the button and the input reads HIGH.
Does in the pull-up case I1 / I2 = R2 / R1 explain the behavior, because there is no resistor in parallel to the resistor of the GPIO and because the connection where no resistor is present the resistance is neglectable (at least over a short distance), all current flow goes to the ground directly?

It seem to me it got something to do with the fact that the connection that has no resistor between the input pin (and the ground or power supply pin) determines the state when both have a closed circuit with it. But what is the mechanism. Does the GPIO unit (in input state) contain a sort of capacitor that “transmits” the charge to the power supply when it is directly connected to it (larger pull with larger voltage), and contains the charge longer (or replaced charge quicker) when it is directly connected to ground, and so influences the internal circuit? Or does it have something to do with the potential difference between the sides of a resistor, and if so how does the input pin read this?

I understand the fact that in you use a ground connection to the input pin (in a pull-down circuit) because otherwise the input pin would be influenced by noise (static) and a resistor because otherwise there would be a direct connection between the Vcc and ground, and this would result in a short circuit. So this part can be skipped in the answer. Of course you can add this in your answer for other users looking for an answer regarding this.

I hope that somebody can give me an (in-depth) explanation of how these circuits work.

Best Answer

A GPIO pin, when in INPUT mode, can be thought of as a very very large resistor connected to ground. The GPIO pin is interested in the voltage that is across this resistor. Take the following circuit for example:

schematic

simulate this circuit – Schematic created using CircuitLab

A logic HIGH is seen by the Arduino when the voltage at the node labelled GPIO is at, or near, \$V_{CC}\$ (in this case 5V). A LOW is seen when the voltage at GPIO is at or near \$0V\$.

With the switch SW1 open, there are just the two resistors in play - the pull-up, and the internal GPIO port's resistor. So, using simple maths, we can calculate the voltage that would be at GPIO.

First we calculate the ratio of the two resistors, using \$\frac{R2}{R1 + R2}\$, and then multiply it by the voltage, which is \$5V\$. So we have the sum:

$$ \frac{10,000,000}{10,000 + 10,000,000}×5 $$

We can of course simplify that by doing the addition, then cancelling out trailing zeros above and below the line:

$$ \frac{10,000,000}{10,010,000}×5 $$ $$ \frac{1,000}{1,001}×5 $$

And so the answer comes out as \$4.995V\$ - pretty much the full \$5V\$. So the Arduino see that as being HIGH, since it is above its "input logic high threshold", also known as \$V_{IH}\$ in datasheets.

So now what happens when we press the button? Well, basically we create a short circuit across the internal GPIO resistor. So now we can completely ignore that resistor, since we have essentially put a wire across it to short circuit it.

So now our sum gets changed slightly, since \$R2\$ is now \$0\Omega\$ (the resistance of the wire shorting out \$R2\$).

$$ \frac{0}{0 + 10,000}×5 = 0V $$

And of course, \$0V\$ is below the "input logic low threshold", or \$V_{IL}\$.

Another way of looking at it is that the GPIO, when the button is pressed, is directly connected to ground. No amount of tweaking of the resistor \$R1\$ will ever change the fact that the voltage at ground is \$0V\$. The only way you can change that is by short circuiting \$R1\$ so that becomes \$0\Omega\$ as well, and then you have basically short circuited your battery, and all your wires have now melted.

For reference, here is part of Table 28.2 from the ATMega328P data sheet detailing the input voltage thresholds:

enter image description here

We can see there the \$V_{IL}\$ and \$V_{IH}\$ voltages for the \$2.4V - 5.5V\$ \$V_{CC}\$ range listed as \$0.3V_{CC}\$ and \$0.6V_{CC}\$ respectively. Now, this doesn't refer to \$0.3V\$ and \$0.6V\$, but to \$0.3×V_{CC}\$ and \$0.6×V_{CC}\$.

If \$V_{CC}\$ is \$5V\$, then \$V_{IL}\$ is \$0.3 × 5 = 1.5V\$, and \$V_{IH}\$ is \$0.6 × 5 = 3V\$.

So any voltage seen on the GPIO pin that is below \$1.5V\$ is registered as a logic LOW, and any voltage see that is above \$3V\$ is registered as a logic HIGH.