自制了一个廉价的风扇控制器,因为我的主板PWM功能失效。
Built a cheap DIY fan controller because my motherboard never had working PWM

原始链接: https://www.himthe.dev/blog/msi-forgot-my-fans

## 复古电脑抢救:解决风扇控制缺陷 出于怀旧,作者着手打造一台能够兼顾经典游戏和现代任务的复古电脑。该配置以AMD Phenom II X6处理器为中心,搭配一张出人意料的现代GTX 960显卡以兼容Windows XP,以及一张MSI 970 Gaming主板。然而,该配置遇到了一个问题:MSI主板存在一个关键缺陷——负责风扇控制的Super IO芯片接线不正确,导致风扇转速失控。 现有的解决方案要么昂贵,要么不兼容。作者巧妙地使用Arduino读取CPU温度并控制风扇转速,通过PWM信号绕过了有缺陷的芯片,从而创建了一个定制解决方案。这个方案进一步发展成为一个更广泛的项目,旨在解决许多旧电脑缺乏4针风扇控制的问题。 最终成果是一个两部分组成的系统:一个Arduino脚本和一个名为“DummyFanX”的C++应用程序(兼容Windows XP至11)。DummyFanX允许自定义风扇转速曲线,通过HWiNFO或定制内核驱动程序(PawnIO)监控温度,并提供手动控制选项。该项目是开源的,为控制旧电脑甚至新电脑的风扇提供了一种经济高效且通用的解决方案。

## DIY风扇控制器总结 一位用户使用Arduino Nano和Windows应用程序构建了一个自定义风扇控制器,以解决主板PWM风扇控制功能失效的问题。Arduino根据Windows应用程序读取的CPU温度生成25kHz PWM信号,并通过串口发送。固件是开源的(MIT许可)。 讨论围绕替代信号生成方法(使用音频端口)、系统崩溃时的故障保护机制(将风扇设置为100%速度)以及在现代CPU散热管理下进行此类项目的必要性展开。许多评论者争论了微控制器与模拟电路在风扇控制方面的优缺点,引用了易于调整、长期稳定性以及元件数量等因素。 一位贡献者分享了一个类似的项目,使用ESP32实现WiFi启用的风扇控制,可购买或DIY构建,并提供开源代码和原理图。一个关键点是,原始发帖者主板上的SuperIO芯片可能存在问题,即使PS/2等端口功能正常,也可能接线错误。
相关文章

原文

March 22, 2026

Links


How it all started

Nostalgia hit me like a ton of bricks recently. The early 2010s were calling out to me. I really wanted to build a retro computer that could run old games, but at the same time, I wanted something that could still be somewhat useful for modern things.

So I've started going to flea markets, asking friends for parts and looking out for good deals. I got a really nice collection going, including a socket 754 motherboard, a Sempron Mobile 3400+ CPU, and some DDR1 ram, but when building the actual PC, this is what I finally settled on:

  • CPU: AMD Phenom II X6 1075T
  • RAM: 2x4GB Corsair 1600MHz + 2x4GB Corsair 1866MHz
  • GPU: NVIDIA GTX 960
  • Motherboard: MSI 970 Gaming (AM3+)

Peak older brother core. Well, except that GTX 960, but it's the newest card that has official drivers for Windows XP, and I wanted to go all out. To be fair, the GTX960 is something that somone would've bought back in 2015 to upgrade their AM3/AM3+ rig, so it still fits the theme.

If you disagree, just know that I'm always up for a fiery debate.


The motherboard

The heart of the build is the MSI 970 Gaming (MS-7693), and on paper, it's pretty solid.

MSI 970 Gaming Motherboard The black PCB, the red accents, full solid capacitors, super ferrite chokes. And MSI's marketing team went hard on it - Military Class 4 components, Killer E2205 NIC for "prioritized gaming traffic", Audio Boost 2 with the Realtek ALC1150, and support for SLI and CrossFire through two PCIe 2.0 x16 slots. MSI 970 Gaming Motherboard IO The VRM can handle overclocking without catching fire, it's got 6 SATA III ports, and it even came with USB 3 at a time when it was only a "nice to have".

For 2014, I think it's pretty impressive, and even today it still feels somewhat modern.


One Small Problem

When I first fired it up and went into the BIOS, I immediately noticed something was off.

BIOS screen showing 255°C and 0 RPM

CPU Temperature: 255°C.
Fan Speed: 0 RPM.

Foreshadowing: 255 is 0xFF, the value you get when you read a register that isn't connected to anything.

I thought it was a bad sensor, a BIOS bug or maybe a setting I missed.

So I did what any reasonable person would do, and searched online.

And that's when I facepalmed so hard, it could power Earth for the next 100 years.

MSI forgot to wire the Super IO chip.

This board has a Fintek F71878AD, a perfectly capable Super IO controller that can read temperatures, control fan PWM, and monitor fan speeds, but MSI just didn't connect it to the board.

The CPU fan header defaults to whatever curve the Super IO chip has hardcoded, which never drops below 50% and only ramps up from there. And the other 4 and 3 pin headers just run at full blast, no matter what.

I genuinely don't understand how this passed QA. Did nobody at MSI plug in a fan during testing? Did they test in a server room where nobody could hear the fans anyway?


What now?!

I looked up products, searched reddit threads and even asked LLMs.

The suggestions were either expensive, proprietary or software solutions that didn't work for my motherboard anyway.

I also found fan controllers with potentiometers that you manually adjust, which were more expensive than I expected.

All of these solutions are subpar. You either pay too much or sacrifice too much functionality - or both. Compatibility can be a problem too.

For example, Corsair iLink is proprietary, and will only run on Windows 10 and above.

What I really wanted was a cheaper Corsair iLink that doesn't require diving into a rabbit hole of proprietary accessories.

Here's what I knew:

  1. An Arduino can generate a 25kHz PWM signal. This is the standard frequency for 4-pin PC fans.
  2. Windows can read CPU temperature directly from the CPU's internal thermal diode, completely bypassing the useless Super IO chip.
  3. A USB serial connection between the two is trivial to manage.

So I came up with a plan:

  1. Read the CPU temp on the PC side
  2. Calculate a fan speed based on a curve
  3. Send the duty cycle to an Arduino over serial
  4. Have the Arduino send the PWM signal to a fan hub

This could help everyone

While working on this project, I realized it fixes a much bigger problem than one botched MSI board.

A ton of older PCs don't have 4-pin fan headers at all. Socket 754, Socket 939, AM2, LGA 775, tons of early AM3 boards; they all shipped with 3-pin headers. Some have voltage control, but most run at fixed 100% speed. And many of these have thermal sensors.

And even without thermal sensors, the arduino could work as a manual fan controller, so I decided to polish everything up and release it in two parts:

Since the spec for the Arduino script is open, you don't even have to use my application, you can just write your own.


The Script

I used a Nano clone for this project. A board that costs about the same as a nice coffee, with the same ATMEGA328P chip as the original.

All nano variants should be supported. If you need it on other models, feel free to contribute or fork the repo.

One output pin (D9) generates a 25kHz phase-correct PWM signal through direct Timer1 register manipulation. Not analogWrite(). Arduino's default PWM runs at ~490Hz, which could make your fans whine.

Two optional input pins: D2 reads the motherboard's own PWM signal, and D3 reads the fan tachometer for RPM reporting.

Wiring is just D9 to your fan hub's PWM wire, ground to ground. Plug the Nano into a USB header or route a cable out the back.

Arduiono wiring diagram

On boot, the fans blast at 100% for 3 seconds, then drop to 50% (I thought it would be cool if it did that, like a little warm-up). From there, a priority system takes over:

  1. PC app connected? Use whatever duty cycle the app sends.
  2. No PC, but motherboard PWM detected? Mirror the motherboard's signal.
  3. Nothing at all? Hold at the current preset speed.

You don't even need the PC app. There's a physical button input on pin D4 that cycles through speed presets: 0% → 25% → 50% → 75% → 100%. If you cannot or do not want to use a control application, you could realistically repurpose your computer's reset button for this.


The Application

The Arduino script is nice for a set-and-forget setup, but I also wanted to do proper fan curves, like every motherboard made after 2014 does out of the box.

That's how DummyFanX came to be. I first built it in Rust with egui. It worked for me, but it would only run on Windows 8 and above. It could also run on Windows 7, but only with some compatibility hacks, and I didn't like that.

Since the whole point of writing an article about this project and bringing awareness to the PWM situation was to make it available for as many people as possible, including people running Windows XP, I rewrote it in C++ with Dear ImGui and DirectX 9. And it now supports, Windows XP through Windows 11.

DummyFanX main screen

Twice a second, the app reads the CPU temp, runs it through a fan curve, and sends the duty cycle to the Arduino. The curve has smoothing built in - hysteresis, rate limiting, and a zero-RPM mode so fans can fully stop at idle. If you've ever tweaked a fan curve in a BIOS, it's exactly that, but more flexible.

For temperature reading, two backends are supported:

  • HWiNFO - if you already run HWiNFO, just tick "Shared Memory Support" in settings and DummyFanX picks up any sensor it can see.

DummyFanX HWiNFO shared memory checkbox


  • PawnIO - a signed kernel driver that reads the CPU's thermal diode directly. Lower overhead, no external app needed. PawnIO's DLL is architecture-specific, so you'll need the 64-bit build of DummyFanX on modern systems.

If neither is available, it still works as a manual fan controller.

DummyFanX manual control slider

It lives in your system tray. Can be configured to start with Windows, connects to the Arduino, does its thing in the background. If the temperature reading ever fails, it defaults to 100%.

Both 32-bit and 64-bit builds are included.


Why's it called DummyFanX?

Well, on one hand, it controls fans. On the other, any dummy can slap an "X" on an app and think they're smart.

Real talk though, I just thought it sounded cool.


Nano clone and a single pin,

fans go quiet, let the fun begin

联系我们 contact @ memedata.com