Working a lot with Raspberry Pi and Arduino stuff lately. The concept of pull-up and pull-down resistors came up quickly and confused me a little at first. So I thought I’d do a little demo of how they work and why they are needed. Doing this helped to clarify it for me, so maybe it’ll help you too.
Common scenario. You want to set up something that reads an input of a GPIO pin. Say, you want to know when the user is pressing a switch. You set up a simple circuit like so:
And here that is wired up:
When you press the button, pin 25 goes high. No press, no high, must be low, right? Well, let’s see…
We’ll set up a simple Python script to read the status of pin 25:
#! /usr/bin/python import RPi.GPIO as GPIO import time PIN = 25 GPIO.setmode(GPIO.BCM) GPIO.setup(PIN, GPIO.IN) while True: if GPIO.input(PIN) == GPIO.HIGH: print("pin is high") time.sleep(.1) else: print("pin is low") time.sleep(.1)
When I run this, I get 20-30 lines saying pin 25 is high, then 20-30 saying it’s low, back and forth, without touching the button. Sure enough when I press the button, it stays high, but apparently the definition of “low” is not “not high”.
After too many years in the highly binary world of software programming, some of us delving into hardware may be surprised to learn that a lot of electronics operate on “tri-state logic” as opposed to simple binary. Here, an input can be high, low, or floating. In this particular circuit, high means connected to 3.3 volts, low means connected to ground, and floating means… neither or somewhere in between. Actually, due to the sensitive nature of tiny electronics, system components can pick up various signals that create slight fluctuations in what it is reading. It’s rarely if ever going to pick up exactly 0.000 volts just because it’s not connected to 3.3 volts.
So we need to force the issue and say, “Yo! You are LOW!” My first thought on how to do this would probably have been to do something like this:
When the switch is in one position, pin 25 is connected directly to ground, sending it solidly low. When the switch is changed, it connects 25 to 3.3 volts, making it high. This will work just fine, but it’s a bit overengineered as it turns out.
How about if we go simpler and just connect pin 25 to ground and leave it that way, like so:
(Note: DO NOT ACTUALLY BUILD THIS CIRCUIT!)
Now, when the switch is open, pin 25 is undoubtedly low. But we have a problem that when you do hit the switch, you now have a short circuit directly between 3.3 volts and ground. Not good. Again, do not do this. The solution? Throw a resistor in there:
And in the real world:
Now, when the switch is open, pin 25 is connected to ground through the 10K resistor. Even with the resistor though, it’s enough of a connection to make it solidly low. It’s not going to fluctuate.
Then we hit the switch, connecting the lower part of the circuit to the 3.3 volts. Because we have a fairly high resistance there, most of the current is going to go to pin 25, sending it solidly high. Some of it is also going to go to ground via R1. But Ohm’s Law tells us that 3.3 volts divided by 10,000 ohms will let about 0.33 milliamps in. That’s not going to break the bank.
So in this circuit, R1 is called a pull-down resistor because in its default state it pulls the signal down to 0 volts or a low state.
Now let’s swap things around a bit:
Now pin 25 is hard-wired to 3.3 volts through R1, making its default state high. However when the button is pressed, pin 25 will be directly connected to ground, sending it low. Because the resistor pulls pin 25 up to 3.3 volts and a high state, it’s now known as a pull-up resistor.
So, which one do you use? It depends on whether you want your default signal to be high or low.
Hope that helps.