The Raspberry Pi’s GPIO (General Purpose Input/Output) pins are what transform it from a tiny computer into a powerful hardware control platform. Whether you want to blink an LED, read a button press, or switch a high-power relay to control an appliance, the GPIO interface makes it all possible with just a few lines of Python code.
In this comprehensive tutorial, you’ll learn everything you need to know about Raspberry Pi GPIO — from understanding the pin numbering schemes to building practical circuits. By the end, you’ll have controlled an LED, read a button, and switched a relay, all from your Raspberry Pi running Python.
What is GPIO and Why Does It Matter?
GPIO stands for General Purpose Input/Output. On a Raspberry Pi, these are the 40 pins arranged in a double row along one edge of the board. Unlike the pins on a USB port or HDMI connector, GPIO pins have no fixed function — you program them in software to do exactly what you need.
Each GPIO pin can be configured as either an input or an output:
- Output mode: The Pi drives the pin HIGH (3.3V) or LOW (0V). Use this to turn on LEDs, trigger relays, or send signals to other devices.
- Input mode: The Pi reads whether the pin is HIGH or LOW. Use this to detect button presses, read sensor signals, or receive data from other devices.
The GPIO system runs at 3.3V logic levels — this is critical. Never connect a 5V signal directly to a GPIO pin, or you risk permanently damaging the Pi. Most sensors and modules sold for the Pi are 3.3V compatible, but always double-check.
Understanding GPIO Pin Numbering
One of the most confusing aspects for beginners is that Raspberry Pi GPIO pins have two numbering systems:
BCM (Broadcom) Numbering
This uses the chip’s internal numbering. GPIO17, GPIO27, GPIO22 etc. This is what most tutorials and libraries use by default, and what we’ll use throughout this guide.
Board (Physical) Numbering
This numbers pins 1–40 as they physically appear on the board, going left-to-right, top-to-bottom. Pin 1 is the 3.3V power pin in the top-left corner (with the board oriented text-side up).
The easiest way to remember the layout is to keep a GPIO pinout diagram handy. The command pinout in the terminal (on Raspberry Pi OS) displays a colour-coded map of all 40 pins right in your terminal.
Key power and ground pins:
- Pins 1, 17: 3.3V power
- Pins 2, 4: 5V power
- Pins 6, 9, 14, 20, 25, 30, 34, 39: Ground (GND)
Setting Up Python GPIO Libraries
Raspberry Pi OS comes with GPIO libraries pre-installed, but it’s good practice to make sure you have the latest versions. Open a terminal and run:
sudo apt update
sudo apt install python3-gpiozero python3-rpi.gpio -y
We’ll primarily use gpiozero in this tutorial — it’s the officially recommended library for beginners because it abstracts away a lot of low-level complexity. For more advanced use cases, we’ll also show the equivalent RPi.GPIO code.
To verify your installation:
python3 -c "import gpiozero; print(gpiozero.__version__)"
Project 1: Controlling an LED
Let’s start with the classic “Hello World” of hardware: blinking an LED.
Components Needed
- 1× LED (any colour)
- 1× 330Ω resistor (orange-orange-brown)
- Breadboard and jumper wires
- Raspberry Pi with Raspberry Pi OS
Circuit Connections
- Connect the long leg (anode, +) of the LED to one end of the 330Ω resistor
- Connect the other end of the resistor to GPIO17 (physical pin 11)
- Connect the short leg (cathode, −) of the LED to any GND pin (physical pin 9 or 14)
The resistor is essential — without it, the LED draws too much current and will either burn out or damage the GPIO pin. At 3.3V with a standard LED forward voltage of ~2V, a 330Ω resistor limits current to about 4mA, which is safe and bright enough to see clearly.
Code: Blink an LED
from gpiozero import LED
from time import sleep
led = LED(17) # BCM pin 17
while True:
led.on()
sleep(1)
led.off()
sleep(1)
Save this as blink.py and run it with python3 blink.py. You should see the LED blink once per second. Press Ctrl+C to stop.
The gpiozero library automatically cleans up GPIO resources when the script exits — no need for explicit cleanup calls. This is one of the many reasons it’s recommended for beginners.
Project 2: Reading a Button Press
Now let’s make the GPIO work the other way — reading an input from a physical button.
Components Needed
- 1× Tactile push button
- 1× 10kΩ resistor (pull-down resistor)
- Breadboard and jumper wires
Understanding Pull-Up and Pull-Down Resistors
When a button is not pressed, the GPIO input pin is “floating” — it’s not connected to anything and can randomly read as HIGH or LOW. A pull-down resistor (connected between the pin and GND) keeps the pin firmly at LOW when the button is open. When you press the button, the pin connects to 3.3V and reads HIGH.
Alternatively, a pull-up resistor (connected between the pin and 3.3V) keeps the pin HIGH when the button is open, and the button connects the pin to GND when pressed, reading LOW. The Raspberry Pi has built-in software pull-up and pull-down resistors, so you often don’t need an external resistor at all.
Circuit Connections
- Connect one side of the button to GPIO18 (physical pin 12)
- Connect the other side to 3.3V (physical pin 1)
- We’ll use the internal pull-down resistor in software
Code: Detect Button Presses
from gpiozero import Button
from signal import pause
button = Button(18, pull_up=False) # Internal pull-down enabled
def button_pressed():
print("Button pressed!")
def button_released():
print("Button released!")
button.when_pressed = button_pressed
button.when_released = button_released
print("Waiting for button presses... (Ctrl+C to exit)")
pause() # Keep the script running
Combining LED and Button
from gpiozero import LED, Button
from signal import pause
led = LED(17)
button = Button(18, pull_up=False)
button.when_pressed = led.on
button.when_released = led.off
print("Hold the button to light the LED")
pause()
This elegantly links the button directly to the LED — no if/else statements needed. Gpiozero’s event-driven approach makes GPIO code clean and readable.
Project 3: Controlling a Relay Module
Relays are electrically-operated switches that allow your Raspberry Pi to control high-voltage AC circuits (like a lamp or fan) using its low-voltage GPIO pins. This is how you build home automation systems with the Pi.
How a Relay Works
A relay has two circuits: a control circuit and a load circuit. When you send a signal to the control circuit, an electromagnet activates and physically moves a switch in the load circuit. This way, your Pi’s 3.3V GPIO can safely control 230V AC appliances.
Most relay modules sold for the Pi are active-LOW — they trigger when the control pin goes LOW (0V), not HIGH. Always check your specific module’s datasheet.
Components Needed
- 1× Single or dual channel relay module (5V, suitable for Raspberry Pi)
- Jumper wires
- Caution: If connecting to AC mains, use proper insulated connectors and exercise extreme caution. Never touch bare AC wires.
Circuit Connections
- Connect relay module VCC to Pi’s 5V pin (physical pin 2)
- Connect relay module GND to Pi’s GND pin (physical pin 6)
- Connect relay module IN (signal) to GPIO27 (physical pin 13)
Code: Switch a Relay
from gpiozero import OutputDevice
from time import sleep
# active_high=False because most relay modules are active-LOW
relay = OutputDevice(27, active_high=False, initial_value=False)
print("Relay demo: ON for 3 seconds, then OFF")
relay.on() # Activates the relay (closes the load circuit)
print("Relay ON")
sleep(3)
relay.off() # Deactivates the relay
print("Relay OFF")
Advanced GPIO Techniques
PWM (Pulse Width Modulation)
PWM lets you simulate analog output from a digital pin by switching it ON and OFF very rapidly. The ratio of ON to OFF time (duty cycle) controls the effective voltage. This is how you dim an LED or control a servo motor’s position.
from gpiozero import PWMLED
from time import sleep
led = PWMLED(17)
# Fade in
for brightness in range(0, 101, 5):
led.value = brightness / 100
sleep(0.05)
# Fade out
for brightness in range(100, -1, -5):
led.value = brightness / 100
sleep(0.05)
GPIO Interrupts and Edge Detection
Instead of constantly polling a pin’s state in a loop (which wastes CPU), you can set up interrupts that trigger a function when a pin changes state. Gpiozero’s when_pressed and when_released use interrupts internally. In RPi.GPIO, you’d use GPIO.add_event_detect().
I2C and SPI Protocols
The GPIO pins include dedicated I2C (pins 3 and 5) and SPI (pins 19, 21, 23, 24, 26) pins. These protocols allow you to connect many sensors and displays using just 2–4 wires. Enable them in raspi-config → Interface Options.
GPIO Safety Rules
Follow these rules to protect your Raspberry Pi from damage:
- Never exceed 3.3V on GPIO inputs. Use a voltage divider or logic level shifter for 5V devices.
- Maximum 16mA per GPIO pin, with a total of 50mA across all GPIO pins. Use transistors or MOSFETs for higher-current loads.
- Always use current-limiting resistors with LEDs.
- Use flyback diodes with inductive loads (motors, solenoids, relay coils) to suppress voltage spikes.
- Shut down properly before disconnecting GPIO wires. Hot-plugging pins with the Pi powered on can cause shorts.
- Double-check your wiring before powering on, especially if working near the 5V and GND pins.
Frequently Asked Questions
Can I use all 40 pins as GPIO?
No. Of the 40 pins, 8 are power pins (5V, 3.3V, GND) and some GPIO pins have dedicated functions like I2C, SPI, UART, and PWM. On a Raspberry Pi 5, you have up to 26 freely usable GPIO pins, though some share functions with communication buses. The pinout command shows which pins are available.
Why is my GPIO pin not working?
Common causes: wrong pin number (BCM vs board), floating input without a pull-up/down resistor, exceeded current limit, or using a 5V signal on a 3.3V pin. Also check that you’re not accidentally using a special-function pin (like GPIO2/3 for I2C) without enabling that interface in raspi-config.
Can I use GPIO while running a desktop GUI?
Yes. GPIO access in Python runs independently of the desktop environment. Just make sure you’re running your script as the pi user (not root), and gpiozero will handle permissions automatically via the underlying libgpiod or RPi.GPIO libraries.
How do I connect a 5V sensor to Raspberry Pi GPIO?
Use a resistor voltage divider (two resistors to reduce voltage) or a dedicated logic level converter/shifter module. For example, a 1kΩ and 2kΩ resistor in series will drop a 5V signal to 3.3V. Logic level converter modules (available for under ₹50) handle this more elegantly for bidirectional signals.
What’s the maximum number of GPIO devices I can connect?
Directly, you’re limited by available pins (26 usable) and current capacity (50mA total). However, using I2C you can address up to 127 devices on two pins, and SPI supports multiple devices with separate chip-select pins. For even more expansion, GPIO expander ICs like the MCP23017 add 16 GPIO pins over I2C.
Next Steps: Building Real Projects
Now that you understand the fundamentals of Raspberry Pi GPIO, you’re ready to build real projects. Some popular next steps for Indian makers:
- Home automation: Control fans, lights, and pumps via relay modules, triggered by sensors or a web interface
- Weather station: Connect a BME280 or DHT11 sensor, log data to a spreadsheet or database
- Security system: PIR motion sensor + relay + camera, send alerts via email or WhatsApp
- Soil moisture monitor: For rooftop gardens, trigger irrigation pumps automatically
The Raspberry Pi GPIO is a gateway to the physical world — once you understand how to control it, the possibilities are genuinely unlimited. Start small with LEDs and buttons, then work up to more complex projects as your confidence grows.
Ready to start your GPIO projects? Browse our full range of Raspberry Pi boards, sensors, and accessories at Zbotic.in — India’s trusted electronics components store with fast shipping across the country.
Add comment