Raspberry Pi PWM Fan Speed Control
May 23, 2022
As you probably know, Raspberry Pi single-board computers, especially Pi 4 models, can get quite hot. While passive cooling options are often good enough to avoid overheating and thermal throttling, at some point you’ll need to think about using a cooling fan. The Raspberry Pi’s GPIO pins don’t supply enough current to power even a small fan, but there are several ways to power and control a fan with the Pi.
Raspberry Pi single-board computers can get quite hot under load, often requiring an active cooling system. Such a system, i.e. a fan, can be wired to run all the time, or as outlined here, it’s fairly easy to have the Raspberry Pi OS turn cooling on and off when needed via internal temperature sensing.
What’s not as straightforward is getting a fan to come on at a low speed via PWM control, then have it ramp up when it needs to quickly expel thermal energy from the Pi’s processor. This requires a bit of yak shaving, but it’s not too difficult, as outlined here.
For Raspberry Pi PWM fan control, you’ll need one of the following:
- A PC style 5V PWM fan, as explained here.
- A simple 2-wire fan, or even something like the ICE Tower, plus a plug-and-play control module like the EZ Fan 2
- Simple 2-wire fan, plus transistor-based DIY control setup
With the exception of the last scenario, connecting the hardware is a matter of plugging in the 5V, ground, and PWM signal pins. Software-wise, you’ll need to make up or download a Python program to handle PWM output. An example of this type of code is found here, by author Aerandir14, and includes info on how to set up your own DIY transistor implementation.
To run this example code, download calib_fan.py and fan_ctrl.py from the linked page. The first of these will help you set up your fan, while the second activates the fan in response to temperature. Upload the code to your Pi. WinSCP on Windows, or Netatalk on Macintosh are good methods for transfer if you don’t have a go-to option.
Enter python calib_fan.py on the Pi terminal, and enter values from 0 to 100 to determine your fan’s behavior at different duty cycles. Using a small 30mm fan, I found mine didn’t come on until around a value of 40, though your results may vary. Ctrl-c exits the test routine.
With this knowledge in-hand, open up fan_ctrl.py via the command nano fan_ctrl.py, and change variables around as you see fit. This allows you to set minimum and maximum temperatures, and you can also define additional temperature/duty cycle steps. Between these steps, the code does a linear interpolation, ramping up the speed in proportion to the temperature.
As shown above, I did a slight modification of the linked code. I set FAN_MIN to 0, and changed the fanSpeed to equal this variable instead of the lowest speedSteps. I also added code to print out the CPU temperature and fan speed, which would be commented out for normal usage. If you want to play around with the code, or even start over using this as an example, the two lines below form the crux of how PWM control works here:
- fan = GPIO.PWM(FAN_PIN, PWM_FREQ)
Run On Startup
To get your PWM fan code to run automatically at startup, enter sudo nano /etc/rc.local, add the initiation command before the “exit 0” line. For my program name/location, this is python /home/pi/fan_ctrl.py & where the & operator allows it to run in the background. To ensure this is working, reboot and run a stress test as outlined here.
Going Further With Podman or Docker
For another take on PWM control, this repository features a lengthier Python routine, which can run on any Linux distribution that features Podman or Docker. This versatility could be advantageous, though the really interesting bit is the ability to export temperature and fan speed stats over time for graphing. It looks like a lot of fun if you’re willing to set it up.
Keep Your Pi Appropriately Cool via PWM
Caption: Pi Fan and prototyping enclosure top as outlined here
Image Credit: Jeremy Cook
Whatever technique you employ, it’s great to know that your Pi won’t get too hot under load, and that unless you’re doing something extreme you won’t have to worry about thermal cycling. Given the cost and limited availability of Raspberry Pi’s these days, more than ever it pays to take care of your computing equipment!
Jeremy Cook is a freelance tech journalist and engineering consultant with over 10 years of factory automation experience. An avid maker and experimenter, you can follow him on Twitter, or see his electromechanical exploits on the Jeremy Cook YouTube Channel!