To safely switch a 5V or 12V load using the Raspberry Pi Model A (or A+) GPIO, you must use a transistor driver circuit. The Pi’s BCM2835 chip outputs 3.3V logic and can only source roughly 16mA per pin, with a strict 50mA total bank limit. Connecting a 5V relay coil directly to a GPIO pin will draw 70mA+ at 5V, instantly frying the SoC. By using a 2N2222 NPN transistor and a 1kΩ base resistor, you can safely switch high-current loads while keeping the GPIO pin current under 3mA.
The Raspberry Pi A GPIO Reality: 3.3V Logic and Pin Limits
The original Raspberry Pi 1 Model A featured a 26-pin header, while the later Model A+ expanded this to 40 pins. Fortunately, the first 26 pins are electrically identical across both revisions, and the Pinout.xyz standard applies universally. However, the underlying BCM2835 silicon remains the same.
The most common bench mistake I see with the Pi A series is treating the 3.3V rail or the GPIO pins as power sources. The 3.3V regulator on the Model A/A+ is fed from the 5V input and is only rated for about 50mA of total draw across all 3.3V pins. If you are powering sensors, an I2C display, and a relay, you will brown out the board. Always power external 5V modules from the 5V rail (Pin 2 or 4), and use the GPIO pins strictly for logic-level signaling.
Decision Path: How to Drive Your Load
Before wiring anything, determine your switching strategy based on the load requirements. Use this decision tree to select the correct hardware interface.
| Load Type & Specs | Required Interface | Concrete Part Pick |
|---|---|---|
| < 16mA, 3.3V logic (e.g., LED, optocoupler input) | Direct GPIO with series resistor | 330Ω 1/4W Resistor |
| 16mA - 500mA, 5V/12V DC (e.g., small solenoid, fan) | NPN Transistor + Flyback Diode | 2N2222 Transistor + 1N4007 Diode |
| > 500mA, or Mains AC (120V/240V) | Transistor driving an Opto-isolated Relay | 2N2222 + Songle SRD-05VDC-SL-C Relay Module |
The Verdict: For 90% of home automation and DIY projects, you are switching a mains appliance or a 12V DC lock. Default to the third option: Use a 2N2222 transistor to drive a 5V opto-isolated relay module. This provides galvanic isolation, protecting your Pi from back-EMF spikes and mains noise.
Parts List and Wiring Spec Sheet
This build targets the Raspberry Pi 1 Model A+ (running Raspberry Pi OS Bookworm or later), but the BCM pin mapping and circuit apply to any 40-pin Pi variant. We are building a transistor-switched 5V relay to control a 12V DC solenoid lock.
| Component | Exact Variant / Value | Purpose |
|---|---|---|
| Microcontroller | Raspberry Pi 1 Model A+ (BCM2835) | Logic controller |
| Relay Module | Songle SRD-05VDC-SL-C (5V coil, 10A contacts) | Switches the high-power load |
| Transistor | 2N2222 (NPN, TO-92 package) | Amplifies 3.3V GPIO signal to switch 5V coil |
| Base Resistor | 1kΩ (1/4W, 5% tolerance) | Limits GPIO base current to ~2.6mA |
| Flyback Diode | 1N4007 (or built-in module diode) | Clamps inductive voltage spikes |
| Load | 12V DC Solenoid Lock | The target device being switched |
Pin Mapping Table (BCM Numbering)
Always use BCM (Broadcom) numbering in your code, as physical pin numbers change between the 26-pin Model A and 40-pin Model A+.
- GPIO 17 (Physical Pin 11): Connects to the 1kΩ resistor, which connects to the 2N2222 Base.
- 5V (Physical Pin 2): Connects to the Relay Module VCC and the 12V Solenoid positive supply.
- GND (Physical Pin 6): Connects to the 2N2222 Emitter, Relay Module GND, and 12V Solenoid negative supply.
Step-by-Step Wiring Procedure
- Prepare the Transistor: Identify the pins on the 2N2222 (flat side facing you: Emitter, Base, Collector from left to right).
- Wire the Base: Connect GPIO 17 (Pin 11) to one leg of the 1kΩ resistor. Connect the other leg to the Base (middle pin) of the 2N2222.
- Wire the Emitter: Connect the Emitter (left pin) directly to Pi GND (Pin 6).
- Wire the Collector & Relay: Connect the Collector (right pin) to the Relay Module's IN or GND pin (depending on module logic). Connect Pi 5V (Pin 2) to the Relay VCC.
- Install the Flyback Diode: If your relay module lacks a built-in flyback diode, solder a 1N4007 across the relay coil pins, with the diode's cathode (stripe) facing the 5V positive side. This is non-negotiable for inductive loads.
- Wire the Load: Connect your 12V power supply positive to the relay COM (Common) terminal. Connect the relay NO (Normally Open) terminal to the solenoid positive. Tie all grounds together.
Python Control Code (gpiozero)
Modern Raspberry Pi OS (Bookworm and later) has deprecated the legacy RPi.GPIO library in favor of gpiozero and the underlying lgpio character device interface. This code targets the Pi A+ but is fully forward-compatible with Pi 4 and Pi 5.
from gpiozero import OutputDevice
import time
import sys
# Define the GPIO pin using BCM numbering
# GPIO 17 corresponds to Physical Pin 11 on the header
RELAY_PIN = 17
# Initialize the relay.
# active_high=True means the pin goes HIGH (3.3V) to trigger the transistor.
relay = OutputDevice(RELAY_PIN, active_high=True, initial_value=False)
def cycle_solenoid(on_time=2.0, off_time=3.0, cycles=3):
"""Cycles the relay on and off with error handling."""
print(f"Starting solenoid cycle: {cycles} iterations.")
try:
for i in range(cycles):
print(f"Cycle {i+1}: Engaging solenoid...")
relay.on()
time.sleep(on_time)
print(f"Cycle {i+1}: Disengaging solenoid...")
relay.off()
if i < cycles - 1:
time.sleep(off_time)
except KeyboardInterrupt:
print("\n[!] Cycle interrupted by user (Ctrl+C).")
except Exception as e:
print(f"\n[!] Unexpected hardware error: {e}")
sys.exit(1)
finally:
# Ensure the relay is off and GPIO resources are released
relay.off()
relay.close()
print("[+] GPIO cleaned up. Relay secured in OFF state.")
if __name__ == "__main__":
cycle_solenoid(on_time=1.5, off_time=2.0, cycles=5)
Debugging: First Checks and the /dev/mem Error
When a GPIO circuit fails, don't immediately rewrite your code. Hardware and OS permission issues cause 95% of bench failures.
The First Three Things to Check
- Measure the 5V Rail: Put your multimeter probes on Pin 2 (5V) and Pin 6 (GND). You must read between 4.8V and 5.2V. If it reads 4.6V or lower, your Pi power supply is sagging under the relay coil load, causing the BCM chip to brown out and drop GPIO states.
- Verify Ground Continuity: With the Pi powered off, check for < 1Ω resistance between Pi Pin 6 and the GND terminal on your relay module. A missing common ground is the #1 reason transistors fail to switch.
- Test the Base Resistor: Pull the 1kΩ resistor and measure it. If you accidentally grabbed a 10kΩ resistor, the base current will be too low (~0.26mA) to saturate the 2N2222, leaving the relay chattering or failing to pull in.
Ranked Causes for the /dev/mem Error
If you are running older code or tutorials, you will likely hit this exact error string:
RuntimeError: No access to /dev/mem. Try running as root!
Why it happens: Legacy libraries like RPi.GPIO attempt to map the physical memory addresses of the BCM2835 peripherals directly using /dev/mem. Modern Linux kernels restrict this for security.
| Rank | Cause | Fix |
|---|---|---|
| 1 | Running legacy RPi.GPIO script without sudo. | Run with sudo python3 script.py or migrate to gpiozero (as shown above). |
| 2 | User is not in the gpio or dialout groups. | Run sudo usermod -aG gpio,dialout $USER and reboot. |
| 3 | SPI or I2C device tree overlays are hogging the pin. | Run sudo raspi-config and disable SPI/I2C if you aren't using them. |
Extending or Simplifying the Build
Depending on your project timeline and enclosure constraints, you can alter this build in two distinct directions.
How to Simplify (The Pre-Built Route)
If you want to skip the breadboard and transistor math, purchase a pre-wired Opto-isolated Relay Module (brands like Elegoo, HiLetgo, or Keyestudio sell these for ~$6 for a 2-pack). These boards have the PC817 optocoupler, the driver transistor, and the flyback diode already soldered onto the PCB. You simply wire three connections: VCC to 5V, GND to GND, and IN to GPIO 17. The Python code remains exactly the same.
How to Extend (Networked Control)
To turn this Pi A+ into a networked IoT node, extend the Python script using the paho-mqtt library. By connecting to an MQTT broker (like Mosquitto running on a Home Assistant server), you can trigger the solenoid remotely.
- Install the library:
sudo apt install python3-paho-mqtt - Subscribe to a topic like
home/office/door_lock. - When a payload of
"UNLOCK"arrives, trigger therelay.on()function for 2 seconds, then turn it off.
systemd services to ensure your relay defaults to a safe "locked" state on boot.





