I made this tutorial to show how I set up a 5V fan controlled by GPIO 23 on my Raspberry Pi 4 running LineageOS 23.
In my setup, the fan turns ON when GPIO 23 is HIGH and OFF when LOW, with an optional automatic fan script running at boot.
- Raspberry Pi 4 (GPIO output)
- 5V fan (cooler)
- NPN transistor 2N2222
- Optional diode 1N4007 (for protection)
- 330 Ω resistor (for transistor base)
Control the fan using GPIO 23: ON when HIGH, OFF when LOW.
The following diagram illustrates the wiring setup between the Raspberry Pi 4, the transistor, and the fan:
| Pin | Description |
|---|---|
| Emitter (E) | Small pin at one end |
| Base (B) | Middle pin |
| Collector (C) | Pin at other end |
Double-check your transistor datasheet; packages may vary.
- Red wire (+5V) → +5V power supply
- Black wire (−) → Collector (C) of 2N2222
- Emitter (E) → GND (common ground with Raspberry Pi)
- GPIO 23 → 330–470 Ω resistor → Base (B)
- Resistor protects GPIO by limiting current.
- Cathode (stripe) → fan +5V
- Anode → fan − / transistor collector
- Prevents voltage spikes from damaging the transistor.
- Fan red → +5V
- Fan black → Collector (C)
- Emitter → GND
- GPIO 23 HIGH (3.3V) → transistor conducts → fan ON
- GPIO 23 LOW (0V) → transistor off → fan OFF
| Component | Connect to | Notes |
|---|---|---|
| Fan + (red) | +5V | Power supply |
| Fan − (black) | Collector (C) of 2N2222 | NPN transistor switching side |
| Emitter (E) | GND | Common ground |
| GPIO 23 | Base (B) via 330–470 Ω resistor | Controls transistor |
| 1N4007 diode | Across fan, stripe to +5V | Optional protection |
This section sets up the fan control script to run automatically on boot.
Create fan_control.sh:
#!/system/bin/sh
ON_THRESHOLD=75
OFF_THRESHOLD=60
while true; do
TEMP=$(( $(cat /sys/class/thermal/thermal_zone0/temp) / 1000 ))
if [ "$TEMP" -ge "$ON_THRESHOLD" ]; then
gpioset gpiochip0 23=1
elif [ "$TEMP" -le "$OFF_THRESHOLD" ]; then
gpioset gpiochip0 23=0
fi
sleep 5
doneMake it executable:
chmod +x fan_control.shCreate fan_control.rc:
service fan_control /data/local/fan_control.sh
class main
user root
group root
disabled
seclabel u:r:init:s0
on property:sys.boot_completed=1
start fan_control- Connect to your Pi:
adb connect <YOUR_PI_IP>
adb root
adb remount- Push files:
adb push fan_control.sh /data/local/
adb push fan_control.rc /data/local/- Set permissions and move RC file:
adb shell
chmod 755 /data/local/fan_control.sh
mv /data/local/fan_control.rc /vendor/etc/init/
chcon u:object_r:vendor_file:s0 /data/local/fan_control.sh
chcon u:object_r:vendor_configs_file:s0 /vendor/etc/init/fan_control.rc
exitadb reboot
adb shell
getprop init.svc.fan_control- Expected output:
running - Your fan will now automatically turn on/off based on CPU temperature at boot.
- The script polls CPU temperature every 5 seconds.
- GPIO pin 23 must match your wiring.
- Optional diode protects the transistor from voltage spikes.
- Ensure root access is available, or the script will not control GPIO.
