After mounting the GPIO hammer headers to my RPi Zero I am now ready to do some prototyping. The first thing I wanted to test is controlling a 4 pin PWM fan. So here is a short howto on that.
Besides a RPi Zero with pin headers you need a 4 pin PWM (Pulse With Modulation) fan. I took a Noctua NF-F12 5V fan. Be aware that when you take a 12V fan it will damage your board!
To easily access the RPi Zero during setup I use an USB to serial adapter cable as described in on of my other posts.
Prepare the SD card as usually. Usually before mounting an RPi Zero I put it into my Raspberry Pi 3 B+. Since that one has an ethernet connection I can update the system and install required libraries:
sudo apt update
sudo apt upgrade -y
sudo apt install -y python3-pip
sudo python3 -m pip install --upgrade pip
sudo pip3 install RPi.GPIO
Don't forget to change the default to something more secure.
The serial connection cables are connected as described in my other article linked above. So you are able to connect to it via screen
.
Wiring the fan is also straight forward:
- PIN 1: GND (brown)
- PIN 2: +5V (red)
- PIN 3: TACH (leave unconnected)
- PIN 4: PWM (orange)
For this test I use simple jumper cables to to wire the fan connector to the RPi zero header:
On the RPi Zero I connected the PWM pin to GPIO 17:
Since now all is wired here is how to control the fan with a simple python script:
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
# GPIO 17 for PWM fan control
fan_pin = 17
GPIO.setup(fan_pin, GPIO.OUT)
fan_pwm=GPIO.PWM(fan_pin, 50)
fan_pwm.start(50)
def fan_speed(percent):
fan_pwm.ChangeDutyCycle(percent)
def fan_off():
fan_speed(0);
# Turn off fan on startup
fan_off()
try:
for percent in range(10, 100, 5):
fan_speed(percent)
print("F:{:.0f}%".format(percent))
time.sleep(5.0)
except RuntimeError as error:
print(error.args[0])
except KeyboardInterrupt:
print("Interrupted.")
GPIO.cleanup()
First the pulse is set to a frequency of 50Hz which is sufficient for that fan. Then the fan is being turned of by setting its duty cycle to 0%. Step by step it increses by 5% until it reaches a duty cycle of 100%.
The output of the script will be as following:
$ python3 fan.py
F:10%
F:15%
F:20%
F:25%
F:30%
F:35%
F:40%
F:45%
F:50%
F:55%
F:60%
F:65%
F:70%
F:75%
F:80%
F:85%
F:90%
F:95%
F:100%
It would be a good idea to not set the duty cycle to less than 10-15% since the fan requires a certain level to start rotating.