The Raspberry Pi 5 Pin Diagram: What Changed with the RP1 Chip?
When you first look at the Raspberry Pi 5 pin diagram, it appears mechanically identical to the Pi 4: the standard 40-pin header is right where you expect it, with the same 3.3V, 5V, and ground rail placements. However, under the hood, the architecture has fundamentally shifted. The BCM2712 application processor no longer handles GPIO directly. Instead, Raspberry Pi introduced the RP1 southbridge chip to manage all peripheral I/O, including the GPIO pins, I2C, SPI, and UART buses.
This architectural change means that while the physical pinout remains backward-compatible for hardware wiring, the software memory mapping is entirely different. Legacy GPIO libraries that hardcode BCM283x or BCM2711 peripheral base addresses (like older versions of RPi.GPIO) will fail or segfault on the Pi 5. To interact with the Pi 5 pinout successfully in 2026, you must use libraries updated to target the RP1 chip via the lgpio backend.
Project Build: I2C Environmental Monitor with GPIO Alert
To demonstrate the Pi 5 pinout in action, we will build a Smart Desk Environment Monitor. This project reads temperature and pressure data from an I2C sensor and triggers a physical LED alert when thresholds are exceeded, with a manual reset button. This exercises the Pi 5's I2C bus, digital output, and internal pull-up input configurations.
Parts List
- Board: Raspberry Pi 5 (8GB variant recommended for headless + desktop overhead), running Raspberry Pi OS Bookworm 64-bit.
- Power: Official Raspberry Pi 27W USB-C PD Power Supply (required to prevent brownout warnings on the Pi 5).
- Sensor: BME280 I2C Temperature/Humidity/Pressure breakout (Adafruit 2652 or generic 3.3V variant with onboard pull-ups).
- Output: 5mm Red LED and 330Ω current-limiting resistor.
- Input: 6x6mm tactile push button.
- Wiring: Female-to-female and male-to-female jumper wires (24 AWG copper).
Pin Mapping and Wiring Table
The following table maps the physical Raspberry Pi 5 pin diagram to our specific components. We are using the primary I2C bus (I2C1) and standard Broadcom (BCM) GPIO numbering, which the RP1 chip translates seamlessly when using modern libraries.
| Component | Board Pin (Physical) | BCM / Function | Wire Color (Suggested) |
|---|---|---|---|
| BME280 VIN | Pin 1 | 3.3V Power | Red |
| BME280 GND | Pin 6 | Ground | Black |
| BME280 SDA | Pin 3 | GPIO 2 (I2C1 SDA) | Blue |
| BME280 SCL | Pin 5 | GPIO 3 (I2C1 SCL) | Yellow |
| LED Anode (via 330Ω) | Pin 11 | GPIO 17 (Output) | Orange |
| LED Cathode | Pin 9 | Ground | Black |
| Tactile Button (Side A) | Pin 13 | GPIO 27 (Input, Pull-up) | Green |
| Tactile Button (Side B) | Pin 14 | Ground | Black |
Step-by-Step Wiring and OS Configuration
Before writing code, we must ensure the RP1 chip's I2C controller is exposed to the OS.
- De-energize the board: Unplug the USB-C power supply. Never wire I2C or GPIO pins while the Pi 5 is powered; the RP1 is sensitive to hot-plugging transients.
- Wire the I2C Bus: Connect the BME280 SDA to Pin 3 and SCL to Pin 5. Ensure your breakout board has 4.7kΩ pull-up resistors to 3.3V. If it doesn't, you will need to add them externally to prevent bus floating.
- Wire the GPIO Output: Connect Pin 11 to the 330Ω resistor, then to the LED's long leg (anode). Connect the short leg (cathode) to Pin 9 (GND).
- Wire the GPIO Input: Connect the tactile button across Pin 13 and Pin 14. We will enable the internal pull-up resistor in software, so no external resistor is needed.
- Enable I2C in OS: Boot the Pi 5, open a terminal, and run
sudo raspi-config. Navigate to Interface Options -> I2C -> Enable. Reboot the system. - Verify I2C Address: After reboot, run
sudo i2cdetect -y 1. You should see76or77in the grid, confirming the RP1 is successfully routing I2C traffic to the sensor.
Complete Python Code (RP1 Compatible)
This script targets the Raspberry Pi 5 running Bookworm. It explicitly forces the lgpio pin factory to bypass legacy memory-mapping errors and includes robust error handling for I2C bus failures.
Prerequisites: sudo apt install python3-rpi-lgpio python3-smbus2 and pip3 install bme280
import os
import sys
import time
import smbus2
import bme280
# CRITICAL FOR PI 5: Force the lgpio backend to talk to the RP1 southbridge
os.environ['GPIOZERO_PIN_FACTORY'] = 'lgpio'
try:
from gpiozero import LED, Button
except Exception as e:
print(f"Fatal Import Error: {e}")
print("Ensure rpi-lgpio is installed: sudo apt install python3-rpi-lgpio")
sys.exit(1)
# --- Pin Definitions ---
PIN_LED = 17
PIN_BUTTON = 27
I2C_BUS_ID = 1
BME280_ADDRESS = 0x76 # Change to 0x77 if your breakout uses the alt address
TEMP_THRESHOLD = 26.0 # Celsius
# --- Hardware Initialization ---
alert_led = LED(PIN_LED)
reset_btn = Button(PIN_BUTTON, pull_up=True, bounce_time=0.05)
alert_active = False
def handle_button_press():
global alert_active
if alert_active:
print("[INFO] Button pressed. Clearing alert.")
alert_active = False
alert_led.off()
reset_btn.when_pressed = handle_button_press
def read_sensor():
try:
bus = smbus2.SMBus(I2C_BUS_ID)
calibration_params = bme280.load_calibration_params(bus, BME280_ADDRESS)
data = bme280.sample(bus, BME280_ADDRESS, calibration_params)
bus.close()
return data.temperature, data.pressure
except FileNotFoundError:
print("[ERROR] I2C bus not found. Is I2C enabled in raspi-config?")
sys.exit(1)
except OSError as e:
print(f"[ERROR] I2C Communication failed: {e}. Check wiring to Pins 3 & 5.")
return None, None
def main():
global alert_active
print(f"[START] Monitoring environment. Threshold: {TEMP_THRESHOLD}C")
try:
while True:
temp, pressure = read_sensor()
if temp is not None:
print(f"Temp: {temp:.2f}C | Pressure: {pressure:.1f}hPa | Alert: {alert_active}")
if temp > TEMP_THRESHOLD and not alert_active:
alert_active = True
alert_led.on()
print("[ALERT] Temperature threshold exceeded!")
time.sleep(2.0)
except KeyboardInterrupt:
print("\n[EXIT] Graceful shutdown triggered.")
finally:
alert_led.close()
reset_btn.close()
if __name__ == "__main__":
main()
Debugging: First Three Things to Check When It Fails
Moving from a Pi 4 to a Pi 5 often results in immediate script crashes due to the RP1 transition. If your script fails on startup, check these ranked causes.
1. The Exact Error: gpiozero.exc.BadPinFactory: Unable to load any default pin factory!
Cause: The gpiozero library cannot find a compatible backend to talk to the Pi 5's RP1 chip. The legacy RPi.GPIO factory is either missing or incompatible with Bookworm on Pi 5.
Fix: Install the lgpio Python bindings via the OS package manager. Run: sudo apt update && sudo apt install python3-rpi-lgpio. The environment variable in our code will then successfully route commands through this factory.
2. The Exact Error: FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'
Cause: The I2C kernel module is not loaded, meaning the RP1 isn't exposing the bus to the Linux file system.
Fix: Run sudo raspi-config, enable I2C under Interface Options, and reboot. If it still fails, edit /boot/firmware/config.txt and manually add dtparam=i2c_arm=on.
3. Sensor Reads as 0.0 or -999.0
Cause: Missing I2C pull-up resistors. The RP1 chip's internal pull-ups for I2C are sometimes insufficient for longer wire runs or specific breakout boards.
Fix: Verify your BME280 breakout has physical 4.7kΩ surface-mount resistors near the SDA/SCL pins. If not, solder external pull-ups between the 3.3V line and both SDA/SCL lines.
Extending and Simplifying the Build
To Simplify: If you don't need physical alerts, strip out the gpiozero LED and Button logic. You can log the temp and pressure variables directly to a CSV file or push them to an MQTT broker using the paho-mqtt library, turning this into a headless data logger.
To Extend: The Raspberry Pi 5 pin diagram includes a dedicated 4-pin JST PWM fan connector (located near the USB-C port, separate from the 40-pin header). You can extend this project by plugging in the Official Active Cooler and using the vcgencmd terminal commands or the gpiozero PWMLED class mapped to the internal thermal zone to dynamically scale fan RPM based on the BME280's ambient temperature readings.
Raspberry Pi 5 Pinout FAQ
Are the Raspberry Pi 5 GPIO pins 5V tolerant?
No. The RP1 southbridge chip operates strictly at 3.3V logic levels. Applying 5V to any GPIO pin (including SDA/SCL) will likely cause permanent damage to the RP1 silicon. If you must interface with 5V logic (like an Arduino Uno or older relay modules), use a bidirectional logic level shifter (e.g., Texas Instruments TXB0108 or a standard MOSFET-based module).
Does the Raspberry Pi 5 have the same 40-pin header layout as the Pi 4?
Yes, mechanically and electrically (at a pinout level), the 40-pin header is identical to the Pi 4. Pin 1 is still 3.3V, Pin 2 is 5V, and the I2C/SPI/UART pins occupy the same physical locations. This ensures that physical HATs and wiring harnesses designed for the Pi 4 will fit the Pi 5 without modification. You can verify this in the official Raspberry Pi 5 datasheet.
Why do older Python GPIO scripts fail on the Raspberry Pi 5?
Older scripts typically rely on the RPi.GPIO library, which uses direct memory access to the BCM SoC's peripheral registers. Because the Pi 5 routes GPIO through the RP1 chip via PCIe, those memory addresses no longer exist. Modern scripts must use gpiozero (with the lgpio backend) or the raw lgpio Python library, which use the correct character device (/dev/gpiochip0) interface to talk to the RP1.
Where is the dedicated fan header on the Raspberry Pi 5 pin diagram?
The dedicated PWM fan header is not part of the 40-pin GPIO array. It is a separate 4-pin JST connector located on the board near the USB-C power input and the PCIe FFC connector. It provides 5V power, ground, a PWM control signal, and a tachometer feedback line, allowing the Pi 5's firmware to manage cooling without sacrificing standard GPIO pins.






