My 5V RaspberryPi fan was very loud and annoying, so I wanted a solution to regulate the fan depending on the Pi temperature.
To achieve that, I used a mosfet switch, pulled out from an old computer motherboard, followed by some easy bash scripting.
Almost any mosfet from an old computer motherboard should work.
Wiring:
You can use any not used GPIO to connect the gate pin, in the picture above it’s #23.
I connected the mosfet pin to GPIO 19 in my case. You can choose your own.
Software:
sudo apt-get update sudo apt-get install bc
Enable selected GPIO pin, In my case, GPIO 19
echo "19" > /sys/class/gpio/export echo "out" > /sys/class/gpio/gpio19/direction
If you wan’t to select another GPIO and you already exported one GPIO, you need to unexport previous GPIO.
echo "19" > /sys/class/gpio/unexport
Bash script for controlling fan “speed”:
pico rpipwm.sh
Paste the script bellow, edit your GPIO pin and save:
#!/bin/bash
#Poor man's PWM
#16.11.2015 by S55MA
#Quick and dirty script for controlling fan speed on RaspberryPI
#No rights reserved
#Define GPIO pin
pin="19"
while true; do
#Read temp
temp=$(cat /sys/class/thermal/thermal_zone0/temp | awk 'NR == 1 { print $1 / 1000}' | cut -c -4)
#If temperature is equal or lower than 39.99, the fan will stop spinning
if [[ $(bc <<< "$temp <= 39.99") == 1 ]] ;
then
$(echo "0" > /sys/class/gpio/gpio$pin/value)
fi
#If temperature is between 40 and 42.99, the fan will start with 1 second burst and 1 second sleep
if [[ $(bc <<< "$temp >= 40 && $temp <= 42.99") == 1 ]] ;
then
$(echo "1" > /sys/class/gpio/gpio$pin/value; sleep 1; echo "0" > /sys/class/gpio/gpio$pin/value; sleep 1)
fi
#If temperature is between 43 and 47.99, the fan will start with 1 second burst and 0.5 second sleep
if [[ $(bc <<< "$temp > 43 && $temp <= 47.99") == 1 ]] ;
then
$(echo "1" > /sys/class/gpio/gpio$pin/value; sleep 1; echo "0" > /sys/class/gpio/gpio$pin/value; sleep 0.5)
fi
#If temperature is equal or higher than 48, the fan will start spinning constantly
if [[ $(bc <<< "$temp >= 48") == 1 ]] ;
then
$(echo "1" > /sys/class/gpio/gpio$pin/value)
fi
sleep 0.1
done
chmod +x rpipwm.sh
./rpipwm.sh
Enable auto start at boot:
sudo cp rpipwm.sh /etc/init.d/rpipwm.sh
sudo chmod +x /etc/init.d/rpipwm.sh
sudo update-rc.d /etc/init.d/rpipwm.sh defaults
or you can use crontab:
crontab -e
Add and save:
@reboot /path/to/script/rpipwm.sh
sudo update-rc.d cron defaults




