You are not logged in.

#1 2009-02-02 02:26:01

ProbablyX
Member
Registered: 2009-02-01
Posts: 12

Fan speed control

Hello!

I can't get the fans to speedup automatically when needed on my MacBook. The wiki says this isnt implemented but the wiki was written in 2007 and the C program supplied can not be downloaded anymore. As all other distros can handle the macbooks fans now I was hoping there's a fix.

Currently after having followed the guides I have lm_sensors installed, applesmc mod - and I can read the temperature manually.
My modprobe.conf contains

alias char-major-89 i2c-dev

and rc.conf loads these modules (related to the fans):

i2c-i801 eeprom coretemp

Could anyone help me making the macbook increase the fanspeed when my cpu gets hot, instead of always running in the same speed, as I dont want it to get fried? This is a Core Duo (the 1st gen) Mac Book.

Thanks smile

Last edited by ProbablyX (2009-02-02 02:26:16)

Offline

#2 2009-02-02 11:14:08

ProbablyX
Member
Registered: 2009-02-01
Posts: 12

Re: Fan speed control

Maybe I should move this to the laptop forum though?

Offline

#3 2009-02-14 16:16:25

mobitux
Member
Registered: 2008-11-08
Posts: 9

Re: Fan speed control

As all other distros can handle the macbooks fans now I was hoping there's a fix.

which distros do you mean?

Offline

#4 2009-02-17 00:17:34

ProbablyX
Member
Registered: 2009-02-01
Posts: 12

Re: Fan speed control

Hi smile

Ubuntu, Fedora for instance

Thanks

Offline

#5 2009-02-19 20:06:20

mobitux
Member
Registered: 2008-11-08
Posts: 9

Re: Fan speed control

Hello, I tried Ubuntu 8.04 but with the same result. So I decided to prog. a little daemon.
It works only with a Macbook Pro 3.1 because I don't have the other Macbook specs.
Try this http://aur.archlinux.org/packages.php?ID=21391

Offline

#6 2009-02-20 02:07:25

ProbablyX
Member
Registered: 2009-02-01
Posts: 12

Re: Fan speed control

mobitux wrote:

It works only with a Macbook Pro 3.1 because I don't have the other Macbook specs.

I have a MacBook 1.0, is there any part of the C code I should edit to make it work?

Thanks smile

Offline

#7 2009-02-20 20:31:22

mobitux
Member
Registered: 2008-11-08
Posts: 9

Re: Fan speed control

You should modify:
1.) fan min and max:
#define MIN_SPEED 2000
#define MAX_SPEED 6000

2.)model name:
if (!strncmp(buffer,"model name    : Intel(R) Core(TM)2 Duo CPU",39)){

3.) fan speed:
fan_speed=(temp-38)*160;

Find the best settings for your macbook. For my macbook fan_speed=(temp-38)*160 works good.

Example 1:
temp=50,5°
fan_speed=(58-38)*160=2000 RPM

Example 2:
temp=58°
fan_speed=(58-38)*160=3200 RPM

Example 3:
temp=75,5°
fan_speed=(58-38)*160=6000 RPM

Please post the ouput of:

bash-3.2# more /sys/devices/platform/applesmc.768/fan1_max
bash-3.2# more /sys/devices/platform/applesmc.768/fan2_max
bash-3.2# more /sys/devices/platform/applesmc.768/fan2_min
bash-3.2# more /sys/devices/platform/applesmc.768/fan1_min
bash-3.2# grep -n "model name" /proc/cpuinfo

Offline

#8 2009-04-27 23:04:02

random
Member
Registered: 2007-11-22
Posts: 12

Re: Fan speed control

Hmmm builds with no errors and installs but `/etc/rc.d/cmp-daemon start` doesn't do anything. `sh /usr/sbin/cmp-daemon` displays the message "cannot execute binary file".


--name="Zach"

Offline

#9 2009-04-28 18:49:40

chetan51
Member
Registered: 2009-04-23
Posts: 14

Re: Fan speed control

I have this problem too. I'm planning on writing my own fanspeed control script soon. If you have time, I suggest you learn bash and write your own too, so you'll have even more control over your own system.

As a temporary fix, I wrote a script that can manually set the fanspeed. Make it executable and save it in /usr/sbin. Call it with "sudo setfans [speed between 2000 and 4500]"

setfans:
#! /bin/bash

echo 1 > /sys/devices/platform/applesmc.768/fan1_manual
echo "$1" > /sys/devices/platform/applesmc.768/fan1_output
echo 1 > /sys/devices/platform/applesmc.768/fan2_manual
echo "$1" > /sys/devices/platform/applesmc.768/fan2_output

Offline

#10 2009-04-30 20:02:46

random
Member
Registered: 2007-11-22
Posts: 12

Re: Fan speed control

Yeah I'm just too lazy to figure out how to make an rc.d script, and:

1. You shouldn't have to worry about fan2 because it just does what fan1 is doing and vice versa methinks.
2. Maybe making a crontab entry for it is fine and it could be added/deleted from an rc.d script.
3. http://www.mail-archive.com/mactel-linu … 00516.html explains temp 1-12 for the most part.

I'll slap something together and post it soon and I think it's pretty strange that there's not a known way to do this.

EDIT: Came up with this horrible thing but it works enough for me:

#!/bin/bash

CPU_TEMP_TMP=`sensors | grep temp3 | cut -d'°' -f1`
CPU_TEMP=${CPU_TEMP_TMP:14:2}

if [ $CPU_TEMP -lt 45 ]; then
    echo 2400 > /sys/devices/platform/applesmc.768/fan1_min
elif [ $CPU_TEMP -gt 45 ]; then
    echo 3800 > /sys/devices/platform/applesmc.768/fan1_min
fi

It can easily be fixed to support some kind of cooling model but again, I'm too lazy. I'm sure you guys can come up with some interesting stuff.

EDIT: The smcfancontrol script found on the arch wiki (linked to an ubuntuforums.org thread) is pretty awesome and complete but the only issue with it is that it randomly dies because of input/output errors that randomly occur when reading a temp*-input from /sys/.../applesmc.768/ (this also happens occassionaly when you read the values using `sensors`). Other than that, with very minimal tweaking, it works like magic.

Last edited by random (2009-05-01 20:07:08)


--name="Zach"

Offline

#11 2009-05-10 20:41:03

random
Member
Registered: 2007-11-22
Posts: 12

Re: Fan speed control

Nobody has really talked about this in a long time. People out there are probably saying "damn this macbook (or pro) is getting really hot."

I keep wishing that there was a daemon out there to control applesmc and do COOL stuff. Shut up and write it yourself, random. Haha. Well I don't know how to so I put together a few things. What follows is the contents of two files that keep my macbook pro 4,1 cool, whether I am browsing this forum or playing urban terror in KDE4.

/usr/bin/smcfancontrol

#!/bin/bash                                          
############################################         
#                                          #         
#  Name: fanControl                        #         
#  Version: 0.2                            #         
#  Description:                            #         
#     Control fans on Apple Macintosh      #         
#  Dependencies:                           #         
#     applesmc                             #         
#  Author: Kenny Lasse Hoff Levinsen       #         
#     Alias: Joushou                       #         
#  Use at own risk                         #         
#                                          #         
############################################         

appleSMCPath=/sys/devices/platform/applesmc.768
                        # Path to applesmc (Seems static)

minTemp=48              # Lowest temperature
maxOnlineTemp=80        # Highest temperature when online
maxOfflineTemp=75       # Highest temperature when offline

fanMinSpeed=2200        # Lowest fan-speed
fanMaxSpeed=6000        # Highest fan-speed

tempCalc=highest        # Temperature calculation ("highest" uses highest temperature, "average" takes the average                                                                                                
sensorsUsed=4           # How many sensors to use                                                        
debug=onChange          # Set to onLoop for every loop, onChange on state-changes, or false for off      
manFanControl=false     # Set to true if you want to define direct output, instead of fan minimum speeds 
debugTo=/var/log/smcfancontrol.log                                                                       
                        # Where to write our debugging to (/dev/stdout for standard output)              

debug() # Prints text with a timestamp, when $debug
{                                                  
        [[ $debug == onChange ]] && [[ $stateChange == true ]] && echo "$(date "+%d/%m %H:%M:%S"): $@" >> $debugTo                                                                                                
        [[ $debug == onLoop ]] && echo "$(date "+%d/%m %H:%M:%S"): $@" >> $debugTo                       
}                                                                                                        

fatal() # Fatal error
{                    
        stateChange=true
        debug "FATAL: Failing at: $1"
        echo "$(date "+%d/%m %H:%M:%S"): FATAL: Failing at: $1" > /dev/stderr
        debug "Attempting to set fans to safe values"                        
        for i in $appleSMCPath/fan*_manual                                   
        do                                                                   
                echo 0 > $i                                                  
        done                                                                 
        fanEnd="_min"                                                        
        counter=0                                                            
        until [[ $counter == $fans ]]                                        
        do                                                                   
                ((counter++))                                                
                echo 4000 > /sys/devices/platform/applesmc.768/fan${counter}${fanEnd}
        done                                                                         
        debug "Commit suicide. Bye."                                                 
        exit 1                                                                       
}                                                                                    

initSetup() # Initialize
{                       
        [[ $debugTo != "/dev/stdout" ]] && [ -e $debugTo ] && mv ${debugTo} ${debugTo}.0
        fans=0                                                                          
        debug "Detecting configuration"                                                 
        for i in $appleSMCPath/fan*_output # Count fans                                 
        do                                                                              
                ((fans++))                                                              
        done                                                                            

        if [[ $manFanControl == true ]]
        then                           
                for i in $appleSMCPath/fan*_manual
                do                                
                        echo 1 > $i               
                done                              
                fanEnd="_output"                  
        else                                      
                for i in $appleSMCPath/fan*_manual
                do                                
                        echo 0 > $i               
                done                              
                fanEnd="_min"                     
        fi                                        

        debug "  Fans: $fans $([[ $manFanControl == true ]] && echo ', Manually controlled')"
        debug "    Min fan-speed: $fanMinSpeed"                                              
        debug "    Max fan-speed: $fanMaxSpeed"                                              

        sensors=0
        for i in $appleSMCPath/temp*_input # Count temperature sensors
        do                                                            
                ((sensors++))                                         
        done                                                          

        debug "  Sensors: $sensors"
        debug "    Limited by user to $sensorsUsed"

        (cat /proc/acpi/battery/BAT0/state | grep "yes" > /dev/null) && laptop=true || online=true
        (cat /proc/acpi/ac_adapter/ADP1/state | grep on-line > /dev/null) && online=true || online=false

        debug "  Laptop: $laptop"
        debug "    ACPI-State: $([[ $online == true ]] && echo online || echo offline)"
        debug "Configuration detected"                                                 

}

setFans() # Adjust fan-speeds
{                            
        counter=0            
        until [[ $counter == $fans ]]
        do                           
                ((counter++))        
                echo $1 > /sys/devices/platform/applesmc.768/fan${counter}${fanEnd} || fatal "setting fans"                                                                                                       
        done                                                                                             
}                                                                                                        

update() # Update temperatures and ACPI state
{                                            

        counter=1
        until [[ $counter == $sensors ]]
        do                              
                tempVar=$(cat $appleSMCPath/temp${counter}_input) || fatal
                ((tempSensor[$counter]=tempVar/1000))                     
                ((counter++))                                             
        done                                                              

        if [[ $tempCalc == "highest" ]]
        then                           
                counter=0              
                temp=0                 
                until [[ $counter == $sensorsUsed ]] || [[ $counter == $sensors ]]
                do                                                                
                        ((counter++))                                             
                        [[ ${tempSensor[$counter]} > $temp ]] && temp=${tempSensor[$counter]}
                done                                                                         
                [[ $oldTemp != $temp ]] && stateChange=true && oldTemp=$temp                 
        else                                                                                 
                counter=0                                                                    
                temp=0                                                                       
                until [[ $counter == $sensorsUsed ]] || [[ $counter == $sensors ]]           
                do                                                                           
                        ((counter++))                                                        
                        let "temp = ${tempSensor[$counter]} + $temp"                         
                done                                                                         
                ((temp=temp/(counter-1)))                                                    
                [[ $oldTemp != $temp ]] && stateChange=true && oldTemp=$temp                 
        fi                                                                                   

        if [[ $laptop == true ]]
        then                    
                (cat /proc/acpi/ac_adapter/ADP1/state | grep on-line > /dev/null) && online=true || online=false                                                                                                  

                if [[ $oldOnline != $online ]]
                then                          
                        [[ $online == true ]] && maxTemp=$maxOnlineTemp || maxTemp=$maxOfflineTemp
                        ((ratio=(fanMaxSpeed-fanMinSpeed)/(maxTemp-minTemp)))                     
                        oldOnline=$online
                        stateChange=true
                fi
        fi
}

stateChange=true
initSetup

while : # Lets loop
do
        update || fatal "calling update"
        if [[ $stateChange == true ]]
        then
                ((speed=((temp-minTemp)*ratio)+fanMinSpeed))
                (( $speed >= $fanMaxSpeed )) && speed=$fanMaxSpeed                              # Don't try to set fan-speed over $fanMaxSpeed
                (( $speed <= $fanMinSpeed )) && speed=$fanMinSpeed                              # Don't try to set fan-speed under $fanMinSpeed
                setFans $speed || fatal "calling setFans"
        fi
        debug "Temperature: $temp, Fan-speed: $speed, ACPI-State: $([[ $online == true ]] && echo online || echo offline)"
        stateChange=false
        sleep 5
done

/usr/bin/smcfancontrol_keepalive

#!/bin/bash

while [ 1 ]
do
        sudo /usr/bin/smcfancontrol
        sleep 2
done

In summary... Well first, thanks/credit goes to Joushou for the smcfancontrol script, which was found on ubuntuforums.org. I noticed that, as mentioned in my last post, the script likes to die because sometimes there is an i/o error with the temp[n] files buried in /sys/.../applesmc.768/ so that would be the reason behind the keepalive bash script. It simply indefinitely runs Joushou's script. I threw the keepalive in rc.local and never worry about my mbp overheating.


--name="Zach"

Offline

Board footer

Powered by FluxBB