5

I wish to control a 4 pin 12V dc pc fan (https://www.arctic.ac/en/F9-PWM/AFACO-090P2-GBA01) with my raspberry pie. After reading several threads I came up with the following:

First problem is that the PWM signal must be 5V but the GPIOs only give 3.3V. So I decided to use a level shifter from 3.3V to 5V (https://www.amazon.com/-/de/dp/B07LG646VS/ref=sr_1_3?dchild=1&keywords=level+shifter&qid=1605728038&sr=8-3) to feed a 5V PWM signal to the fan. Other than that I connected an external 12V dc power supply to the fan (first two pins on the fan connector).

The only thing left to do is to connect the GPIO pin which I use for the PWM signal to the 4th pin of the fan. In the end my circuit looks like the one from this tutorial: https://www.raspberrypi-spy.co.uk/2018/09/using-a-level-shifter-with-the-raspberry-pi-gpio/ except that I don´t use a 5V sensor but the 5V PWM input of the fan. So the PWM signal wire is the only connection between the pie and the fan.

Good thing is that the fan is running (at full speed) when I connect the power supply. I use the following code to vary the duty cycle.

import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)

GPIO.setmode(GPIO.BCM)
GPIO.setup(12, GPIO.OUT)

p = GPIO.PWM(12, 25000)
p.start(0)

time.sleep(2)

try:
    while True:
        p.ChangeDutyCycle(100)
        print('100')
        time.sleep(5)
        p.ChangeDutyCycle(50)
        print('50')
        time.sleep(5)
        p.ChangeDutyCycle(0)
        print('0')
        time.sleep(5)
            
except KeyboardInterrupt:
    pass

p.ChangeDutyCycle(0)
p.stop()
GPIO.cleanup()

When I connect the fan to the dc power supply, connect the 5V PWM signal and start the script the fan will continue to run at full speed, no matter what.

To test if my circuit is wrong I installed a LED which gets the 5V PWM signal as the positive voltage. The LED changes from 100% brightness to 50% and then switches off as expected.

I tested every connection line of the four from the level shifter. I tested another fan. I switched to other GPIOs. Unfortuntely it´s always the same result. LED works perfectly. Fan runs at full speed all the time.

I really like the idea of using a level shifter. It´s a compact and simple solution for me. So my question is if somebody has an idea where the problem is and how to solve it.

A second question related to this is if it would be beneficial to use a L298n motor driver for fan control.

2
  • 3
    it is not raspberry pie
    – jsotola
    Nov 19, 2020 at 2:10
  • A simple solution would be to use a MOSFET where the gate is connected to the PI, which has a 10K pull down resistor. The Pi and 5V grounds are connected to each other. The drain connects to the - of the fan and the + goes to 12V. You can also just connect it to the PWM input of the smart fan.
    – Gil
    Mar 7 at 5:56

4 Answers 4

2

You need to connect a ground wire between the Pi and the fan. Otherwise the PWM signal will have no effect as the fan will not know when the signal is high or low.

I doubt that software timed PWM will actually manage 25 kHz. I don't know how the fan will react at the likely frequency of about 10 kHz (depending on the Pi model being used).

3
  • Thanks a lot for the helpful answer! it solved the problem.
    – Kai
    Nov 19, 2020 at 17:31
  • 1
    Additionally for other people who will read this, the PWM control on this fan also works with the 3.3V output of the GPIO pins. So the level shifter is not even necessary.
    – Kai
    Nov 19, 2020 at 19:49
  • @Kai: There are many "fan questions" here. These fan projects serve a useful purpose as learning projects. I'm posting this as a suggestion to you: Please add your own answer here with a clear schematic that shows how you wired the fan to the RPi, and the code you used. That would be very useful, and I'd certainly up-vote a clear answer accompanied with working code and schematic. I suspect others would also. Here's the link to the schematic if you need it.
    – Seamus
    Nov 19, 2020 at 20:55
5

Since everything is working now I want to post a summary of how I am controlling a 12V fan with my Pi.

My Hardware for this is:

  • 1x KeeYees 4-channel IIC I2C level shifter from 3.3V to 5V
  • 1x Artic F9 PWM fan
  • 1x 12V dc power supply

This is how my circuit looks like:

schematic

simulate this circuit – Schematic created using CircuitLab

I figured that you could skip the level shifter and feed the 3.3V PWM signal from the GPIO directly to the fan. But it is less stable from my experience. Sometimes the fan will go to full speed as if no PWM signal is present while controlling the fan. So I recommend using a level shifter.

I wrote the following script for testing (you may have to change the GPIO pin number):

import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)

GPIO.setmode(GPIO.BCM)
GPIO.setup(12, GPIO.OUT)

p = GPIO.PWM(12, 1000)
p.start(0)

time.sleep(2)

try:
    while True:
        p.ChangeDutyCycle(100)
        print('100')
        time.sleep(5)
        p.ChangeDutyCycle(50)
        print('50')
        time.sleep(5)
        p.ChangeDutyCycle(0)
        print('0')
        time.sleep(5)
            
except KeyboardInterrupt:
    pass

p.ChangeDutyCycle(0)
p.stop()
GPIO.cleanup()

If everything is working fine the fan should turn on after 2 seconds at full speed. After 5 seconds it should throttle down to 50% and after another 5s it sould stop. Until the script is interrupted this loop will stay active.

I hope this helps anybody who is new to this stuff and wants to start up an easy PWM fan control for his project.

0

In addition to @Kai 's answer, I'm sharing my experience using PWM fan but with Super6C with CM4 modules.

My configuration:

  • 1x Super6C with 5 CM4
  • 1x KeeYees 4-channel IIC I2C level shifter from 3.3V to 5V
  • 1x ARCTIC P12 Slim PWM PST (12v)

For PWM signal, I'm using the first CM4's GPIO18 (the only port available in Super6C per each CM4 module). I've updated Kai's script from the answer to use GPIO18 instead of GPIO12.

Below is the Super6C first CM4 module and level shifter configuration: enter image description here enter image description here

Super6C CM4 $1 Level Shifter
5V_CM4 HV
3V3_CM4 LV
GND GND
GPIO18 LV1

enter image description here

PWM fan Level Shifter
GND GND
12v not connected!!!, leave it as is
Tach not connected!!!, leave it as is
PWM HV1

Notes:

  • you can use any LVx-HVx combo (e.g. LV4-HV4 instead of LV1-HV1)
  • Level shifter has two GND (upper and lower rows) but it doesn't matter which one you connect FAN GND or CM4 GND to - upper and lower level shifter's GND are the same GND.
  • you can use any CM4 module (1-6) to control PWM FAN. I used $1.
  • you could potentially connect FAN TACH to other module's GPIO18 to get FAN speed via GPIO18 to LV3 and HV3 to TACH. It's not required for PWM to work and is out of the scope of my answer :).

The major caveat I had is not every PWM fan stops when p.ChangeDutyCycleis called with 0. For instance, ARCTIC P12 Slim PWM spins at 200 RPM for when p.ChangeDutyCycle(0). Apparently, stop mode was removed since many customers thought that they fan was defective because it didn't spin :D. I spent quite a bit of time debugging since I expected my fan to stop at some point using Kai's script.

I'd highly recommend to use 5v LED with 330Om resistor to troubleshoot any issues:

  • run the script
  • connect wire #1 to GPIO18 and wire #2 to GND on Super6c.
  • the LED should be on, dimmed and then off in cycles.

Note: to determine polarity and test your configuration, connect LED + resistor to 3V3_CM4 and GND.

I hope it helps.

0

To build on the others from this post I was able to get a 12v pwm notuca fan working with the pi's 3.3V pwm output using the diagram below and by using a p and n mos setup in basic inverter config. i used a irf9540 (pmos) and irf540N (nmos). This is probably more complex than it needed to be but the logic was to use a 5v power supply to drive the 5v pwm signal the fan requires and use a 12v supply for the fan.

i also want to point out some things that might be obvious to some but not so common sense to beginner hobbies, I found out things are backwards and double backwards (in my learning style 2 backward's didn't give me a straight forward haha yay for learning) then what i thought they should be. To my understanding this is due to the pnp or pmos transistor in the fan for regulating the pwm signal. In an attempt to not get to lost i would highly suggest making the below circuit with and LED and turn it off and on so you can get your bearings then add the fan and pwm signal wire. with a basic understanding on pwm i thought code wise i would have a pretty wide range but i found out for my fan and circuit my pwm sweet spot is in between about 5.3% and about 6.3% i'm assuming these percentages are duty cycle and might have other factors i'm currently unaware but this should still get ya started. Those were the big two take a ways for me.

For my project i'm trying to build a rpi3 fan and water pump controller for my crypto-mining cooling system. it contains two 24" barrel fans (with pwm signals) and a 24v 65gpm water pump (with pwm signal) if anyone has any suggestions feel free to leave a comment.

Code:

import RPi.GPIO as GPIO
from time import sleep  

GPIO.setmode(GPIO.BCM)  
GPIO.setup(13, GPIO.OUT)

fan = GPIO.PWM(13, 100)  
print ("start")
fan.start(0)              
sleep (10)
i=0
while i < 10:
    print ("Run 5.4%")   
    fan.ChangeDutyCycle(5.4)
    sleep(15)
    print ("Run 5.5%")
    fan.ChangeDutyCycle(5.5)
    sleep(15)
    print ("Run 6.3%")
    fan.ChangeDutyCycle(6.3)
    sleep(30)
    print ("Run 6.31%")
    fan.ChangeDutyCycle(6.31)
    sleep(30)
    print ("Run 6%")
    fan.ChangeDutyCycle(6)
    sleep(15)   
    print ("Run 6.15%")
    fan.ChangeDutyCycle(6.15)
    sleep(15)  
    print ("Run 5.4%")   
    fan.ChangeDutyCycle(5.4)
    sleep(15)
    print ("Run 6.31%")
    fan.ChangeDutyCycle(6.31)
    sleep(30)
    i+=1
    print("i = ",i)
print ("Stop")
fan.ChangeDutyCycle(100)
fan.stop()
GPIO.cleanup()

and from forums.raspberrypi.com/viewtopic.php?t=278492 (last reference listed below) this code helped me realize things are backwards from what i was thinking along with my fan has a pwm sweet spot

Code#2:

import RPi.GPIO as GPIO 
from time import sleep  

GPIO.setmode(GPIO.BCM)  
GPIO.setup(25, GPIO.OUT)

fan = GPIO.PWM(25, 100)  
print ("start")
fan.start(0)              
sleep (5)  
print ("Run 100%")   
fan.ChangeDutyCycle(100)
sleep(0.5)
speed = [15,25,50,75,100]
for sp in speed:
    print ("Run", sp,"%")
    fan.ChangeDutyCycle(sp)      
    sleep(10)
fan.ChangeDutyCycle(0) 
print ("Stop")
sleep (5)  
print ("Run 100%") 
fan.ChangeDutyCycle(100)
sleep(0.5)  
for sp in range(15,101,5):
    print ("Run", sp,"%")
    fan.ChangeDutyCycle(sp)      
    sleep(2)
sleep(5)
print ("Stop")
fan.stop()     
GPIO.cleanup()

    

references:
https://noctua.at/pub/media/wysiwyg/Noctua_PWM_specifications_white_paper.pdf
https://www.digikey.com/en/maker/blogs/2019/how-to-control-a-dc-fan-using-the-raspberry-pi
https://www.infineon.com/dgdl/Infineon-IRF540N-DataSheet-v01_01-EN.pdf?fileId=5546d462533600a4015355e39f0d19a1
https://www.vishay.com/docs/91078/91078.pdf
https://noctua.at/en/nf-f12-industrialppc-3000-pwm
https://forums.raspberrypi.com/viewtopic.php?t=278492
pinout.xyz/pinout/pin33_gpio13

https://www.digikey.com/schemeit/project/pwm-12v-dc-fan-public-a724371f6e85467f96064d36ec9f68d6

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.