Pull-up and Pull-down Resistors
Pull-up and pull-down resistors are simple solutions that ensure a pin always has a known voltage level, even when nothing else is driving it. Let's understand how they work.
What Are Pull-up and Pull-down Resistors?
Pull-up Resistor
Connects the pin to the positive voltage (3.3V on the Pico) through a resistor. This "pulls" the pin HIGH by default. When you press a button that connects the pin to ground, the pin reads LOW.
Pull-down Resistor
Connects the pin to ground (0V) through a resistor. This "pulls" the pin LOW by default. When you press a button that connects the pin to 3.3V, the pin reads HIGH.
How Pull-up Resistors Work
Let's look at a typical button circuit with a pull-up resistor:
Pull-up resistor configuration
How It Works
- ▸Button not pressed: Current flows through the resistor to the GPIO pin, holding it at 3.3V (HIGH)
- ▸Button pressed: You create a direct path to ground. Electricity follows the path of least resistance, current flows through the button to ground, and the pin reads LOW
How Pull-down Resistors Work
A pull-down resistor works in the opposite direction:
Pull-down resistor configuration
How It Works
- ▸Button not pressed: The GPIO pin is connected to ground through the resistor, reading LOW
- ▸Button pressed: The button connects the pin directly to 3.3V, and the pin reads HIGH
Internal Pull Resistors
The Raspberry Pi Pico has built-in pull-up and pull-down resistors on every GPIO pin. You don't need to add external resistors for basic button inputs. You can enable them in software.
Hardware Bug in Early RP2350 Chips: There's a hardware bug (E9) in the initial RP2350 chip that affects internal pull-down resistors. The bug causes the GPIO pin to read HIGH even when the button isn't pressed.
The bug was fixed in the newer RP2350 A4 chip revision.
Workaround: If you have an older chip, avoid using Pull::Down. Use Pull::Up instead, or use an external pull-down resistor with Pull::None.
Using Internal Pull Resistors in Code
Here's how to configure internal pull resistors in Rust:
Pull-up Configuration
let button = Input::new(p.PIN_16, Pull::Up);
// With pull-up enabled:
// - Button not pressed = HIGH
// - Button pressed (connected to GND) = LOW
if button.is_low() {
// Button is pressed
}Pull-down Configuration
let button = Input::new(p.PIN_16, Pull::Down);
// With pull-down enabled:
// - Button not pressed = LOW
// - Button pressed (connected to 3.3V) = HIGH
if button.is_high() {
// Button is pressed
}No Pull (Floating)
let button = Input::new(p.PIN_16, Pull::None);
// Use this only when:
// - You have an external pull resistor
// - Connecting to devices that actively drive the pin HIGH or LOWFor the Pico 2 W, it's recommended to use Pull::Up for buttons connected to ground. This avoids the pull-down bug in early chips and is the most common button configuration.