Home Page of Ron Star

Auto Video Card Fan Control For AMD Radeon 7770

xfx_r7770_core_editionWhen I got my new PC I wasn’t very happy with how loud the fan was on the video card. I picked up the XFX R7770. It was about $100 on Amazon. It’s an all right video card save a few small issues. One of the biggest issues is that the fan is so loud by default.

After searching and trying to figure it out I came across a tool that could set the fan speed (and over-clock the board). After figuring out the controls I was able to set the board to 20% fan. Perfect!

But there is a problem. It’s a hard number and not dynamic. I needed the fan to change depending on the temp of the card. The same tool that sets the fan can also report the temp. So I created a daemon for it.

#!/usr/bin/env ruby
# encoding: utf-8

#
# Required Gems
#
# gem install fallen clap
#

require 'fallen'
require 'fallen/cli'

def get_temp
  temp_str = `aticonfig --adapter=0 --od-gettemperature`
  temp_str.scan(/Sensor 0: Temperature - (\d+\.\d+) C/)[0][0].to_i
end

def get_speed
  speed_str = `aticonfig --pplib-cmd "get fanspeed 0"`
  speed_str.scan(/Fan Speed: (\d+)/)[0][0].to_i
end

def set_speed(speed)
  `aticonfig --pplib-cmd "set fanspeed 0 #{speed}"`
end

module Azazel
  extend Fallen
  extend Fallen::CLI

  def self.run
    @thresholds = [ 40, 60, 65, 70, 80, 85 ]
    @speeds     = [ 10, 20, 25, 30, 45, 50 ]
    @speed  = 100 # default speed

    pid_file "/var/run/quiet-fan.pid"
    stdout "/var/log/quiet-fan.log"

    puts "#{Time.now} Started."

    while running?
      temp = get_temp

      @thresholds.each_with_index do |threshold, index|
        @speed = @speeds[index] and break if temp < threshold
      end

      set_speed(@speed) if @speed != get_speed

      puts "#{Time.now} Temperature: #{temp}°C / Fan speed: #{@speed}%"
      sleep 10
    end

    puts "#{Time.now} Ended."
  end

  def self.usage
    puts "Quiet-Fan Usage:\n"
    puts "  quiet-fan.rb [ start | stop ]\n\n"
    puts "start: starts quiet-fan in the background"
    puts " stop: stops the background running quiet-fan"
  end
end

case Clap.run(ARGV, Azazel.cli).first
when "start"
  Azazel.daemonize!
  Azazel.start!
when "stop"
  Azazel.stop!
else
  Azazel.usage
end

I run this daemon from init.d and all is good. It can possible work for other cards and you can tweak it to fit even more.

It’s also possible that the card has something built-in but I haven’t found it yet. This works for me.