Controlling fanspeeds in Linux on PWM motherboards, Thinkpads and ASUS Eee PC

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

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]

This entry was posted in Articles, Computer. Bookmark the permalink.

9 Responses to Controlling fanspeeds in Linux on PWM motherboards, Thinkpads and ASUS Eee PC

  1. Pingback: g2k » Blog Archiv » Control Fan speed on ASUS Motherboard

  2. Vik says:

    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

  3. 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. :)

  4. Claude says:

    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

  5. 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?

  6. Pingback: g2k » Blog Archive » Control Fan speed on ASUS Motherboard

  7. abitbol says:

    For eeepc there is eee-control (for ubuntu in synaptic) :

    http://greg.geekmind.org/eee-control/

  8. Pingback: Upgrading Ubuntu i686 (32bit) to x86_64 (64bit) | tjansson.dk

  9. Jay says:

    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

Leave a Reply