GPIO (General Purpose Input/Output) pins are what make the Pi a physical computing platform. Today you'll control the physical world from Python.
The Raspberry Pi 5 has a 40-pin GPIO header. Not all pins are GPIO — some are 3.3V power, 5V power, or ground. GPIO pins operate at 3.3V logic (NOT 5V — connecting 5V directly will damage the Pi). Pins can be configured as input (read voltage state) or output (set voltage high/low). Some pins have special functions: UART, SPI, I2C, PWM — we'll use those in Day 3.
Digital output: set a pin HIGH (3.3V) or LOW (0V). Connect an LED with a 330Ω current-limiting resistor in series between the GPIO pin and ground. Without the resistor, you'll exceed the pin's 16mA max current and damage the GPIO controller. Use gpiozero (high-level) or RPi.GPIO (low-level). gpiozero is recommended — it handles cleanup automatically.
Digital input: read whether a pin is HIGH or LOW. Use the Pi's internal pull-up (pin pulled to 3.3V, button connects to ground) or pull-down resistors. PWM (Pulse Width Modulation): rapidly switch a pin on/off at a set frequency and duty cycle. 50% duty cycle = ~1.65V average. Use PWM to dim LEDs, control servo position, or set motor speed. Hardware PWM on GPIO12, 13, 18, 19 is more precise than software PWM.
#!/usr/bin/env python3
# GPIO examples: LED, button, PWM
# Run on Raspberry Pi: python3 gpio_demo.py
from gpiozero import LED, Button, PWMLED
from signal import pause
from time import sleep
# ── Digital Output: LED ─────────────────────────────────────
led = LED(17) # GPIO17, pin 11
# Simple blink
for _ in range(5):
led.on() # 3.3V
sleep(0.5)
led.off() # 0V
sleep(0.5)
# ── Digital Input: Button ───────────────────────────────────
btn = Button(27) # GPIO27, pin 13, internal pull-up enabled
print("Press button (GPIO27 to GND)...")
btn.wait_for_press(timeout=10)
print("Button pressed!")
# Event-driven: react to button
led2 = LED(17)
btn2 = Button(27)
btn2.when_pressed = led2.on
btn2.when_released = led2.off
# ── PWM: LED brightness ─────────────────────────────────────
pwm_led = PWMLED(18) # GPIO18 — hardware PWM capable
# Fade in
print("Fading LED...")
for v in [i/10 for i in range(11)]:
pwm_led.value = v # 0.0 to 1.0
sleep(0.1)
# Fade out
for v in [i/10 for i in reversed(range(11))]:
pwm_led.value = v
sleep(0.1)
pwm_led.off()
print("Done. GPIO cleaned up automatically by gpiozero.")
python3 traffic.py >> traffic.log 2>&1 &Connect a servo motor to GPIO18 (hardware PWM). Servos use 50Hz PWM signal: 1ms pulse = 0°, 1.5ms = 90°, 2ms = 180°. Use gpiozero's AngularServo class to sweep the servo from 0° to 180° and back. Then write a function that takes an angle as input and moves the servo to that position.