If you need to know what Raspberry Pi do I have right this second, open your terminal and type cat /proc/cpuinfo | grep Revision. You will see a hex code (like c03112 or d04170). Cross-reference that code with the official Raspberry Pi revision code table to find your exact model, RAM size, and manufacturer.
But if you are building a headless kiosk, an automated test jig, or a fleet of IoT nodes, manually checking terminal outputs is not scalable. You need a programmatic way to identify the board variant on boot and verify that the GPIO header is actually functional. In this guide, we will build a Python-based Pi Model Identifier and GPIO Hardware Tester that reads the silicon revision code, prints the exact hardware specs, and flashes an LED to confirm the pinout is intact.
Project Spec Sheet & Parts List
| Parameter | Specification |
|---|---|
| Difficulty Rating | 2/5 (Beginner-Intermediate) |
| Estimated Time | 45 minutes |
| Target Board Variant | Raspberry Pi 4 Model B (4GB) & Raspberry Pi 5 (8GB) |
| OS Requirement | Raspberry Pi OS Bookworm (64-bit) or later |
| Python Version | Python 3.11+ (Pre-installed on Bookworm) |
Required Hardware
- Microcontroller: Raspberry Pi 4 Model B (any RAM variant) or Raspberry Pi 5. The code is backward compatible to the Pi 3B+.
- Storage: SanDisk Extreme 32GB microSD card (A2 application performance class for faster random I/O during boot).
- Power Supply: 5V 3A USB-C PSU for Pi 4, or an official 27W USB-C PD (5V 5A) PSU for Pi 5. Note: Using a standard 5V 3A phone charger on a Pi 5 will trigger a low-voltage warning and limit USB peripheral current to 600mA.
- Component: 1x 5mm standard LED (any color, 20mA max forward current).
- Resistor: 1x 330Ω through-hole resistor (1/4W).
- Wiring: 2x Female-to-Male (F-M) jumper wires.
Pin Mapping & Hardware Setup
We are using BCM (Broadcom) pin numbering, which is the standard for modern Raspberry Pi OS environments. Do not use physical board pin numbers (1-40) in the software configuration.
| Component Leg | BCM GPIO / Power | Physical Pin # | Wire Color (Suggested) |
|---|---|---|---|
| LED Anode (Long Leg) | GPIO 18 (PWM capable) | 12 | Orange |
| Resistor (Inline) | N/A (Series with Cathode) | N/A | N/A |
| LED Cathode (Short Leg) | GND | 14 | Black |
Wiring Steps
- De-energize the board: Unplug the USB-C power cable from the Raspberry Pi before touching the GPIO header.
- Connect the GPIO pin: Plug the female end of your orange jumper wire into Physical Pin 12 (BCM GPIO 18). Connect the male end to the breadboard row containing the LED anode.
- Insert the resistor: Plug one leg of the 330Ω resistor into the same row as the LED cathode, and the other leg into an empty ground rail row.
- Connect Ground: Plug the female end of your black jumper wire into Physical Pin 14 (GND). Connect the male end to the breadboard ground rail sharing the resistor.
- Verify: Visually trace the circuit from GPIO 18 -> LED Anode -> LED Cathode -> Resistor -> GND. Ensure the LED is not inserted backward.
- Power up: Reconnect the USB-C PSU and boot into the Raspberry Pi OS desktop or SSH terminal.
The Identifier & GPIO Test Code
This script targets Raspberry Pi OS Bookworm and utilizes the gpiozero library, which is the recommended GPIO interface for modern Pi environments. It reads the raw hex revision code from /proc/cpuinfo, maps it to a human-readable model name, and pulses the LED to confirm hardware continuity.
import os
import sys
import time
from gpiozero import LED
from gpiozero.exc import GpioZeroError
# --- PIN DEFINITIONS ---
# Using BCM GPIO 18 (Physical Pin 12)
TEST_LED_PIN = 18
led = None
# --- REVISION CODE LOOKUP TABLE ---
# Sourced from official Raspberry Pi documentation
REVISION_MAP = {
'a03111': 'Raspberry Pi 4 Model B - 1GB',
'b03111': 'Raspberry Pi 4 Model B - 2GB',
'c03111': 'Raspberry Pi 4 Model B - 4GB',
'c03112': 'Raspberry Pi 4 Model B - 4GB (Rev 1.2)',
'd03114': 'Raspberry Pi 4 Model B - 8GB',
'c04170': 'Raspberry Pi 5 - 4GB',
'd04170': 'Raspberry Pi 5 - 8GB',
'a22082': 'Raspberry Pi 3 Model B',
'a020d3': 'Raspberry Pi 3 Model B+',
'902120': 'Raspberry Pi Zero 2 W'
}
def get_pi_revision_code():
try:
with open('/proc/cpuinfo', 'r') as f:
for line in f:
if line.strip().startswith('Revision'):
return line.strip().split(':')[1].strip().lower()
except FileNotFoundError:
return None
except PermissionError:
return 'PERMISSION_DENIED'
return 'UNKNOWN'
def identify_board():
print('--- Raspberry Pi Hardware Identifier ---')
rev_code = get_pi_revision_code()
if rev_code == 'PERMISSION_DENIED':
print('Error: Cannot read /proc/cpuinfo. Check file permissions.')
return
if rev_code and rev_code in REVISION_MAP:
model_name = REVISION_MAP[rev_code]
print(f'[SUCCESS] Hex Revision: {rev_code}')
print(f'[SUCCESS] Identified Board: {model_name}')
else:
print(f'[WARNING] Hex Revision: {rev_code}')
print('[WARNING] Board not in local lookup table. Check official docs.')
def test_gpio_hardware():
global led
print('\n--- GPIO Hardware Continuity Test ---')
try:
led = LED(TEST_LED_PIN)
print(f'Initializing BCM GPIO {TEST_LED_PIN}...')
# Pulse 3 times to verify physical connection
for i in range(3):
led.on()
time.sleep(0.4)
led.off()
time.sleep(0.2)
print('[SUCCESS] GPIO pin drove HIGH successfully. LED flashed 3 times.')
print('Hardware header is functional.')
except GpioZeroError as e:
print(f'[FATAL] GPIO Initialization Failed: {e}')
print('First 3 things to check:')
print('1. Is the user in the gpio group? (Run: sudo usermod -aG gpio $USER)')
print('2. Are you using an outdated RPi.GPIO library on Pi OS Bookworm?')
print('3. Is the physical pin bent or shorted to the metal shield?')
except ValueError as e:
print(f'[FATAL] Invalid Pin Configuration: {e}')
except Exception as e:
print(f'[FATAL] Unexpected Error: {e}')
if __name__ == '__main__':
try:
identify_board()
test_gpio_hardware()
except KeyboardInterrupt:
print('\nTest interrupted by user.')
finally:
if led is not None:
led.close()
print('\nCleanup complete. GPIO resources released.')
Debugging: Common GPIO & Identification Errors
When working with bare-metal hardware access on Linux, permissions and library transitions are the most common failure points. If your script crashes, look for these exact error strings.
Error 1: 'PermissionError: [Errno 13] Permission denied: /dev/gpiomem'
This is the most common error on Raspberry Pi OS Bookworm when a standard user attempts to access the GPIO memory registers without proper group assignments.
- Cause 1 (Most Likely): Your current user is not in the
gpioordialoutsystem groups. Fix: Runsudo usermod -aG gpio $USERand reboot the Pi. - Cause 2: You are running the script via a cron job or systemd service that defaults to the
rootornobodyuser without inheriting the environment. Fix: AddUser=pi(or your specific username) to your.servicefile. - Cause 3: You are using an ancient version of the
RPi.GPIOlibrary which attempts to access/dev/meminstead of the safer/dev/gpiomem. Fix: UninstallRPi.GPIOand switch entirely togpiozerowith thelgpiobackend.
Error 2: 'ValueError: A physical pin is not a valid GPIO pin'
This error occurs when the pin factory receives a number it cannot map to the Broadcom SOC GPIO matrix.
- Cause 1 (Most Likely): You passed a physical board pin number (e.g.,
12for physical pin 12) but the library expects the BCM number (which is18for physical pin 12). Fix: Ensure you are using BCM numbering. Physical pin 12 = BCM GPIO 18. - Cause 2: You are trying to use a power pin (like Physical Pin 1 / 3V3) as a programmable GPIO output. Fix: Only use pins designated as GPIO in the pinout diagram.
Extending and Simplifying the Build
How to Extend: Add an I2C OLED Display
If you are building a headless node and want to display the Pi model and IP address without SSH-ing in, extend this build by adding a 128x64 SSD1306 I2C OLED display. Wire the display's VCC to 3V3 (Physical Pin 1), GND to GND (Physical Pin 6), SDA to GPIO 2 (Physical Pin 3), and SCL to GPIO 3 (Physical Pin 5). Install the adafruit-circuitpython-ssd1306 library via pip, and modify the identify_board() function to push the model_name string to the display buffer instead of just printing to the console.
How to Simplify: The Bash-Only Approach
If you do not need the GPIO hardware test and only want to identify the board in a startup script, strip out the Python code entirely. Use the native vcgencmd tool or standard shell parsing:
#!/bin/bash
# Simple Pi Identifier
REVISION=$(cat /proc/cpuinfo | grep 'Revision' | awk '{print $3}')
echo 'Board Hex Revision: '$REVISION
cat /proc/device-tree/model
echo ''
This bash snippet reads the device tree model string directly, which outputs human-readable text like 'Raspberry Pi 5 Model B Rev 1.0' without needing a Python dictionary lookup.
Frequently Asked Questions
How can I tell what Raspberry Pi I have without turning it on?
Look at the physical board layout and silkscreen text. If the board has blue USB ports, it is a Raspberry Pi 4. If it has a large metal shield over the CPU, a PCIe connector on the bottom left, and a small J5 connector for an RTC battery, it is a Raspberry Pi 5. If it has yellow composite video (RCA) jacks and black USB ports, it is a Pi 3B+ or older. Finally, check the white silkscreen text near the GPIO header; it usually explicitly states 'Raspberry Pi 4 Model B' or similar.
What Raspberry Pi do I have if the board has no markings or the silkscreen is faded?
Count the RAM chips on the top or bottom of the board and check the main processor silkscreen. A Pi 1 has 26 GPIO pins (early models) or 40 pins with a Broadcom BCM2835. A Pi Zero is half the size with a single micro-USB port. If you have a bare compute module (CM4), look for the two high-density board-to-board connectors on the back. When in doubt, power it up with a monitor attached; the boot splash screen will display the exact RAM and model variant.
Why does my Pi 5 show up as a generic BCM2712 in older scripts?
The Raspberry Pi 5 uses the new BCM2712 silicon, which features a completely different southbridge architecture (RP1 chip) compared to the BCM2711 in the Pi 4. Older Python libraries like RPi.GPIO were hardcoded to look for BCM283x/2711 memory addresses. When they fail to find the expected registers, they either crash or fallback to generic identifiers. Always use gpiozero with the lgpio backend on a Pi 5 to ensure the RP1 chip is addressed correctly via the standard Linux libgpiod API.
How do I check my Raspberry Pi model in Windows IoT or Ubuntu Server?
On Ubuntu Server, the cat /proc/cpuinfo command works exactly as it does on Raspberry Pi OS. On Windows IoT Core, open PowerShell and run Get-ComputerInfo | Select-Object CsModel, or check the 'Device Portal' web interface by navigating to the Pi's IP address on port 8080 in your browser. Note that Windows IoT is largely deprecated for newer Pi models, and Ubuntu Server is the recommended alternative for non-Raspbian Linux environments.






