If you are staring at a bare circuit board asking what to use Raspberry Pi for, you are likely confusing a single-board computer (SBC) with a microcontroller. You do not use a Raspberry Pi to read a simple DHT22 temperature sensor and deep-sleep for 10 minutes; an ESP32-C3 does that for $3 and 10 microamps. You use a Raspberry Pi when your project requires a full operating system, local database management, heavy compute (like OpenCV vision), or simultaneous multi-protocol bridging (like running an MQTT broker, a web dashboard, and Zigbee2MQTT at the same time).
This guide cuts through the noise. We will run a decision matrix to select the exact board variant for your needs, then build a foundational project that highlights the Pi's true strengths: a local MQTT-to-GPIO relay hub running on the latest Pi OS Bookworm.
The 'What to Use Raspberry Pi For' Decision Matrix
Before buying hardware, map your project requirements to the silicon. Use this decision tree to terminate on a specific board.
| Project Requirement | Choose This Board | Why Not the Alternative? |
|---|---|---|
| Need deep sleep (<1mA), battery powered, simple sensor polling | ESP32-C3 or Arduino Nano 33 BLE | Pi Zero draws ~120mA at idle. It will kill a 18650 cell in days. |
| Need local machine learning, computer vision, or frigate NVR | Raspberry Pi 5 (8GB) | Microcontrollers lack the RAM and PCIe bandwidth for ML inference. |
| Need a headless local smart-home brain (MQTT + Node-RED + GPIO) | Raspberry Pi Zero 2 W | Pi 4/5 is overkill and runs too hot for enclosed DIN-rail mounts. |
| Need a portable handheld retro-gaming or kiosk display | Raspberry Pi 400 or Pi 4B (4GB) | Zero 2 W lacks the raw GPU throughput for smooth 1080p60 UI rendering. |
Project Build: Local MQTT-to-GPIO Relay Hub
To demonstrate the Pi's multitasking capability, we are building a local hub. It runs an Eclipse Mosquitto MQTT broker and a Python script that listens for MQTT payloads to toggle physical relays. This is the backbone of a DIY smart home that doesn't rely on cloud servers.
Exact Parts List
- SBC: Raspberry Pi Zero 2 W with pre-soldered 40-pin header ($15-$20)
- Storage: 32GB Samsung EVO Plus microSD card (A2 rated for OS longevity) ($9)
- Power: Official Raspberry Pi 27W USB-C Power Supply (Crucial for stable 5V rail) ($12)
- Relay Module: Sunfounder 3.3V 2-Channel Relay Module with optocouplers (Model: SRD-03VDC-SL-C) ($8)
- Wiring: 22 AWG solid core hookup wire, female-to-female Dupont jumpers
Wiring and Pin Mapping
A common mistake when asking what to use Raspberry Pi for is treating its GPIO like an Arduino's. The Pi's GPIO operates at 3.3V logic. If you buy a standard 5V relay module, the 3.3V output from the Pi will not provide enough forward voltage to trigger the optocoupler's internal LED reliably, resulting in chattering or dead relays. You must use a 3.3V-specific relay module.
| Pi Zero 2 W Pin (Physical) | BCM GPIO Number | Relay Module Pin | Function |
|---|---|---|---|
| Pin 1 | 3V3 Power | VCC | Powers the optocoupler LEDs |
| Pin 6 | Ground | GND | Common ground reference |
| Pin 11 | GPIO 17 | IN1 | Logic trigger for Relay 1 |
| Pin 13 | GPIO 27 | IN2 | Logic trigger for Relay 2 |
The Python Control Script (Bookworm Compatible)
Pi OS Bookworm (Debian 12) deprecated the legacy RPi.GPIO library. If you try to use it on a Pi 5 or a fresh Bookworm install, you will get kernel access errors. We use gpiozero (which leverages the lgpio backend) and paho-mqtt v2.0.
Prerequisites: Run sudo apt install python3-gpiozero python3-paho-mqtt mosquitto and enable the broker with sudo systemctl enable --now mosquitto.
import paho.mqtt.client as mqtt
from gpiozero import OutputDevice
import logging
import signal
import sys
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# --- PIN DEFINITIONS ---
# Using BCM numbering (default for gpiozero)
RELAY_1_PIN = 17 # Physical Pin 11
RELAY_2_PIN = 27 # Physical Pin 13
# Initialize Relays (Active High for Sunfounder 3.3V modules)
relay1 = OutputDevice(RELAY_1_PIN, active_high=True, initial_value=False)
relay2 = OutputDevice(RELAY_2_PIN, active_high=True, initial_value=False)
# MQTT Configuration
BROKER_IP = '127.0.0.1'
BROKER_PORT = 1883
TOPIC_SUB = 'home/relays/#'
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code == 0:
logging.info(f'Connected to MQTT broker at {BROKER_IP}')
client.subscribe(TOPIC_SUB)
else:
logging.error(f'Connection failed with code: {reason_code}')
def on_message(client, userdata, msg):
try:
payload = msg.payload.decode('utf-8').strip().upper()
logging.info(f'Received [{msg.topic}]: {payload}')
if msg.topic == 'home/relays/1/set':
if payload == 'ON': relay1.on()
elif payload == 'OFF': relay1.off()
else: raise ValueError('Invalid payload')
elif msg.topic == 'home/relays/2/set':
if payload == 'ON': relay2.on()
elif payload == 'OFF': relay2.off()
else: raise ValueError('Invalid payload')
except Exception as e:
logging.error(f'Error processing message: {e}')
def on_disconnect(client, userdata, flags, reason_code, properties):
logging.warning(f'Disconnected from broker (Reason: {reason_code}). Attempting auto-reconnect...')
def graceful_exit(signum, frame):
logging.info('Shutting down relays and exiting...')
relay1.off()
relay2.off()
client.disconnect()
sys.exit(0)
# Signal handlers for clean shutdown
signal.signal(signal.SIGINT, graceful_exit)
signal.signal(signal.SIGTERM, graceful_exit)
# Paho MQTT v2.0 requires explicit API version declaration
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id='pi_relay_hub')
client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect
if __name__ == '__main__':
try:
client.connect(BROKER_IP, BROKER_PORT, keepalive=60)
client.loop_forever()
except Exception as e:
logging.critical(f'Fatal error starting MQTT loop: {e}')
relay1.off()
relay2.off()
Debugging: When the Relay Won't Click
When building embedded Linux projects, the abstraction layers between Python, the OS, and the silicon can hide faults. Here is the exact decision path for the three most common failures.
Error 1: ConnectionRefusedError: [Errno 111] Connection refused
- Cause A (Most Likely): The Mosquitto broker service is not running or crashed.
- Cause B: Mosquitto is bound only to localhost but your script is querying a different IP, or a firewall is blocking port 1883.
- Fix: Run
systemctl status mosquitto. If inactive, runsudo systemctl restart mosquitto. Verify the listener withnetstat -tlnp | grep 1883.
Error 2: gpiozero.exc.GPIOPinInUse: pin 17 is already in use
- Cause A: A previous instance of your Python script crashed without releasing the GPIO pins (zombie process).
- Cause B: Another peripheral (like an I2C or SPI overlay in
/boot/firmware/config.txt) is claiming BCM 17. - Fix: Kill zombie python processes with
sudo killall python3. Checkconfig.txtto ensure no dtoverlay is conflicting with GPIO 17.
Error 3: Relay chatters or stays permanently ON
- Cause A: You are using a 5V relay module on the 3.3V Pi GPIO. The optocoupler LED isn't getting enough forward voltage to fully switch, leaving it in a high-impedance floating state.
- Cause B: The
active_highparameter ingpiozerois inverted for your specific relay board (some modules trigger on LOW). - Fix: Swap to a true 3.3V relay module. If the logic is inverted, change
active_high=Truetoactive_high=Falsein the Python script.
1. Service Status: Is Mosquitto actually running? (
systemctl status mosquitto)2. Voltage Rail: Put your multimeter on Physical Pin 1 (3.3V) and Pin 6 (GND). If it reads below 3.2V under load, your power supply is browning out and the Pi is throttling GPIO current.
3. Port Binding: Run
lsof -i :1883 to ensure no other service (like Home Assistant) has hijacked the MQTT port.
Extending or Simplifying the Build
Knowing what to use Raspberry Pi for means knowing when to scale the hardware up or down based on the project's evolution.
How to Simplify (Drop the MQTT)
If you realize you don't need a message broker and just want to toggle the relay from a web browser on your phone, strip out the Paho MQTT library. Install Flask (pip install flask) and create a simple HTTP GET route (/toggle/1) that calls relay1.toggle(). This reduces system overhead and eliminates the need to manage the Mosquitto daemon.
How to Extend (Add Zigbee and Dashboards)
If this hub is destined to be the brain of a whole-house off-grid or smart home setup, the Pi Zero 2 W can handle more protocols. 1. Plug a Sonoff Zigbee 3.0 USB Dongle Plus (P-Version) into the Pi's micro-USB port via an OTG adapter. 2. Install Zigbee2MQTT via Docker. 3. Install Node-RED to visually wire your Zigbee motion sensors to the Python-controlled GPIO relays. At this point, you have justified the use of the Pi over an ESP32: you are running a Linux container stack, a radio protocol bridge, and a hardware GPIO controller simultaneously.
For deeper reading on the underlying libraries used in this build, consult the official gpiozero documentation for Bookworm compatibility notes, and the Eclipse Mosquitto manual for securing your local broker with TLS and passwords.






