Scenario: I want to control a PC fan using the Raspberry Pi. The 4-wire-fan (MGT9212UR-W25) has its own power supply (12V) and can be controled via PWM. I would like to control it with a Python script using the RPi.GPIO
module, which unfortunately leads to bad results with a loud creaking noise. The fan's PWM input is connected to the Raspberry Pi on pin 12 (BCM). I would like to set the speed to 20% (for this example).
Good results: GPIO command line utility
gpio -g mode 12 pwm
gpio pwmr 100
gpio -g pwm 12 20
Bad results: RPi.GPIO module using Python 3.5
from RPi import GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(12, GPIO.OUT)
pwm = GPIO.PWM(12, 50)
pwm.start(0)
pwm.ChangeDutyCycle(20)
Question: Both attemps work, but the command line utility always leads to smooth results (pwmr
not required), while the Python script leaves me with a crackling fan (loud). I tried different values for ChangeDutyCycle and ChangeFrequency, so what am I doing wrong? How can the good results (from the command line utility) be produced using RPi.GPIO in Python? Thanks!!
-
I suggest you try gpiozero See gpiozero.readthedocs.io/en/stable/… AFAIK this still uses software PWM but you can vary frequency gpiozero.readthedocs.io/en/stable/…Milliways– Milliways2020年06月23日 23:54:23 +00:00Commented Jun 23, 2020 at 23:54
-
Thanks for the hint! I tried gpiozero, which gives better results than RPi.GPIO, but using pigpio runs the fan even smoother.Tobias Mai– Tobias Mai2020年06月24日 10:57:35 +00:00Commented Jun 24, 2020 at 10:57
2 Answers 2
Probably found an answer thanks to @joan 's answer.
It seems like RPi.PWM
can only do software PWM, but the fan requires hardware PWM to run as smooth as possible. To do hardware PWM on any GPIO pin, the pigpio daemon has to be executed, and controlled by Python. Therefore, pigpio has to be installed first and configured to be started on boot (systemd
). After that, hardware PWM is available on BCM pin 12 at 20% duty cycle at a frequency of 40 kHz with the following Python script:
import pigpio
PI = pigpio.pi()
PI.hardware_PWM(12, 40000, 200000)
I don't know if 40 kHz is the right value, but it works.
-
In fact using PWM to control a fan is poor practice. If the PWM is fast enough or the inertia high enough it may work - depending on what kind of motor.Milliways– Milliways2020年06月24日 03:55:32 +00:00Commented Jun 24, 2020 at 3:55
-
2@Milliways The fan is a 12V 4-wire. Since one line is PWM control, I think the fan expects to be controlled with PWM.Tobias Mai– Tobias Mai2020年06月24日 10:42:52 +00:00Commented Jun 24, 2020 at 10:42
-
Please accept your own answer with a click on the tick on its left side. Only this will finish the question and it will not pop up again year for year.Ingo– Ingo2020年06月26日 09:47:07 +00:00Commented Jun 26, 2020 at 9:47
There are two fundamental differences between the two approaches.
The gpio utility (part of wiringPi)
- is using hardware timed PWM.
- appears to be setting a frequency of 40 kHz.
The RPi.GPIO script
- is using software timed PWM.
- is setting a frequency of 50 Hz.
I'd guess the frequency is the main factor.