The Raspberry Pi 4 GPIO header features 40 physical pins, 26 of which are usable digital I/O lines operating strictly at 3.3V logic. The BCM2711 SoC enforces a safe continuous current limit of ~16mA per pin and a total GPIO bank limit of ~50mA. Exceeding these limits will permanently damage the SoC. This guide provides the exact hardware specifications, a complete Python control script with error handling, and a definitive troubleshooting path for the most common permission and wiring failures.
The Quick Decision Path: Which Raspberry Pi 4 GPIO Setup Do You Need?
Before wiring anything to the 40-pin header, determine your load requirements. Use this decision tree to select the correct hardware interface.
| Scenario / Load Requirement | Recommended Hardware | Why This Pick? |
|---|---|---|
| Driving standard 5mm LEDs, reading pushbuttons, or interfacing with 3.3V logic sensors. | Direct GPIO via Breakout Board | Simplest wiring; no extra silicon needed. 16mA per pin is sufficient for indicator LEDs. |
| Switching 5V/12V relays, solenoids, or DC motors drawing >50mA. | ULN2803 Darlington Array or Logic-Level MOSFET (e.g., IRLZ44N) | Protects the 3.3V GPIO pins from inductive kickback and overcurrent. The Pi only sources the gate/base current. |
| Need more than 26 digital I/O pins for a large LED matrix or keypad. | MCP23017 I2C GPIO Expander | Adds 16 extra I/O pins using only two Pi GPIO pins (SDA/SCL). Supports up to 8 expanders on one bus. |
| Interfacing with 5V logic devices (e.g., Arduino, 5V shift registers). | Bi-directional Logic Level Converter (e.g., TXS0108E) | Prevents 5V backfeed into the Pi's 3.3V pins, which will instantly fry the BCM2711 SoC. |
Hardware Spec Sheet: Pi 4 Model B GPIO Pin Mapping & Limits
This section targets the Raspberry Pi 4 Model B (4GB RAM variant). The pinout is identical across the 1GB, 2GB, 4GB, and 8GB variants, as well as the Pi 400.
Exact Parts List
- Board: Raspberry Pi 4 Model B (4GB) [Approx. $55 USD]
- Interface: SunFounder GPIO Breakout Board with 40-pin ribbon cable [Approx. $12 USD]
- Component: 5mm Red LED (2.0V forward voltage) [Approx. $0.10 USD]
- Current Limiter: 330Ω 1/4W Carbon Film Resistor [Approx. $0.05 USD]
- Wiring: 22 AWG solid core jumper wires for breadboard
Critical Pin Mapping Table (BCM vs Physical)
Always use the BCM (Broadcom SOC channel) numbering scheme in your code. Physical pin numbers are only for counting from the board edge.
| Physical Pin | BCM GPIO | Function / Name | Voltage / Current Limit |
|---|---|---|---|
| 1 | N/A | 3.3V Power | Max 50mA total draw |
| 2 | N/A | 5V Power | Limited by USB-C PSU (Max 3A total system) |
| 3 | 2 | SDA1 (I2C) | 3.3V Logic, 16mA max |
| 5 | 3 | SCL1 (I2C) | 3.3V Logic, 16mA max |
| 12 | 18 | GPIO 18 (PCM_CLK / PWM0) | 3.3V Logic, 16mA max (Hardware PWM capable) |
| 6, 9, 14, 20, 25, 30, 34, 39 | N/A | Ground (GND) | Common ground reference |
Step-by-Step Build: Wiring and Python Control
Wiring the Circuit
- De-energize the board: Unplug the USB-C power cable from the Pi 4. Never wire GPIO pins while the board is powered.
- Connect the breakout board: Align the notch on the 40-pin ribbon cable with Pin 1 on the Pi and the breakout board. Ensure the red stripe on the cable aligns with the 3.3V rail (Pin 1).
- Wire the GPIO output: Connect a jumper wire from BCM GPIO 18 (Physical Pin 12) on the breakout board to one end of the 330Ω resistor on your breadboard.
- Wire the LED: Connect the other end of the resistor to the Anode (long leg) of the 5mm LED.
- Complete the ground loop: Connect the Cathode (short leg, flat edge) of the LED to a GND pin on the breakout board (e.g., Physical Pin 14).
- Verify and Power: Double-check that the 5V pin is not touching the 3.3V pin. Plug in the official 5.1V/3.0A USB-C power supply.
Complete Python Control Code
This script uses the RPi.GPIO library. It includes explicit pin definitions, software PWM for fading, and a robust try/except/finally block to ensure the GPIO pins are safely reset if the script is interrupted. Note: On Raspberry Pi OS Bookworm, install the compatibility shim via sudo apt install python3-rpi-lgpio before running.
#!/usr/bin/env python3
"""
Raspberry Pi 4 GPIO LED Fade Script
Target Board: Raspberry Pi 4 Model B (BCM2711)
Library: RPi.GPIO (with rpi-lgpio backend on Bookworm)
"""
import RPi.GPIO as GPIO
import time
import sys
# --- EXPLICIT PIN DEFINITIONS ---
LED_PIN = 18 # BCM GPIO 18 (Physical Pin 12) - Hardware PWM capable
PWM_FREQ = 1000 # 1kHz frequency to avoid visible LED flicker
FADE_STEP = 5 # Duty cycle increment/decrement
DELAY = 0.05 # Seconds between fade steps
def setup_gpio():
"""Initialize GPIO settings safely."""
GPIO.setmode(GPIO.BCM) # Use Broadcom SOC channel numbering
GPIO.setwarnings(False) # Suppress 'channel in use' warnings
GPIO.setup(LED_PIN, GPIO.OUT) # Set pin as output
return GPIO.PWM(LED_PIN, PWM_FREQ)
def main():
pwm = setup_gpio()
pwm.start(0) # Start with 0% duty cycle (LED off)
print(f"Starting LED fade on BCM GPIO {LED_PIN}. Press Ctrl+C to stop.")
try:
while True:
# Fade In
for duty_cycle in range(0, 101, FADE_STEP):
pwm.ChangeDutyCycle(duty_cycle)
time.sleep(DELAY)
# Fade Out
for duty_cycle in range(100, -1, -FADE_STEP):
pwm.ChangeDutyCycle(duty_cycle)
time.sleep(DELAY)
except KeyboardInterrupt:
print("\nInterrupt received. Stopping PWM...")
except Exception as e:
print(f"\nUnexpected error: {e}", file=sys.stderr)
finally:
# CRITICAL: Always clean up to release hardware resources
pwm.stop()
GPIO.cleanup()
print("GPIO cleaned up successfully. Exiting.")
if __name__ == "__main__":
main()
Debugging: Fixing the /dev/mem Permission Error
When running GPIO scripts on the Pi 4, the most frequent roadblock is a permissions failure. If your script crashes immediately, look for this exact error string in your terminal:
RuntimeError: No access to /dev/mem. Try running as root!
Ranked Causes and Fixes
- User lacks GPIO group permissions (Most Likely): Modern Raspberry Pi OS does not require
sudofor GPIO if the user is in the correct group.
Fix: Runsudo usermod -aG gpio $USER, then log out and log back in. - Missing Bookworm Compatibility Layer: Raspberry Pi OS Bookworm switched to
lgpioas the backend, deprecating directRPi.GPIOmemory access.
Fix: Install the shim viasudo apt install python3-rpi-lgpio. - Running inside an isolated Virtual Environment: If you created a venv without system site packages, it cannot see the OS-level GPIO libraries.
Fix: Recreate the venv usingpython3 -m venv --system-site-packages myenv.
The First Three Things to Check When GPIO Fails
If the code runs without errors but the physical LED does not light up, perform these three checks in order:
- Verify Pin Numbering Scheme: Did you use
GPIO.setmode(GPIO.BCM)but wire to Physical Pin 18? BCM 18 is Physical Pin 12. Mismatched numbering is the #1 cause of silent hardware failures. Always default to BCM. - Measure Physical Voltage: Set your multimeter to DC Volts. Place the red probe on Physical Pin 1 (3.3V) and the black probe on Physical Pin 6 (GND). You must read between 3.25V and 3.35V. If you read 0V, your Pi's internal polyfuse has tripped or the board is unpowered.
- Check LED Polarity and Resistor Placement: Ensure the flat edge (cathode) of the LED faces the GND pin. A reversed LED will not light up and will drop the full 3.3V across the resistor, which you can verify by measuring the voltage drop across the LED legs (it should read ~2.0V when forward-biased).
Extending and Simplifying Your GPIO Build
Once you have mastered direct GPIO control, you will inevitably hit the physical limits of the 40-pin header. Here is how to scale your project up or down.
How to Extend: Adding I2C GPIO Expansion
If you need to wire 16 additional LEDs or read a 4x4 matrix keypad, do not buy a second Raspberry Pi. Use an MCP23017 I2C GPIO Expander (approx. $3 USD).
Wiring: Connect the MCP23017 VDD to Pi 3.3V, VSS to Pi GND, SDA to Pi BCM 2, and SCL to Pi BCM 3.
Code: Use the Adafruit CircuitPython MCP230xx library to address the expander over the I2C bus, freeing up your primary GPIO pins for high-speed tasks like SPI displays.
How to Simplify: Switching to GPIO Zero
For production scripts where you don't need manual PWM frequency tuning, abandon RPi.GPIO and use the gpiozero library. It abstracts away the setup, cleanup, and pin numbering entirely.
from gpiozero import PWMLED
from time import sleep
# gpiozero defaults to BCM numbering automatically
led = PWMLED(18)
try:
led.pulse() # Built-in hardware fade method
except KeyboardInterrupt:
pass
Final Recommendation: For initial prototyping and learning hardware constraints, stick to the RPi.GPIO script provided above to understand the underlying register setups and cleanup routines. Once your circuit is verified on the breadboard, refactor your production code to gpiozero for cleaner syntax and automatic resource management. Always respect the 16mA per-pin and 50mA total bank limits of the BCM2711 chip to ensure your Pi 4 survives your next build.






