The control of the fan speed is done through a "PWM" value set in some registers of the driver...But as the PWM levels needed for the fan control are really specific, I had to change the algorith provided in the original fancontrol script, to use a different function.
I got the idea after looking at fantulence which is another fan control program.
Update : After several days using the function I've provided before in this post, the noise was still a bit too high, without the temperature cooling so much... so I've changed a little bit again the curve which I want fancontrol to use.
Explanation of the function :
If the temp of the processor was 35°C, the fan should stop... but it won't reach that temperature, I suppose ;)... Now, when it's 46°C, I want the PWM to be set to 8, so that the fan is at the lowest speed (around 1800 rpm). When it becomes 49°C, I want it to be 14, which means 2400 rpm, and if it reaches 60°C almost full speed for the fan : more than 3300 rpm .
The curve is then something like : (x-35)^2 / 14 + 0 (based on a "(x-t0)^n / q + r" curve, where r is the PWM value we want to have at temperature t0, n the quadratic factor of the curve, and q the ratio to apply...
Here is the /etc/fancontrol
config file :
INTERVAL=10 FCTEMPS=1-0290/pwm1=1-0290/temp2_input FCFANS= 1-0290/pwm1=1-0290/fan1_input MINTEMP=1-0290/pwm1=35 MAXTEMP=1-0290/pwm1=58 MINSTART=1-0290/pwm1=90 MINSTOP=1-0290/pwm1=10
Then, the patch for /usr/sbin/fancontrol
:
--- /usr/sbin/fancontrol.old 2005-10-09 18:34:39.000000000 +0200
+++ /usr/sbin/fancontrol 2005-10-09 18:32:48.000000000 +0200
-236,7 +236,8
then pwmval=255 # at specified maxtemp switch to 100%
else
# calculate the new value from temperature and settings
- pwmval=`calc "^2*(255-${minso})+${minso})" |cut -d'.' -f1`
+ pwmval=`calc "((${tval}-35)^2)/14" | bc -l |cut -d . -f1`
if [ $pwmpval -eq 0 -o $fanval -eq 0 ]
then # if fan was stopped start it using a safe value
echo $minsa > $pwmo
I've added a /etc/init.d
script for fancontrol, and added it in /etc/rc2.d/S30 level...
Reading proper sensors values with lm-sensors :
Now, I should also say that I adapted the sensors configuration according to the guidelines at : http://wiki.debian.org/JacobAnawalt (see bottom of the page).
Update: in addition to these quidelines for /etc/sensors.conf
, I changed some small configs to avoid the ALARMS... here is the current setup for my it87 :
chip "it87-*" "it8712-*" # The values below have been tested on Asus CUSI, CUM motherboards. # Voltage monitors as advised in the It8705 data sheet label in0 "VCore 1" label in1 "VCore 2" label in2 "+3.3V" label in3 "+5V" label in4 "+12V" label in5 "-12V" label in6 "-5V" label in7 "Stdby" label in8 "VBat" # vid is not monitored by IT8705F # comment out if you have IT8712 ignore vid # Incubus Saturnus reports that the IT87 chip on Asus A7V8X-X seems # to report the VCORE voltage approximately 0.05V higher than the board's # BIOS does. Although it doesn't make much sense physically, uncommenting # the next line should bring the readings in line with the BIOS' ones in # this case. # compute in0 -0.05+@ , @+0.05 # If 3.3V reads 2X too high (Soyo Dragon and Asus A7V8X-X, for example), # comment out following line. # compute in2 2*@ , @/2 # compute in3 ((6.8/10)+1)*@ , @/((6.8/10)+1) compute in4 ((30/10) +1)*@ , @/((30/10) +1) # For this family of chips the negative voltage equation is different from # the lm78. The chip uses two external resistor for scaling but one is # tied to a positive reference voltage. See ITE8705/12 datasheet (SIS950 # data sheet is wrong) # Vs = (1 + Rin/Rf) * Vin - (Rin/Rf) * Vref. # Vref = 4.096 volts, Vin is voltage measured, Vs is actual voltage. # The next two are negative voltages (-12 and -5). # The following formulas must be used. Unfortunately the datasheet # does not give recommendations for Rin, Rf, but we can back into # them based on a nominal +2V input to the chip, together with a 4.096V Vref. # Formula: # actual V = (Vmeasured * (1 + Rin/Rf)) - (Vref * (Rin/Rf)) # For -12V input use Rin/Rf = 6.68 # For -5V input use Rin/Rf = 3.33 # Then you can convert the forumula to a standard form like: # compute in5 (7.67 * @) - 27.36 , (@ + 27.36) / 7.67 # compute in6 (4.33 * @) - 13.64 , (@ + 13.64) / 4.33 # Neither of those calculations work for the "SK41G" ("FX41") :( # in5 (-12V) is 0.96 when BIOS shows was showing 11.95-12.00. # Adjusting -12V Rin/Rf to 4.16 gives a close value # in6 (-5V) is 2.42 when BIOS was showing 5v # Adjusting -5V Rin/Rf to 4.43 gives a close value # compute in5 (5.16 * @) - 17.04 , (@ + 17.04) / 5.16 compute in6 (5.43 * @) - 18.15 , (@ + 18.15) / 5.43 # # # this much simpler version is reported to work for a # Elite Group K7S5A board # # compute in5 -(36/10)*@, -@/(36/10) # compute in6 -(56/10)*@, -@/(56/10) # compute in7 ((6.8/10)+1)*@ , @/((6.8/10)+1) set in0_min 1.5 * 0.95 # set in0_max 1.5 * 1.05 set in0_max 1.5 * 1.10 # set in1_min 2.4 # set in1_max 2.6 set in1_min 3.3 * 0.95 set in1_max 3.3 * 1.05 set in2_min 3.3 * 0.95 set in2_max 3.3 * 1.05 set in3_min 5.0 * 0.95 set in3_max 5.0 * 1.05 set in4_min 12 * 0.95 set in4_max 12 * 1.05 set in5_max -12 * 0.95 set in5_min -12 * 1.05 set in6_max -5 * 0.95 set in6_min -5 * 1.05 set in7_min 5 * 0.95 set in7_max 5 * 1.05 #the chip does not support in8 min/max # Temperature # # Important - if your temperature readings are completely whacky # you probably need to change the sensor type. # Adujst and uncomment the appropriate lines below. # The old method (modprobe it87 temp_type=0xXX) is no longer supported. # # 2 = thermistor; 3 = thermal diode; 0 = unused # set sensor1 3 # set sensor2 3 # set sensor3 3 # If a given sensor isn't used, you will probably want to ignore it # (see ignore statement right below). label temp1 "M/B Temp" # set temp1_over 40 set temp1_over 48 set temp1_low 15 label temp2 "CPU Temp" # set temp2_over 45 set temp2_over 56 set temp2_low 15 # ignore temp3 label temp3 "Temp3" # set temp3_over 45 set temp3_over 48 set temp3_low 15 # The A7V8X-X has temperatures inverted, and needs a conversion for # CPU temp. Thanks to Preben Randhol for the formula. # label temp1 "CPU Temp" # label temp2 "M/B Temp" # compute temp1 (-15.096+1.4893*@), (@+15.096)/1.4893 # The A7V600 also has temperatures inverted, and needs a different # conversion for CPU temp. Thanks to Dariusz Jaszkowski for the formula. # label temp1 "CPU Temp" # label temp2 "M/B Temp" # compute temp1 (@+128)/3, (3*@-128) # Fans set fan1_min 0 # set fan1_min 2200 # set fan2_min 3000 # ignore fan3 # set fan3_min 3000 ignore fan2 ignore fan3