The General Purpose Input/Output (GPIO) header on the Raspberry Pi gives you direct, low-level control over 26 usable digital pins. However, if you are working with the Raspberry Pi 5, the rules have changed. Unlike previous generations where GPIO was memory-mapped directly to the Broadcom SoC, the Pi 5 routes all GPIO traffic through the new RP1 southbridge chip over a PCIe link. This architectural shift means legacy libraries like RPi.GPIO are largely deprecated, and understanding the modern software stack is critical to getting your circuits working.
This guide provides the exact pinouts, hardware requirements, and Python code to build and debug a reliable GPIO circuit on the Pi 5, skipping the outdated advice that plagues older tutorials.
Difficulty: Beginner/Intermediate
Time to Complete: 25 minutes
Target Board: Raspberry Pi 5 (8GB variant) running Raspberry Pi OS (Bookworm or later)
Hardware Requirements & Board Specifications
Before writing a single line of code, you need the right physical components. The Pi 5 requires a robust power supply to prevent brownouts when sourcing current from the GPIO pins.
| Component | Exact Specification / Variant | Notes & Purpose |
|---|---|---|
| Microcontroller | Raspberry Pi 5 (8GB) | Target board. 4GB works identically for GPIO, but 8GB is the 2026 standard for desktop use. |
| Power Supply | Official 27W USB-C PD | Required to enable full 1.2A downstream USB current and stable 3.3V rail. |
| LED | 5mm Red Diffused (Vf ≈ 2.0V) | Standard indicator. Forward voltage (Vf) is critical for resistor math. |
| Current Limiting Resistor | 330Ω 1/4W Carbon Film | See Ohm's law calculation below. |
| Switch | 6x6mm Tactile Pushbutton | Standard 4-pin momentary switch. |
| Wiring | Male-to-Female Dupont Jumpers | 22 AWG stranded copper. |
| Prototyping | Half-size 400-point Breadboard | Standard solderless breadboard. |
The Resistor Math (Why 330Ω?):
The Pi 5 GPIO outputs 3.3V. A standard red LED has a forward voltage (Vf) of 2.0V and a max continuous forward current (If) of 20mA. While Ohm's law (R = V / I) gives (3.3V - 2.0V) / 0.02A = 65Ω, drawing 20mA continuously from a single RP1 GPIO pin is poor practice. The absolute maximum per pin is 16mA, and the total bank limit is 50mA. Derating to a safe 4mA yields: 1.3V / 0.004A = 325Ω. The nearest standard E12 value is 330Ω, which provides excellent brightness while keeping the silicon well within thermal limits.
Pin Mapping & Wiring the Circuit
The Raspberry Pi uses two numbering schemes: BOARD (physical pin position 1-40) and BCM (Broadcom SoC channel numbers). We strictly use BCM numbering in modern Python code, as it maps directly to the RP1 chip's internal registers. For physical wiring, refer to the excellent Pinout.xyz reference.
| BCM Pin | Physical Pin | Function | Wiring Destination |
|---|---|---|---|
| N/A | Pin 1 | 3.3V Power | Not used (we use GND for button) |
| BCM 17 | Pin 11 | GPIO 17 (Input) | Button Pin 1 (Diagonal) |
| N/A | Pin 9 | Ground (GND) | Button Pin 2 (Diagonal) |
| BCM 27 | Pin 13 | GPIO 27 (Output) | 330Ω Resistor Lead 1 |
| N/A | Pin 14 | Ground (GND) | LED Cathode (Short Leg) |
Wiring Steps:
- De-energize: Unplug the Pi 5 USB-C power cable before wiring.
- LED Circuit: Insert the 330Ω resistor into the breadboard. Connect one end to BCM 27 (Physical Pin 13) via a jumper. Connect the other end to the LED Anode (long leg). Connect the LED Cathode (short leg) to GND (Physical Pin 14).
- Button Circuit: Place the tactile switch across the breadboard's center trench. Connect one diagonal pin to BCM 17 (Physical Pin 11). Connect the opposite diagonal pin to GND (Physical Pin 9).
- Verify: Use a multimeter in continuity mode to verify there are no shorts between the 3.3V rail and your GPIO pins before applying power.
Python Control: The gpiozero Standard
With the introduction of the RP1 chip and Raspberry Pi OS Bookworm, the legacy RPi.GPIO library is no longer the standard. The officially supported library is gpiozero, which uses the lgpio backend under the hood to communicate with the Pi 5's hardware. According to the gpiozero official documentation, this abstraction handles pin factory selection and cleanup automatically.
Ensure your system is up to date and the backend is installed:
sudo apt update
sudo apt install python3-gpiozero python3-rpi-lgpio
Save the following code as gpio_test.py. This script includes explicit pin definitions, hardware debouncing, and robust error handling.
from gpiozero import LED, Button
from signal import pause
import sys
import logging
# Explicit BCM pin definitions
LED_PIN = 27
BUTTON_PIN = 17
# Configure basic logging for debugging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def main():
try:
# Initialize LED on BCM 27
led = LED(LED_PIN)
# Initialize Button on BCM 17
# pull_up=True enables the internal 50k pull-up resistor.
# The button connects the pin to GND, pulling it LOW when pressed.
# bounce_time=0.05 handles mechanical switch contact bounce (50ms).
button = Button(BUTTON_PIN, pull_up=True, bounce_time=0.05)
# Map events to functions
button.when_pressed = led.on
button.when_released = led.off
logging.info(f'GPIO initialized. LED on BCM {LED_PIN}, Button on BCM {BUTTON_PIN}.')
logging.info('Press the button to light the LED. Press Ctrl+C to exit.')
# Keep the script running efficiently
pause()
except KeyboardInterrupt:
logging.info('Program interrupted by user (Ctrl+C).')
except Exception as e:
logging.error(f'Fatal GPIO Error: {e}')
finally:
# Safe cleanup: gpiozero handles this on exit, but explicit is better
try:
if 'led' in locals(): led.close()
if 'button' in locals(): button.close()
except Exception:
pass
sys.exit(0)
if __name__ == '__main__':
main()
Debugging: First Three Things to Check When It Fails
When working with GPIO on Raspberry Pi 5, software environment mismatches cause 90% of failures. If your script crashes, check these three items in order.
1. The Pin Factory Error (Missing Backend)
Exact Error String: gpiozero.exc.BadPinFactory: Unable to load any default pin factory!
Cause: You are running a Python virtual environment (venv) or a minimal OS image that lacks the lgpio C-extension required by gpiozero to talk to the RP1 chip.
Fix: Install the native backend via apt (not pip, as pip wheels often lack the C-headers for the Pi 5). Run sudo apt install python3-rpi-lgpio. If using a venv, create it with system site packages: python3 -m venv --system-site-packages myenv.
2. The Legacy Library Crash
Exact Error String: RuntimeError: Not running on a RPi! or ModuleNotFoundError: No module named 'RPi'
Cause: Your code is trying to import the legacy RPi.GPIO library. Because the Pi 5's GPIO is no longer memory-mapped to the CPU in the same way, older versions of RPi.GPIO fail to detect the hardware or map the registers.
Fix: Refactor your code to use gpiozero as shown above. If you absolutely must use RPi.GPIO for legacy compatibility, you must install the specific Pi 5 patched fork: sudo apt install python3-rpi.gpio and set the environment variable export GPIOZERO_PIN_FACTORY=rpigpio, though this is highly discouraged for new projects.
3. Physical Wiring & Floating Pins
Symptom: The LED turns on randomly without pressing the button, or the button triggers multiple times instantly.
Cause: A floating input pin (acting as an antenna picking up EMI) or missing software debouncing.
Fix: Verify your code includes pull_up=True (or pull_down=True if wiring to 3.3V). Ensure your physical wiring is secure. Use your multimeter to measure continuity from the button GND pin to Physical Pin 9 on the Pi header.
Extending and Simplifying the Build
Once the basic circuit is stable, you can scale the project up or down based on your application needs.
To Simplify (Multiple Components):
If you need to control a traffic light sequence or a bank of relays, avoid writing repetitive LED() instantiations. Use the LEDBoard class from gpiozero:
from gpiozero import LEDBoard
lights = LEDBoard(red=17, yellow=27, green=22)
lights.red.on()
lights.blink()
To Extend (Analog & PWM):
The Pi 5 GPIO pins are strictly digital. To fade the LED smoothly or control a 50Hz servo motor, you need Pulse Width Modulation (PWM). While gpiozero.PWMLED works for basic fading using software timing, it can jitter under heavy CPU load. For precision hardware-timed PWM (essential for servos and stepper drivers), install the pigpio daemon, which communicates with the RP1 chip via a local socket:
sudo apt install pigpio
sudo systemctl enable pigpiod
sudo systemctl start pigpiod
Then, set export GPIOZERO_PIN_FACTORY=pigpio before running your Python script to unlock rock-solid hardware PWM.
Frequently Asked Questions
Can I use 5V sensors with GPIO on Raspberry Pi 5?
No. The Raspberry Pi 5 RP1 southbridge operates exclusively on 3.3V logic. Feeding a 5V output from a sensor (like an HC-SR04 ultrasonic module or an Arduino Uno) directly into a Pi GPIO pin will exceed the absolute maximum ratings, permanently damaging the pin and potentially the entire RP1 chip. You must use a bidirectional logic level shifter (such as the Texas Instruments TXS0108E or a simple BSS138 MOSFET-based module) to safely translate 5V signals down to 3.3V.
Why did my GPIO pin stop working after a reboot?
By default, Raspberry Pi OS resets all GPIO pins to high-impedance inputs (floating) on boot to prevent short circuits if a pin is wired to VCC or GND. If your circuit relies on a pin being HIGH or LOW immediately upon power-up, you will experience undefined behavior during the boot sequence. To fix this, you can configure the EEPROM or use a config.txt overlay to set default GPIO states at boot, or rely on external pull-up/pull-down resistors on your breadboard to hold the line in a known state until your Python script initializes.
How much current can a single Raspberry Pi GPIO pin source?
According to the Raspberry Pi hardware documentation, the absolute maximum current per GPIO pin on the Pi 5 is 16mA. However, the RP1 chip is divided into voltage domains (banks), and the total current for all pins in a single bank must not exceed 50mA. Designing your circuits to draw no more than 4mA to 8mA per pin (using high-efficiency LEDs or driving MOSFET gates) ensures long-term reliability and prevents thermal throttling of the southbridge.






