GPU and CPU dependent Case Fan Control with KVM using Linux and Windows Software [Working]

I am running Windows-on-Linux via KVM with hardware passthrough, and am wondering what the best way to connect all my fans (preferably natively) that would allow control of case fans from CPU, and when the KVM is running from both the CPU and KVM’s GPU.

I have an MSI X670-Pro which has:

  • 6x Case Fan headers (1A @12V each)
  • 1x CPU Header (2A @12V)
  • 1x AIO/Pump Header (2A @12V)
  • 2x Mystic Light RGB 5V headers (might be OpenRGB compatible, the GitLab Readme says it isn’t, but the website says it is…)

I have also just bought a Corsair Commander Pro which has (but could return if there’s a better option):

  • 6x Fan Header (1A@12V each, the D5 pump is SATA power and other people don’t have issues)
  • 4x Temperature inputs
  • 2x RGB 5V headers (up to 4x strips each) (OpenRGB compatible)

Custom Watercooling including:
1x Alphacool ES flow and temperature indicator “HighFlow” with RPM-Signal
1x EK-Quantum Inertia D5 PWM D-RGB (23W / 1.9A @12V)

My current plan is to connect:


  • Case fan header:
    • 4x CPU radiator fans
    • 2x Case fans
  • CPU fan header: Alphacool flow indicator (has the added bonus of removes chance of “no CPU fan” error" and will cause issues if there is no flow)
  • Pump header: N/A
  • RGB: N/A

Commander Pro:

  • Fans:
    • 4x Case Fans
    • 1x D5 pump
    • 1x N/A
  • Temperature probe:
    • 1x Alphacool temperature indicator
    • 3x Unused
  • RGB:
    • 1x CPU Block lighting
    • 1x Res lighting

My thinking is to use the Linux kernel driver for the Commander Pro (introduced in 5.9 apparently) to interface with fancontrol and run the 4x case fans with the CPU, as the GPU will be idle, and then when the KVM is running (in Windows) use iCUE to run 2x case fans with the GPU and 2x with the CPU.

This would allow me to connect each fan to a dedicated fan header and monitor the RPM of each fan, rather than use any PWM fan splitters which would discard the data from one fan per splitter.

The only thing I don’t know if it will work is if iCUE will be able to detect the CPU temperature when it’s running in a KVM - I cannot test just yet as I’m still waiting on most of my watercooling and (more importantly) my CPU to arrive - I could run 4x Case Fans using 2x headers with PWM splitters, but I’d rather not.

I would like all the Case Fans to be controlled by the hottest of both CPU and GPU, but AFAIK that isn’t a thing yet (at least in iCUE), which is unfortunate.

Hmmmm so after some research, it appears that the way I want to connect up all my fans and have both CPU and GPU temperature may be best solved by utilising an arduino…

Only the host (Linux) will only be able to access the CPU temperature, apparently. I was thinking about seeing if I could emulate a thermal sensor either virtually or physically using one of the 4 ports on the Commander Pro, but I realised this was overcomplicating things.

So, new plan:


  • CPU header: Alphacool flow sensor (unchanged)
  • AIO header: unused (unchanged)
  • Fan Header 1-4: 4x CPU radiator fans
  • Fan Header 5: Case fan: to stripboard, where the PWM signal is sent to an arduino, not the fan.
  • Fan Header 6: Case fan: to stripboard; only pin 3 (tachometer) is sent to the motherboard header, power/PWM from stripboard/arduino.

Commander Pro:

  • Temp sensor 1: Alphacool coolant sensor (unchanged)
  • Temp sensors 2-4: unused (unchanged)
  • Fan Header 1: EK D5 pump (unchanged) - this shouldn’t be an issue as it also has SATA power, so it shouldn’t actually draw from this header.
  • Fan Header 2: Unused (unchanged)
  • Fan Header 3: 4x Case fans: PWM by GPU temperature (iCUE) sent to arduino, pins 1/2 are on stripboard, and the tach is sent to the fan header.
  • Fan Headers 4-6: pins 1/2 are on stripboard, tach is sent to the fan header, PWM obtained from arduino.

I now just need to obtain an arduino and code up a basic “if CPU PWM is bigger than GPU PWM signal (but not 100, if the Commander Pro runs at 100 when there is no software control), output CPU PWM, else output GPU PWM”… which would be easier if I’d ever done something like this before. It should be pretty simple…

There is potentially also the issue of where the current flows from PWM output… I assume it’s through the ground wire? If so, it shouldn’t be an issue.

As a side note, I am using Noctua iPPC-3000s as my case fans, so I never want them to run at 100%, because over 2000 RPM they get very noisy, but that’s what PWM control is for.

PWM (at least through the Commander Pro) is 5V.

Using a Raspberry Pi Pico, which is a dual core microprocessor, I have some working code:

Gregregorovich/PWM-Compare: Compares two different computer fan PWM duty cycles and outputs the highest duty cycle (