The Raspberry Pi 5 introduced the RP1 southbridge chip, fundamentally changing how the gpio pins raspberry pi ecosystem handles I/O. Unlike the Pi 4, the Pi 5 routes GPIO through a dedicated silicon die, altering chip numbering, current delivery, and software backend requirements. If you are migrating older scripts or starting a new automation build, assuming the Pi 5 behaves exactly like the Pi 4 will result in immediate permission errors and potential hardware damage.

This guide provides the exact power specifications for the 40-pin header, a safe optocoupler-isolated relay project, complete Python code targeting the Pi 5, and the specific lgpio debugging steps required for Raspberry Pi OS (Bookworm and later).

Raspberry Pi 5 GPIO Power & Pinout Specifications

The most critical upgrade in the Pi 5 is the 5V power rail capacity. When paired with the official 27W USB-C PD power supply, the 5V pins can deliver up to 3A to external peripherals. However, the 3.3V rail remains strictly limited, and individual GPIO pins still cap at 16mA. Exceeding these limits will trigger the Pi 5's onboard brownout protection or permanently damage the RP1 chip.

Bench Tip: Never power a 5V relay coil directly from the Pi's 5V GPIO pins if the coil draws more than 50mA. Always use an external 5V supply or a module with an optocoupler and separate power input to isolate the inductive kickback from the RP1 silicon.
Table 1: Critical Raspberry Pi 5 40-Pin Header Power & Logic Limits
Physical Pin BCM / Function Type Max Current / Specifications
Pin 1 3.3V Power Power ~50mA total shared across all 3.3V outputs
Pin 2 5V Power Power Up to 3A (Requires official 5A/27W USB-C PD PSU)
Pin 11 BCM 17 (GPIO) Logic 3.3V logic level, 16mA max source/sink per pin
Pin 3 BCM 2 (SDA1) I2C Bus 3.3V logic; requires external pull-ups for 5V devices
Pin 6 Ground (GND) Return Shared ground return; use multiple pins for >1A loads

Project Build: Optocoupler-Isolated Relay Control

This project targets the Raspberry Pi 5 (8GB RAM) running Raspberry Pi OS Bookworm (64-bit). We will wire a 2-channel relay module to switch external loads safely. The difficulty is moderate, primarily due to the software backend changes in the Pi 5.

Difficulty: ★★☆☆☆ (Moderate) | Time: 45 Minutes | Cost: ~$95 (excluding Pi/PSU)

Parts List

  • Board: Raspberry Pi 5 (8GB RAM variant)
  • Power: Official Raspberry Pi 27W USB-C PD Power Supply (5V/5A)
  • Module: HiLetgo 2-Channel 5V Relay Module with Optocoupler Isolation
  • Wiring: 22 AWG solid core jumper wires (Dupont female-to-female)
  • Storage: 32GB+ microSD card (Class 10, A1 rated minimum)

Pin Mapping Table

Raspberry Pi 5 Pin BCM Number Relay Module Pin Function
Pin 2 5V VCC Powers the optocoupler LEDs and relay logic
Pin 6 GND GND Common ground reference
Pin 11 BCM 17 IN1 Control signal for Relay 1 (Active LOW)
Pin 13 BCM 27 IN2 Control signal for Relay 2 (Active LOW)

Wiring Steps

⚠️ SAFETY WARNING: The relay module's output side (COM, NO, NC) will be switching mains voltage (120V/240V AC). De-energize the mains circuit, verify dead with a CAT III multimeter, and lock out the breaker before wiring the load side. If you are not comfortable with mains wiring, use the relay to switch a 12V DC LED strip instead. Local electrical codes may require a licensed electrician for permanent mains connections.
  1. Power Down: Ensure the Raspberry Pi 5 is completely powered off and unplugged from the USB-C supply.
  2. Connect Power: Route a red 22 AWG wire from Pi Pin 2 (5V) to the Relay Module VCC pin.
  3. Connect Ground: Route a black 22 AWG wire from Pi Pin 6 (GND) to the Relay Module GND pin.
  4. Connect Logic: Route yellow wires from Pi Pin 11 (BCM 17) to IN1, and Pi Pin 13 (BCM 27) to IN2.
  5. Verify Jumper: Ensure the jumper cap on the relay module connects VCC to JD-VCC (this keeps the optocoupler powered from the Pi's 5V rail, which is safe for a 2-channel module drawing ~140mA total).
  6. Wire the Load: Connect your AC hot wire to the Relay COM terminal, and the switched hot to the NO (Normally Open) terminal. Leave the Pi's 5V/3.3V pins completely isolated from the load side.

The Code: Python Relay Controller with Error Handling

On the Pi 5, the legacy RPi.GPIO library is deprecated and largely broken. The official standard is gpiozero, which automatically uses the lgpio backend on Bookworm OS. Most standard 5V relay modules are Active LOW, meaning the relay engages when the GPIO pin is pulled to 0V. We configure gpiozero to handle this inversion natively.

#!/usr/bin/env python3
"""
Raspberry Pi 5 Relay Controller
Target: Raspberry Pi 5 (8GB) / Raspberry Pi OS Bookworm
Dependencies: sudo apt install python3-gpiozero python3-lgpio
"""

import sys
import time
from gpiozero import OutputDevice
from signal import pause

# --- Pin Definitions (BCM Numbering) ---
RELAY_1_PIN = 17
RELAY_2_PIN = 27

def initialize_relays():
    """Initialize OutputDevices with Active LOW logic for optocoupler relays."""
    try:
        # active_high=False means relay turns ON when pin goes LOW (0V)
        relay1 = OutputDevice(RELAY_1_PIN, active_high=False, initial_value=False)
        relay2 = OutputDevice(RELAY_2_PIN, active_high=False, initial_value=False)
        return relay1, relay2
    except Exception as e:
        print(f"[FATAL] Failed to initialize GPIO: {e}")
        print("Ensure you are running on a Pi 5 and lgpio is installed via apt.")
        sys.exit(1)

def main():
    relay1, relay2 = initialize_relays()
    
    print("Relay Controller Active. Press CTRL+C to exit safely.")
    
    try:
        while True:
            # Engage Relay 1
            relay1.on()
            print("Relay 1: ENGAGED (Pin LOW)")
            time.sleep(2)
            
            # Disengage Relay 1, Engage Relay 2
            relay1.off()
            relay2.on()
            print("Relay 1: DISENGAGED | Relay 2: ENGAGED")
            time.sleep(2)
            
            # Disengage Relay 2
            relay2.off()
            print("Relay 2: DISENGAGED. Cycle complete.")
            time.sleep(2)
            
    except KeyboardInterrupt:
        print("\n[INFO] Interrupt received. Safely shutting down relays...")
    finally:
        # gpiozero handles cleanup on exit, but explicit close is best practice
        relay1.close()
        relay2.close()
        print("[INFO] GPIO pins released. Exiting.")

if __name__ == "__main__":
    main()

Debugging: Fixing "Invalid Chip" and Permission Errors

The transition to the RP1 chip means the Pi 5 exposes its GPIO as gpiochip4 in the Linux kernel, whereas the Pi 4 used gpiochip0. If you are copying code from older forums or using pip-installed libraries, you will hit immediate errors.

The First Three Things to Check When It Fails

  1. Installation Method: Did you install gpiozero via pip or apt? On Pi 5 Bookworm, you must use sudo apt install python3-gpiozero python3-lgpio. Pip installations often fail to bind to the correct system-level lgpio C-bindings.
  2. OS Version: Are you actually running Raspberry Pi OS Bookworm (or newer)? Older Bullseye images do not have the kernel drivers for the RP1 chip and will fail to mount /dev/gpiochip4.
  3. User Permissions: Is your user account in the gpio group? Running as root (sudo) is a bad practice for daemon scripts. Verify with the groups command in terminal.

Ranked Causes for Specific Error Strings

Error String: PermissionError: [Errno 13] Permission denied: '/dev/gpiochip4'

  • Cause 1 (Most Likely): Your user lacks udev permissions for the RP1 GPIO chip. Fix: Run sudo usermod -aG gpio $USER, then log out and log back in.
  • Cause 2: A background service (like a poorly configured MQTT daemon) has already locked the GPIO pins. Fix: Check running processes with ps aux | grep python and kill the zombie script.

Error String: lgpio.error: 'gpiochip4' is not a valid chip

  • Cause 1 (Most Likely): You are using a Pi 4 or older board, but the code/environment is hardcoded or expecting a Pi 5 environment. Fix: Verify hardware with cat /proc/cpuinfo. On a Pi 4, the chip is gpiochip0.
  • Cause 2: The lgpio Python binding is outdated or installed via pip in a virtual environment without system site packages. Fix: Remove the pip version (pip uninstall lgpio) and rely strictly on the apt system package.

Extending and Simplifying the Build

Depending on your final application, you may need to scale this project up for home automation or strip it down for a simple bench indicator.

How to Simplify (Bench Testing)

If you don't have a relay module or want to test the GPIO logic safely without mains voltage, swap the relay for a standard 5mm LED. Wiring change: Connect the LED anode to BCM 17 via a 330Ω current-limiting resistor, and the cathode to GND. Code change: In the Python script, change active_high=False to active_high=True. Standard LEDs require a HIGH signal (3.3V) to illuminate, whereas the optocoupler relay required a LOW signal.

How to Extend (MQTT Smart Home Integration)

To integrate this relay controller into Home Assistant or Node-RED, replace the time.sleep() loop with an MQTT listener using the paho-mqtt library. Architecture: 1. Install the broker client: sudo apt install python3-paho-mqtt. 2. Subscribe to a topic like home/livingroom/fan/set. 3. Map the MQTT payload (ON/OFF) directly to relay1.on() and relay1.off(). This transforms the Pi 5 from a simple timer into a network-addressable IoT node, leveraging the Pi 5's upgraded PCIe-connected Wi-Fi/bluetooth capabilities for lower latency than the Pi 4.

For further reading on the RP1 silicon architecture and official pin multiplexing, refer to the Raspberry Pi Hardware Documentation and the gpiozero API reference.