The following answer addresses a Hardware and Software approach, and an Easier alternative requiring only hardware & a configuration change. This project may be of interest. The author uses a simple bash
script to read the RPi CPU temperature, and turn a cooling fan on and off based on the temperature. In other words, the fan only runs when the CPU temperature rises above the value you set in the bash
script that controls it.
Hardware
The hardware requirement is simple enough: a 2N2222 transistor serves as a switch to turn the cooling fan on & off. The 2N2222 is driven from a GPIO pin. A ~500𝛀 resistor to bias the transistor properly, and a small diode for back emf protection completes the circuit.
The author has created a YouTube video illustrating the hardware construction. IMHO, this is more elaborate than necessary, but here's a schematic showing the essentials:
simulate this circuit – Schematic created using CircuitLab
Software
The software is not well documented in this project. The author failed to mention that the wiringpi
library must be installed to get the GPIO utility - which is the software that makes this project work. And finally, you must read this page to learn that wiringpi
must be updated to work on the RPi 4B:
cd /tmp
wget https://project-downloads.drogon.net/wiringpi-latest.deb
sudo dpkg -i wiringpi-latest.deb
# verify a successful upgrade via:
gpio -v
gpio version: 2.52
Copyright (c) 2012-2018 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty
If you've followed this so far, and have read Mr. Drogon's news, you'll know that although wiringpi
still works today, sadly, it has been deprecated. The availability of his source code is unknown, but may be available.
Once you've installed & updated wiringpi
as described above, you can run the bash
script, also shown here for completeness:
#!/bin/bash
ontemp=48
gpio -g mode 3 out
temp=$(vcgencmd measure_temp | egrep -o '[0-9]*\.[0-9]*')
echo $temp #use BCM pin 3, as pin 2 is used for PSU control
temp0=${temp%.*}
echo $temp0
if [ $temp0 -gt $ontemp ]
then
echo greater than $ontemp fan on
gpio -g write 3 1
else
echo less than or equal to $ontemp fan off
gpio -g write 3 0
fi
Copy this to your editor, save it as temp-fan.sh
in your home directory, and make it executable (chmod 755 temp-fan.sh
). You should test it before connecting the hardware to verify that everything is in place. If you have a voltmeter you can monitor the GPIO output voltage. Once you've verified things are working, create a cron job
to run periodically to check your RPi temp and start the fan if it's temperature has exceeded your limit. To create the cron
job:
crontab -e
# editor opens; add the following to the bottom of the crontab file:
* * * * * /home/pi/temp-fan.sh >> /home/pi/temp-fan.log 2>&1
# Save and close the editor.
This will load your new cron
job, and it will execute every minute. Any errors will be written to the file /home/pi/temp-fan.log
. If once per minute is too frequent, you can change that (ref the crontab guru), for example to run once every 5 minutes:
*/5 * * * * /home/pi/temp-fan.sh >> /home/pi/temp-fan.log 2>&1
An even easier way to do this:
As mentioned in one of the other answers here, it is not necessary to install wiringpi
, nor even to create this bash script & associated cron
job. You may use a device tree overlay:
From /boot/overlays/README
on your RPi:
Name: gpio-fan
Info: Configure a GPIO pin to control a cooling fan.
Load: dtoverlay=gpio-fan,=
Params:
gpiopin GPIO used to control the fan (default 12)
temp Temperature at which the fan switches on, in
millicelcius (default 55000)
To switch the fan on at 48℃ with GPIO 17 (pin # 11 on the header) requires only the addition of the following line to your file /boot/config.txt
:
dtoverlay=gpio-fan,temp=48000,gpiopin=17
IMHO, while this approach is easier, it gives up some ground in terms of learning opportunities. But there it is - your choice.
Let us know if you have questions.