Raspberry Pi GPIO Foundations: 40-Pin Header, Breadboard Electronics & Python Control
Created: 2026-11-08 Last updated: 2026-11-08
Executive Summary: The defining superpower of the Raspberry Pi compared to a standard laptop or desktop PC is its 40-pin General Purpose Input/Output (GPIO) header. These pins bridge the digital realm of Linux software with the physical world of electronics: allowing Python scripts to illuminate LEDs, read tactile buttons, sample analog sensors, and command electric motors. This guide explains the header layout, untangles the confusion between Physical and BCM pin numbering, enforces the non-negotiable 3.3V logic rule, walks through breadboard circuit assembly, and drives your first interactive hardware project using modern
gpiozero.
-
Header Architecture
Demystify the 40-pin layout: distinguish power supply pins (3.3V, 5V, GND) from software-programmable GPIO lines.
-
BCM vs. Board Numbering
Understand why Physical Board pin numbers (1–40) differ from Broadcom (BCM) numbers and why modern software uses BCM.
-
The 3.3V Survival Rule
Protect your board from permanent damage: understand why GPIO pins lack 5V tolerance and how to wire safely.
-
First Hands-On Lab
Assemble an LED and button circuit on a solderless breadboard and control it with elegant, 5-line Python scripts.
1. Anatomy of the 40-Pin Header
All modern Raspberry Pi models (Pi 5, Pi 4, Pi 3, Pi Zero 2 W) share an identical, standardized 2×20 pin dual-row header:
┌──────────────────────┐
+3.3V (DC) ── │ 01 (●) (●) 02 │ ── +5.0V (DC)
GPIO 2 (SDA1) ── │ 03 (●) (●) 04 │ ── +5.0V (DC)
GPIO 3 (SCL1) ── │ 05 (●) (●) 06 │ ── Ground (GND)
GPIO 4 (GPCLK) ── │ 07 (●) (●) 08 │ ── GPIO 14 (TXD)
Ground (GND) ── │ 09 (●) (●) 10 │ ── GPIO 15 (RXD)
GPIO 17 ── │ 11 (●) (●) 12 │ ── GPIO 18 (PWM0)
GPIO 27 ── │ 13 (●) (●) 14 │ ── Ground (GND)
GPIO 22 ── │ 15 (●) (●) 16 │ ── GPIO 23
+3.3V (DC) ── │ 17 (●) (●) 18 │ ── GPIO 24
GPIO 10 (MOSI) ── │ 19 (●) (●) 20 │ ── Ground (GND)
GPIO 9 (MISO) ── │ 21 (●) (●) 22 │ ── GPIO 25
GPIO 11 (SCLK) ── │ 23 (●) (●) 24 │ ── GPIO 8 (CE0)
Ground (GND) ── │ 25 (●) (●) 26 │ ── GPIO 7 (CE1)
ID_SD ── │ 27 (●) (●) 28 │ ── ID_SC
GPIO 5 ── │ 29 (●) (●) 30 │ ── Ground (GND)
GPIO 6 ── │ 31 (●) (●) 32 │ ── GPIO 12 (PWM0)
GPIO 13 (PWM1) ── │ 33 (●) (●) 34 │ ── Ground (GND)
GPIO 19 (MISO) ── │ 35 (●) (●) 36 │ ── GPIO 16
GPIO 26 ── │ 37 (●) (●) 38 │ ── GPIO 20 (MOSI)
Ground (GND) ── │ 39 (●) (●) 40 │ ── GPIO 21 (SCLK)
└──────────────────────┘
The Three Functional Pin Groups
- Power Supply Pins (Fixed Voltage Outputs):
+3.3VPower (Pins 1 & 17): Delivers clean 3.3V DC directly from the on-board voltage regulators (max ~50 mA total draw across all pins).+5.0VPower (Pins 2 & 4): Connected directly to the incoming USB-C power rail. Capable of powering small sensors, cooling fans, and relay coils.- Ground (
GND, 8 separate pins: 6, 9, 14, 20, 25, 30, 34, 39): The reference ground (0V). All electrical circuits require a closed loop back to one of these pins. - General Purpose Input/Output (GPIO) Pins (26 Pins):
- Software-configurable pins. Can be programmed as an Output (driving 3.3V
HIGHor 0VLOW) or an Input (detecting whether an external circuit isHIGHorLOW). - Specialized Hardware Bus Pins (Alternate Functions):
- Dedicated pins with on-chip hardware engines: I2C (
GPIO 2/3), SPI (GPIO 7–11), UART Serial (GPIO 14/15), and Hardware PWM (GPIO 12/13/18/19).
Physical vs. BCM Pin Numbering: The Confusion Resolved
Beginners often get confused because a single physical pin on the board has two different numbers:
- Physical (Board) Numbering: Refers strictly to the sequential physical position on the connector from
Pin 1toPin 40. Pin 1 is always in the corner closest to the microSD slot / status LED. - BCM (Broadcom) Numbering: Refers to the internal silicon channel number assigned by the Broadcom SoC designer (e.g.,
GPIO 17,GPIO 27).
Example:
┌─────────────────────────────────────────────────────────────┐
│ Physical Pin 11 ═══════════> BCM / Software: GPIO 17 │
│ Physical Pin 13 ═══════════> BCM / Software: GPIO 27 │
│ Physical Pin 06 ═══════════> Ground (GND) │
└─────────────────────────────────────────────────────────────┘
Golden Standard in Software
Always use BCM numbering in your Python code and shell scripts. The modern Python library gpiozero uses BCM numbering by default (e.g. LED(17) refers to BCM GPIO 17 on Physical Pin 11).
2. The 3.3V Survival Rule: Preventing Board Death
The most dangerous pitfall in physical computing with the Raspberry Pi is voltage incompatibility:
%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
SAFE["3.3V Sensor / Signal"] -->|"Safe Voltage"| PI["Raspberry Pi GPIO Input Bank"]
KILL["5.0V Signal (Arduino / 5V Sensor)"] -->|"Overvoltage Spikes!"| PI
PI --> DEAD["Permanent Silicon Breakdown!<br/>SoC / RP1 I/O Cell Burned Out!<br/>Board Permanently Destroyed!"]
GPIO Pins Are Strictly NOT 5V-Tolerant!
Unlike many 5V Arduino boards, the Raspberry Pi's GPIO pins connect directly to the 3.3V I/O transistors of the SoC/RP1 chip without overvoltage clamping diodes. Connecting any voltage greater than 3.6V to a GPIO pin will permanently destroy that pin or the entire computer!
- Never wire a 5V sensor output directly to a GPIO pin.
- Always use a bi-directional Logic Level Shifter (3.3V ↔ 5V) or a resistive voltage divider when reading from 5V devices.
3. Electronics 101: Solderless Breadboards & Ohm's Law
To build experimental circuits without soldering, we use a Solderless Breadboard:
(+) ────────────────────────────────────────── Power Rail (+)
(-) ────────────────────────────────────────── Ground Rail (-)
a b c d e f g h i j
01 [●]─[●]─[●]─[●]─[●] [●]─[●]─[●]─[●]─[●] 01 <- Terminal strip:
02 [●]─[●]─[●]─[●]─[●] [●]─[●]─[●]─[●]─[●] 02 5 holes connected
03 [●]─[●]─[●]─[●]─[●] [●]─[●]─[●]─[●]─[●] 03 horizontally!
- Power Rails (+ and - along the sides): Connected vertically from top to bottom.
- Terminal Strips (rows 1–30): Groups of 5 holes (
a-b-c-d-eandf-g-h-i-j) connected horizontally under the plastic. The center trench isolates the left side from the right side.
Why Every LED Needs a Current-Limiting Resistor
A Light Emitting Diode (LED) is a semiconductor diode. It has almost zero internal electrical resistance once it turns on. If you connect an LED directly between 3.3V and GND, an unlimited surge of current rushes through the diode, instantly melting its internal bond wire and potentially burning out the Raspberry Pi's GPIO output driver!
We calculate the required resistor using Ohm's Law:
Resistance (R) = (Supply Voltage - LED Forward Voltage) ÷ Desired Current
For a standard Red LED:
- Supply Voltage = 3.3V
- LED Forward Voltage drop = ~1.8V
- Safe Operating Current = 10 mA (0.01 A)
- Calculation: (3.3V - 1.8V) ÷ 0.01A = 150 Ω
A 220 Ω or 330 Ω resistor is the ideal standard choice—it ensures the LED glows brightly while limiting current to a safe ~5–7 mA, well within the Pi's safe limit of 16 mA per pin.
4. Hands-On Lab: Wiring an LED Circuit
Required Components
- 1× Solderless Breadboard
- 1× Red 5mm LED
- 1×
330 ΩResistor (Color code: Orange-Orange-Brown-Gold) - 2× Male-to-Female Jumper Wires
Circuit Schematic
Raspberry Pi Breadboard
┌──────────────┐ ┌───────────────────────────┐
│ Pin 11 │ ───────────> │ [Row 10] Resistor (330Ω) │
│ (GPIO 17) │ │ │ │
│ │ │ v │
│ │ │ [Row 11] LED Anode (+) │
│ │ │ │ (Long leg) │
│ │ │ v │
│ │ │ [Row 12] LED Cathode (-) │
│ Pin 06 (GND) │ <─────────── │ (Short leg / flat side) │
└──────────────┘ └───────────────────────────┘
- Identify the LED legs: The longer leg is the Anode (+). The shorter leg (and flat side on the plastic rim) is the Cathode (-).
- Connect Pin 11 (GPIO 17) to one side of the
330 Ωresistor. - Connect the other side of the resistor to the Anode (+) of the LED.
- Connect the Cathode (-) of the LED back to Pin 6 (GND) on the Raspberry Pi.
5. Controlling the LED with Python (gpiozero)
Log in to your Raspberry Pi via SSH and install the official GPIO control library:
Create a new Python script:
Paste the following reproducible, modern code:
#!/usr/bin/env python3
"""Simple, idiomatic LED blinker using gpiozero on Raspberry Pi OS."""
import time
from gpiozero import LED
# Initialize GPIO 17 (Physical Pin 11)
led = LED(17)
print("Starting LED blinker on BCM GPIO 17... (Press Ctrl+C to exit)")
try:
while True:
led.on()
print("LED is: ON (:material-lightbulb-on:)")
time.sleep(1.0)
led.off()
print("LED is: OFF (:material-lightbulb-off:)")
time.sleep(1.0)
except KeyboardInterrupt:
print("\nExiting cleanly... Shutting off LED.")
led.off()
Run the script:
Your physical LED on the breadboard will begin blinking in precise 1-second intervals!
6. Adding Input: Reading a Tactile Pushbutton
Controlling an output (LED) is only half of physical computing; reading an input (like a tactile pushbutton or switch) allows your code to react to the physical environment.
%%{init: {'flowchart': {'wrappingWidth': 600, 'subGraphTitleMargin': {'top': 15, 'bottom': 15}}}}%%
flowchart TB
NOISE["Floating Pin (Unconnected)<br/>Acts as an antenna: picks up EM noise!<br/>Erratic random 0 and 1 readings!"]
PULLUP["Internal Pull-Up Resistor Enabled<br/>Ties pin gently to 3.3V (Default: HIGH / 1)"]
BUTTON["Button Pressed: Connects Pin to GND<br/>Voltage pulled firmly to 0V (LOW / 0)"]
NOISE -. "Solved by" .-> PULLUP
PULLUP -->|"Physical Contact"| BUTTON
The "Floating Pin" Problem & Pull-Up Resistors
If you connect a bare wire to an input pin without a resistor, the pin is floating. It acts like an antenna, picking up static electricity and electromagnetic interference, randomly oscillating between 0 and 1.
The Broadcom SoC contains built-in internal Pull-Up Resistors (~50 kΩ). When enabled, the internal resistor connects the pin to 3.3V, ensuring the pin reads a steady 1 (HIGH) by default. When you press the button, it bridges the pin to GND, cleanly pulling the voltage to 0V (LOW).
Button Circuit & Script
- Connect one leg of a momentary push button to Pin 13 (GPIO 27).
- Connect the opposite leg of the button to Pin 14 (GND).
#!/usr/bin/env python3
"""Interactive Button-Controlled LED with hardware debouncing."""
from signal import pause
from gpiozero import LED, Button
led = LED(17)
# pull_up=True activates internal pull-up resistor; bounce_time prevents false double-clicks
button = Button(27, pull_up=True, bounce_time=0.05)
print("System ready! Press the button to toggle the LED. (Ctrl+C to quit)")
# Bind actions to hardware events
button.when_pressed = led.on
button.when_released = led.off
# Keep script running without burning 100% CPU in an empty while-loop
pause()
Run the interactive script:
Pressing the button illuminates the LED instantly; releasing the button turns it off!
Where to Go Next
Now that you have experienced the thrill of physical computing, learn how to diagnose and resolve errors when things do not work as planned:
-
Next Guide: Troubleshooting & Error Codes
Decode green ACT LED blink codes, solve SSH connection refused errors, and troubleshoot undervoltage issues.