Introduction
In Windows I controlled the fanspeed on my stationary computer by using a ASUS program that read the temperatures. I wanted the same temperature/fanspeed scaling in Linux, so I decided to setup fancontrol, which is a small script that monitors temperatures and fanspeeds and sets the fan at the minimum required level to insure low noise levels.
The following should work on most Linux distributions and with most modern motherboards. For the record I did this on a Ubuntu 8.04 installation with a setup consisting of a ASUS P5W DH Deluxe Digital Home Series motherboard, Gigabyte Triton GZ-XX1CA-SNS casing and a Core 2 Duo E6600 2.4 GHz with a Noctua NH-U12P CPU cooler, see (Hvilke elementer jeg valgte til min nye computer [tjansson.dk]) for more details.
Controlling the speed using PWM
Pulse width modulation (PWM) can be used to control the fan speed on modern motherboards. My ASUS P5W DH is such a motherboard. The PWM values goes from 0 to 255 and can be controlled quite easily:
root@bohr:~# cat /sys/class/hwmon/hwmon0/device/fan1_input 1054 root@bohr:~# echo "50" > /sys/class/hwmon/hwmon0/device/pwm1 root@bohr:~# cat /sys/class/hwmon/hwmon0/device/fan1_input 390 root@bohr:~# echo "255" > /sys/class/hwmon/hwmon0/device/pwm1 root@bohr:~# cat /sys/class/hwmon/hwmon0/device/fan1_input 1054
But this solution is a bit to basic. I wish to be able to do this automatically depending on the temperature. This is where fancontrol comes into the picture. fancontrol and the related pwmconfig is a part of the lm_sensors program which is quite easy to install under Ubuntu:
root@bohr:~# aptitude install lm-sensors
The first thing todo is see whether or not the lm_sensors detects anything:
tjansson@bohr:~$ sensors w83627dhg-isa-0290 Adapter: ISA adapter VCore: +1.47 V (min = +0.00 V, max = +1.74 V) in1: +12.09 V (min = +5.17 V, max = +3.80 V) ALARM AVCC: +3.25 V (min = +0.32 V, max = +0.51 V) ALARM 3VCC: +3.25 V (min = +2.21 V, max = +0.77 V) ALARM in4: +1.37 V (min = +0.51 V, max = +0.80 V) ALARM in5: +1.58 V (min = +0.34 V, max = +0.02 V) ALARM in6: +4.17 V (min = +3.30 V, max = +3.28 V) ALARM VSB: +3.25 V (min = +0.00 V, max = +0.56 V) ALARM VBAT: +3.23 V (min = +1.02 V, max = +0.00 V) ALARM Case Fan: 1054 RPM (min = 5273 RPM, div = 128) ALARM CPU Fan: 1054 RPM (min = 5273 RPM, div = 128) ALARM Aux Fan: 1506 RPM (min = 105 RPM, div = 128) fan4: 1318 RPM (min = 10546 RPM, div = 128) ALARM fan5: 0 RPM (min = 215 RPM, div = 128) ALARM Sys Temp: +49.0°C (high = +92.0°C, hyst = +32.0°C) sensor = thermistor CPU Temp: +47.0°C (high = +80.0°C, hyst = +75.0°C) sensor = diode AUX Temp: +119.0°C (high = +80.0°C, hyst = +75.0°C) ALARM sensor = thermistor
which it clearly did in my case even though it has some funny alarms. To setup fancontrol the first thing to do is run pwmconfig to find the relations between devices in /sys/class/hwmon/hwmon0/device/ and fanspeed. pwmconfig is described as:
This program will search your sensors for pulse width modulation (pwm) controls, and test each one to see if it controls a fan on your motherboard.
To start the config run
root@bohr:~# pwmconfig
And remember to write the information to the file /etc/fancontrol when asked. This is how my file looks (DO NOT COPY-PASTE. SYSTEM SPECIFIC):
root@bohr:~# cat /etc/fancontrol INTERVAL=5 FCTEMPS=hwmon0/device/pwm1=hwmon0/device/temp1_input hwmon0/device/pwm2=hwmon0/device/temp2_input FCFANS=hwmon0/device/pwm1=hwmon0/device/fan1_input hwmon0/device/pwm2=hwmon0/device/fan2_input MINTEMP=hwmon0/device/pwm1=40 hwmon0/device/pwm2=40 MAXTEMP=hwmon0/device/pwm1=52 hwmon0/device/pwm2=60 MINSTART=hwmon0/device/pwm1=50 hwmon0/device/pwm2=50 MINSTOP=hwmon0/device/pwm1=45 hwmon0/device/pwm2=100
Running fancontrol on every reboot
Now I have configured everything, so only thing left to do is to run fancontrol. To start fancontrol just write fancontrol in the console as root user (or using sudo). fancontrol will however stop when the console is closed or the computer is rebooted.
The solution to have fancontrol running on every restart is to create a init.d script. The following should be entered in to a file called /etc/init.d/fancontrol
#!/bin/sh # # Fancontrol start script. # set -e # Defaults DAEMON=/usr/sbin/fancontrol PIDFILE=/var/run/fancontrol.pid PATH=/sbin:/bin:/usr/sbin:/usr/bin test -f $DAEMON || exit 0 . /lib/lsb/init-functions case "$1" in start) log_begin_msg "Starting fancontrol daemon..." start-stop-daemon --start -o -q -m -b -p $PIDFILE -x $DAEMON log_end_msg $? ;; stop) log_begin_msg "Stopping fancontrol daemon..." start-stop-daemon --stop -o -q -p $PIDFILE log_end_msg $? ;; force-reload|restart) sh $0 stop sh $0 start ;; *) log_success_msg "Usage: /etc/init.d/fancontrol {start|stop|restart|force-reload}" log_success_msg " start - starts system-wide fancontrol service" log_success_msg " stop - stops system-wide fancontrol service" log_success_msg " restart, force-reload - starts a new system-wide fancontrol service" exit 1 ;; esac exit 0
and then the script should be executable and added to rc.d:
root@bohr:~# chmod +x /etc/init.d/fancontrol root@bohr:~# update-rc.d fancontrol defaults 99 01 Adding system startup for /etc/init.d/fancontrol ... /etc/rc0.d/K01fancontrol -> ../init.d/fancontrol /etc/rc1.d/K01fancontrol -> ../init.d/fancontrol /etc/rc6.d/K01fancontrol -> ../init.d/fancontrol /etc/rc2.d/S99fancontrol -> ../init.d/fancontrol /etc/rc3.d/S99fancontrol -> ../init.d/fancontrol /etc/rc4.d/S99fancontrol -> ../init.d/fancontrol /etc/rc5.d/S99fancontrol -> ../init.d/fancontrol
Monitoring the temperatures
Personally I use gkrellm, see image, to monitor the temperatures and fanspeeds but there are lots of programs out there, such as xsensors.
Special cases
A friend of my Kåre H. Jensen made a special script for controlling the ASUS Eee PC
- Howto reduce fan noise level on the eee pc 900 1000 1000h [hartvig.de]
- Howto reduce fan noise level on the eee pc 900 1000 1000h part ii [hartvig.de]
For Thinkpad owners there is nice program called tpfand which I have written about on this page Server setup [tjansson.dk] under the section called Noisy fan.
References
Fan speed control [wiki.archlinux.org]
HOWTO: Fancontrol [ubuntuforums.org]
Hey nice tutorial but I have a question –
Are these fans connected to your mother board?
Case Fan: 1054 RPM (min = 5273 RPM, div = 128) ALARM
Aux Fan: 1506 RPM (min = 105 RPM, div = 128)
Because I am working on a system which has a separate panel which has these fans connected to it and that panel doesnt have a sensor hence I aint getting any RPM values for it.
Do you know any application which manages USB fans?
Thanks
Vik
Yes the fans are located on my motherboard. I am not aware of any programs to manage USB fans but then again I haven’t searched around. 🙂
Hi,
I have the same mobo (and the same Noctua NH-U12P CPU cooler too :-). I was wandering if you know what is the “AUX temp” 119 °C on your mobo and 127 °C on mine. Is that normal ?
thanks
No – I haven’t really figured that out. I am quite sure nothing is above 100 degrees inside my computer so I think it is unused or uncalibrated sensor?
For eeepc there is eee-control (for ubuntu in synaptic) :
http://greg.geekmind.org/eee-control/
Here’s a script I wrote for running my fan on a dell laptop (note: it depends on i8kutils, including loading the i8k module into the kernel at boot time):
#!/bin/bash
#Author Jay DeYoung
#You may find my temperatures overly conservative- I like my laptop cool
#All in celcius.
#i8k has three speeds, off, 1, and 2.
fan0=25 #need to incorporate this
fan1=30 #temperature to turn fan on to 1
fan2=43 #temperature to turn fan on to 2
fanBack1=35 #turn fan back to 1
fanBack0=25
#currently not used.
minFan2=30 #minium time for fan to be spinning on mode two (seconds)
minFan1=0 #minimum time for fan to be spinning on mode one (seconds)
while true; do
i=`i8kctl temp`
if [ “$i” -ge “$fan1” ] ; then
while [ “$i” -ge “$fanBack0” ] ; do
if [ “$i” -ge “$fan2” ] ; then
while [ “$i” -ge “$fanBack1” ] ; do
echo “$i”
i8kfan 2 2 >> /dev/null
sleep 2s
i=`i8kctl temp`
done
fi
echo “$i”
i8kfan 1 1 >> /dev/null
sleep 2s
i=`i8kctl temp`
done
i8kfan 0 0 >> /dev / null
sleep 2 s
fi
done
I know this is and old entry, but let’s see if I’m lucky. I have a problem related with the beginning of this entry:
I have a NAS running with Debian:
Linux 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1 (2015-05-24) x86_64 GNU/Linux
I wan’t to control the FAN speed depending of the highest temperature of the HDDs. To do it, I use a python script that reads temperatures and then writes the right value to /sys/class/hwmon/hwmon1/device/pwm3 using cron.
The script works, it is able to write the right value to pwm3 and the speed of the fan changes. The problem is another unknown program in the computer is changing back the power value to 80.
Before I was using fancontrol and after running the configuration program pwmconfig, my script worked fine, the right power values were applied to pwm3 and they remain there. But everytime I rebooted I had to run again pwmconfig.
Thinking that maybe fancontrol was controlling the fan speed even though I didn’t have any configuration saved, I totally purged fancontrol (so I cannot run pwmconfig anymore), but the problem persists. Every time I change the value of pwm3, it returns back to 80 after ~0.5 secs.
Hey, suddenly my fan was scratching smth. inside and was very noisy ( as shit ). So, that was a mechanism’s problem. You should just fix it by putting some oil inside its axis. That helped me ..
HAPPY NEW YEAR )))
Hi! I have a few commands failing after an apt-get upgrade in ubuntu 14.02. My new kernel is 3.13.0-125-generic, and my fan speed control script is using the following commands:
$ echo 1 > /sys/class/hwmon/hwmon0/device/pwm4_enable
$ echo 180 > /sys/class/hwmon/hwmon0/device/pwm4
But both commands are telling “file not found”. I can see radical changes in device control directory:
$ ls /sys/class/hwmon/hwmon0/device/
driver/ subsystem/ temp2_max temp3_max
hwmon/ temp2_crit temp3_crit uevent
modalias temp2_crit_alarm temp3_crit_alarm
name temp2_input temp3_input
power/ temp2_label temp3_label
Where could I read about this changes? Do you know something about them?
Thanx in advance.
Hi Pepe
I have not looked much at fan speeds for the last 5 years, so I am not aware of any changes and cannot help you.
It might very well be that the naming have changes in recent kernels. My article was based on Ubuntu 8.04, so your version is 6 years newer and things have probably changed. The newest long support version of Ubuntu is 16.04.2, so that is also a couple of years newer.
Thanx for your response.
It seems the conflict was caused by Virtualbox. I’ve upgraded its version too and voila! All is under control right now.
Thanx again.
Hello Thomas, i’ve read your article and it’s good, however i need to have a better control of the chassis fan since i have to relate its speed to the nvidia gpu temperature, and here i’d like to know a little bit more about what i’m trying to solve.
Basically i started using this script: http://dan.bodar.com/2016/03/03/linking-nvidia-gpu-temperature-with-a-motherboard-pwm-fan-in-linux/ and i modified it setting the right path to the pwm controlled fan and i used and for the function temperature i used nvidia-smi in order to get the temp of my gpu.
One of the problems i’m facing is i get : trap: SIGHUP: bad trap launching: sh nameofthescript even if i set #!/usr/bin/env bash on the top of the script.
i’m running Debian 9.3 stretch 4.9.0-4-amd64
if i comment the line with SIGHUP i get :gpu_fancontrol: 36:gpu_fancontrol: Syntax error: “(” unexpected
it’s like the shebang line is not working and i’m still using dash…
hey sorry Thomas i found out the shebang is ignored if i launch the script with sh eveything is ok 😉