Converting a PWM-signal to a DC-signal for powering the fan on your aftermarket GPU-cooler

After replacing the stock cooler on my graphics card (Replaced the stock 9600GT cooler with a Arctic Cooling Accelero S1 rev.2), i quickly found out that it needed a fan under load, as it’d otherwise crash when the VRM’s reached upwards of 100 degrees. But without running a 3D game, there’s really no need to have a fan running. So, what we’re looking for is a semi-passive cooling solution, driven by the GPU temperature.

The speed of the standard fan was regulated by a PWM signal coming from a chip on the PCB. Unfortunately, i couldn’t get the duty cycle below 20% in software, which still keeps all PWM fans running. To get better fan control, a PWM-DC converter was needed.

This is the schematic. First, the PWM signal is compared against a the voltage produced by R3 and R4, enabling the first opamp to output a clean 0V – 12V block wave, basically a cleaned-up version of the original PWM signal. This signal goes through a low-pass filter formed by R2 and C1, converting the duty cycle to a corresponding voltage (10% = 1,2 volts, 50% = 6 volt et cetera). The exact values of these components are not really important, just be sure the time constant of the filter (resistance * capacity) isn’t too small or too big, we’re looking for a RC value in the 1mS-1S range. The second opamp then drives Q1 with the voltage needed to put the exact same voltage on the fan as is outputted by the low-pass filter – if the voltage on R1 is not yet as high as on the + input of the opamp, the voltage is raised on the base of the transistor, allowing for more current flow and a higher voltage on R1 until the voltages are equal.

This is what the finished product looks like and how it’s attached to the video card. I decided against making a PCB, as a $5 breadboard works just fine. You can see that there’s 3 NPN transistors in parallel for driving the fan, as i did not have ones at hand that could dissipate all the heat.

The exact temperature-voltage chart can be made in MSI afterburner or any other program that lets you change the fan speed of your GPU (e.g. Rivatuner). If you’re planning on making a PWM->DC converter for yourself, know that any single-supply opamp is suitable, the only thing to look out for is the voltage swing of the ouput: my lm2902 isn’t rail-to-rail, so i can only regulate the output from 0V to 12 – 1.5 = 10.5 volts, which is suboptimal, but more then adequate for my the lowly 95W TDP – I only chose it because it’s a quad opamp for $0,20 and i had one lying around.

The finished product works really well! When just browsing or listening to music, the fan does not turn on, and when playing videogames or other intensive 3D applications, the fan turns on until the GPU gets cool enough.

17 comments

  1. crossposted from Reddit: You’re using an emitter follower to drive the fan. This limits the max voltage across the fan to 11.3V (Vsupply minus VBE), which means that you can’t run the fan at its full speed. I suggest you put the fan in the collector leg rather than the emitter leg and rearrange the feedback. BEWARE, it will be harder to stabilize because you’re adding lots more gain. (Emitter follower = gain of +1, common emitter amplifier with collector load = gain of minus A_Big_Number). One way to do it with NPN transistor is attached IMGUR. But a PNP transistor would let you connect the fan to ground which would be more conventional. This circuit applies essentially all of the supply voltage to the fan (it drops VCEsat across the transistor, this is about 0.05 volts).

  2. Hi Hedgehog:

    I came across this page while trying to find a circuit to control a 3-pin CPU fan from a 4-pin header. After looking up the specs for 4-pin fan control, I think there are a few things wrong with your circuit, and a few things that can be improved:

    1) The PWM signal is open-collector, which means it needs a pull-up resistor to actually produce a pulse train. Furthermore, the spec says the pull-up must be to no more than 5.25V, and preferably to 3.3V, and that the output current must not exceed 5mA. The easiest fix for this is probably to just put another voltage divider on the + input of the first op-amp, with 4.7K to ground and 6.8K to 12V (for a ~5V pull-up) or 3.6K to ground and 10K to 12V (for a ~3.3V pull-up).

    2) As you’ve pointed out, your op-amp can’t swing rail-to-rail, but it can’t work with inputs within 1.5V of the positive rail either. This can be fixed by putting a voltage divider both on the integrator (a second 100K resistor in parallel with C1) and in the feedback circuit (10K between Q1-e and the op-amp’s -ve input, and another 10K between there and ground). That way, the op-amp is only working with inputs in the 0 to 6V range.

    3) Although the op-amp output can’t exceed 10.5V under any sort of load, with a little help it can. I haven’t done the calculations, but a 1K pull-up resistor on the second op-amp output might help. Then it is the resistor driving Q1 instead of the op-amp. This should get you up to 11.3V output to the fan.

    I’m working on a slightly improved version of your circuit which will also include an adjustment that will let you set either a maximum voltage (e.g. the fan will never exceed 80%) or a minimum voltage (e.g. the fan will never drop below 30%) to allow fine tuning to the application. I’ll publish it on my web site when it’s done.

    1. Thanks for your thoughts. I was not aware the PWM signal was open collector, without a pull-up resistor this should indeed not work at all. Smart solution for the rail-to-rail problems as well! I look forward to seeing your circuit.

      1. Just discovered another issue. I don’t know what the PWM frequency on your card is, but on motherboards, it’s generally around 25kHz. At 50% duty cycle, that’s a pulse width of 20us. Unfortunately, the slew rate of the LM2902 (and the LM358 that I used in my experiments) is only about 0.6V/us. That means that to swing from 0 to 12V takes the whole 20us of the pulse width. So at 50% pulse width, you end up with a pure triangle wave instead of the desired crisp square wave. Worse than this, at duty cycles below 50%, you simply get a series of triangular spikes ascending from a 0V baseline, with the height proportional to the duty cycle. At duty cycles above 50%, you get the opposite, with spikes descending from the 12V (well, 11.3V) rail. To get proper square waves, I needed to switch to a TL072, a much faster (13V/us) modern op-amp (which is pin-compatible with the older models).

    1. Looks interesting, but could you put up something where you explain your design choices? Like, the TIP127 is a darlington with a gain of 1000, so why didn’t you put it at the output of the opamp directly? Why R2 and R4, what are they for?
      And like stefanvorkoetter mentioned, the PWM-signal is open-collector, meaning you have to connect a pullup-resistor to it to get a voltage, and you can’t put too much current into it. Good luck with your design!

      1. I tried in simulator your suggestion to put opamp ouptup directly to tip127, but it did not work. R2 with R1 is a voltage divider, but we can leave R2. R3 with R4 is also a V divider i use it because the opamp cant output less then 1,5 V. I use Zener diode to pull up PWM tp 4.3 V and max current is 3.5 mA. First i wanted to build your circuit and before i tested it in Proteus, and i noticed that under 40 % pwm, voltage is less than 4 V. I dont know if it is real, but i want to control CPU cooler, and i think it stops under 4 V. Here is a diagram, data is from Proteus sim. http://i47.tinypic.com/34sozme.jpg

  3. Hello Hedgehog!

    i started to build my circuit, and i need some help.
    To test opamp, i build this schema: http://i46.tinypic.com/2wnafeu.jpg
    I dont undertand the behavior of the opamp, when PWM=100, fan stops, if i decrease pwm fan getting faster. Could you tell me why is it?

    Thanks for reply.

    1. Could you put up a page somewhere (wordpress or something) explaining what exactly your schematic does? For me personally I feel like doing that often leads to a better understanding of the problem, and it would help me understand why you did not put a low-pass filter in. Also, is the simulation behaving in this way as well?

      1. Hi again!

        I’ve finished the converter. (with a 1k resistor to pwm pin the inverting isue goes away)
        It works the way i wanted, the final schema:

        I can set minimum speed with RV1 and the gain (-> max speed) with RV2. Here is pwm-rpm diagram, measured with SpeedFan:

        By the way, in your config what C2 is for?

        Thanks all help.

Leave a reply to Hedgehog Cancel reply