MSI Forgot to Wire My Fans, So I Built My Own Fan Controller
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.
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.
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.
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 chip is there. The traces aren't.
This means:
- No CPU temperature reading in the BIOS or through Super IO
- No PWM fan control - the board can't adjust fan speed based on temperature
- No fan RPM detection - the tachometer pin (pin 3) goes nowhere
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?
They delivered a beautiful board with genuine overclock potential and forgot to deliver on a feature we now take for granted.
What now?!
I started looking for solutions.
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 also more expensive than 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:
- An Arduino can generate a 25kHz PWM signal. This is the standard frequency for 4-pin PC fans.
- Windows can read CPU temperature directly from the CPU's internal thermal diode, completely bypassing the useless Super IO chip.
- A USB serial connection between the two is trivial to manage.
So this was the plan:
- Read the CPU temp on the PC side
- Calculate a fan speed based on a curve
- Send the duty cycle to an Arduino over serial
- 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 even have thermal sensors.
And even without thermal sensors, it could also work as a manual fan controller, so I decided to polish everything up and release it in two parts:
- The Arduino script, which is Open Source, under the MIT license, and available on Github.
- The Windows companion application, sold on Gumroad.
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.
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:
- PC app connected? Use whatever duty cycle the app sends.
- No PC, but motherboard PWM detected? Mirror the motherboard's signal.
- 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. Just wire it to D4 and ground on the Arduino, and now it's the fan speed toggle.
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.
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. The editor lets you drag points around, add new ones, right-click to delete. 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.
- 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.
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