A lot of people uses fan to cool down their Raspberry Pi 4, but the fan’s noise is quiet problem (in a quiet room). In most case pi didn’t need that amount of cooling performance, so we can use PWM (Pulse Width Modulation) to control fan speed and reduce the noise.
I use Noctua NF-A4 5V PWM, a 40mm, 5V PWM fan. Here’s the wiring diagram:
- Yellow: 5V
- Black: GND
- Green: RPM signal
- Blue: PWM signal input
If your fan doesn’t support PWM control, then you can see #138 Variable Speed Cooling Fan for Raspberry Pi using PWM and PID controller or PWM Regulated Fan Based on CPU Temperature for Raspberry Pi to use a BJT transistor to use PWM control.
The fan’s RPM signal is an OC(Open-Collector) circuit design (in most fan), so you’ll need a pull-up resistor to measure output waveform according to Noctua PWM white paper.
Warning! The Pi has 3.3V GPIO, so your pull-up resistor must be connect to 3.3V ONLY! You will fry your Pi if Vcc is connected to 5V.
The pull-up resistor that I use is 1kΩ 1/4W. The white paper says the maximum current is 5mA. According to Ohm’s Law: $V=IR$, the resistor should be 660Ω or larger to protect your fan.
Most micro-controller or SBC already have a decent circuit to generate PWM signal, you don’t need special circuit to generate it.
I use a Molex 2510 4PIN (2.54mm) connector to connect the fan. (Need to cut out some fool-proof board to fit.)
Here’s a photo testing hardware and program on Pi 3B.`
The Pi4 haven’t update to latest version of wiring-pi yet, need to update it manually.
The latest version when I write this post is 2.52
Read GPIO status：
Set pin 1 to PWM mode (using wiring-pi pin number: Pi GPIO Pinout).
gpio mode 1 pwm
Set PWM signal (number from 0~1023)
gpio pwm 1 [number]
Check the fan is working as you expect.
The control script is on: DriftKingTW/Raspberry-Pi-PWM-Fan-Control
I use GPIO18 which is the hardware PWM(12/13 and 18/19) and all other pins are software PWM. Hardware PWM and the headphone jack use the same circuits, don’t use them at the smae time.
mkdir -p Scripts
Download the python script:
And make it auto start:
sudo vim /etc/rc.local
Add the following line before
exit 0 :
python /home/pi/Scripts/fan_control.py &
The route might be different for you. Make sure you’re using absolute path. The ‘&’ symbol means this script runs in background.
If you don’t want to know the theory part, than go ahead to: Reading RPM Signal
PWM uses square wave’s duty-cycle to reduce the average value of voltage, if the duty cycle is 50%, the fan will spin at 50% of it’s full speed; duty cycle 75%, fan 75%, and so on. More detail: Pulse-width modulation
And we can take a look at the control script:
import RPi.GPIO as GPIO
Run script and you will get RPM value every second:
import RPi.GPIO as GPIO