

FanCtrl3-Pro
USB-powered controller for three 4-pin PWM fans, driven by the CPU temperature of a Proxmox VE host - KiCad, MicroPython, OpenSCAD
- Size
- 90 × 60 mm
- Copper layers
- 2
- Thickness
- 1.6 mm
- Parts
- 39
- Nets
- 46
- Pads
- 179
- Tracks, vias
- 993, 120
- Pours
- 2
- Routed
- Yes
- KiCad
- KiCad 10.0 (file 20260206)
- Created
- 23 Sep 2026
- Updated
- 5 Oct 2026
Overview
FanCtrl3-Pro is an open-source printed circuit board by mikagosz, from the mikagosz/FanCtrl3 repository on GitHub, published under the MIT licence. It is a 2-layer board of 90 × 60 mm with 39 parts on 46 nets, routed with 993 tracks and 120 vias.
It is built around the LM27313XMF, DS18B20 and TPS2553DBV, with the SS14 among its other parts. Its parts include 16 resistors, 7 capacitors, 4 connectors, 3 ICs and 3 transistors. It belongs with the RP2040 boards of this library.
Main components
4LM27313XMF
SOT-23-5-40℃~+125℃@(TJ) 1 1.6MHz 2.7V~14V 400uA 5V~28V 800mA Adjustable Boost Boost Built-in No Overcurrent Protection、Cycle-by-cycle current limiting SOT-23-5 DC-DC Converters ROHSTexas InstrumentsDC-DC ConvertersDS18B20
TO-92-55℃~+125℃ 12bit 3V~5.5V 750ms Single-bus ±0.4℃ TO-92 Temperature Sensors ROHSUMWTemperature SensorsTPS2553DBV
SOT-23-6-40℃~+150℃ 1 1.5A 2.5V~6.5V 85mΩ Active High High Side Switch 过压保护、软启动、欠压锁定、反向电压保护、集成电荷泵、Overcurrent Protection、Over temperature protection、锁存保护、Short-Circuit Protection SOT-23-6 Power Distribution Switches ROHSTexas InstrumentsPower Distribution SwitchesSS14
SMA(DO-214AC)-55℃~+150℃ 1A 25A 300uA@40V 40V 550mV@1A Independent SMA(DO-214AC) Schottky Diodes ROHSMDDSchottky Diodes
README
README.md
FanCtrl3
A USB-powered controller for three 4-pin PWM fans, driven by the CPU temperature of a Proxmox VE host.
One USB cable to the host is all it needs — power, control and fan speed readings all go over it. The fan curve runs inside the controller, so a host reboot, a crashed service or a pulled cable never leaves the fans stopped.
Designed for small home servers and mini PCs running Proxmox: the machine sits in a closed cabinet, its own fan is not enough for the cabinet, and a set of quiet 120 mm fans should spin up only when the server actually works.
[!NOTE] FanCtrl3 is a hobby project, built in spare time. Updates may not come often — but ideas, questions and build reports are always welcome (see Contact and contributions).
Project status
[!WARNING] FanCtrl3 has not been tested on real hardware yet. Hardware testing is coming soon; this section will be updated with the results. Until the first boards have run for a while, treat this as a reviewed design, not a proven product.
Verified without hardware
| Area | How | Result |
|---|---|---|
| Schematics | KiCad ERC, both variants | 0 errors, 0 warnings |
| Pro PCB | KiCad DRC with schematic parity | 0 violations, 0 unconnected pads, 0 parity issues |
| Lite perfboard | the generator's own checker | every net connected, no hole shared by two nets, no wire through a foreign pad, no overlapping parts |
| Enclosure | intersection of the enclosure with the component bodies | 0 collisions, both variants |
| Control logic | 22 unit tests, run under CPython and MicroPython | all pass |
Firmware main.py | runs under the MicroPython unix port on stubbed hardware: replies, 25 kHz inverted PWM, watchdog; SERVICE and service mode; SAVE success and failure (12 checks) | all pass |
| Host daemon and CLI | 10 unit tests (Intel and AMD sensors, several CPU packages, CLI errors, a silent socket client) and 13 end-to-end tests against a simulated controller: sensor selection, curve, status, send, calibrate (incl. a dead fan and failsafe), clean stop, restart without a temperature, crash → failsafe | all pass |
Every push and pull request runs these tests on GitHub Actions.
Not tested yet
- Anything on a real board: soldering, the 12 V rail, the current limiter and its
FAULTsignal, real fan speeds from the tachometers, the DS18B20 probe, the LED, the watchdog, USB behaviour with and without a host. - Power drawn from a real USB port with three fans at 100 %.
- The udev rule on a real Pico (
2e8a:0005is MicroPython's default ID). - Printing and fitting the enclosure; the Lite mounting-hole positions.
Known issues
- AMD support (
k10temp,zenpower) is tested only against simulated sensors so far — a report from a real AMD host is welcome. tests/test_main_smoke.shdepends on timing and can fail on a heavily loaded machine; run it again before looking for a bug.
Features
- Three 4-pin PWM fans, 25 kHz PWM and tachometer reading on every channel.
- Powered from USB only. An on-board step-up makes the 12 V for the fans; a TI TPS2553 current-limited switch limits the fan side to 465–570 mA — the budget of a USB 2.0 port — and reports an overload to the controller.
- Curve in the controller, temperature from the host. A small daemon on the Proxmox host sends the CPU package temperature (Intel or AMD) every 5 seconds; the controller applies a curve with hysteresis and ramping.
- Safe by default. No temperature for 30 s → fans at 100 %. A dead microcontroller → the output transistors switch off → fans at 100 %. A clean host shutdown → fans rest at 20 % instead of alarming.
- Ambient probe. A DS18B20 on a cable measures the air in the cabinet and raises the fans on its own above 40 °C (60 %) and 45 °C (100 %).
- Stall detection per fan, per-fan minimum duty and a
calibratecommand that measures it. - Two variants, one firmware — see below.
- Host side needs nothing but Python 3's standard library, a udev rule and a systemd unit.
Two variants
| FanCtrl3 Lite | FanCtrl3 Pro | |
|---|---|---|
| Build | modules on a 72 × 47 mm perfboard (SCI PC-3) | custom 2-layer PCB, 90 × 60 mm |
| Soldering | through-hole only (plus one SOT-23-6 on an adapter) | 0805/1206 and SOT-23 by hand, no QFN |
| 12 V | Pololu U3V16F12 module | TI LM27313 boost on the board (12.4 V) |
| PWM output | BC547B, open collector | 2N7002, open drain |
| Current limit | TPS2553 on a SparkFun SOT-23 → DIP adapter | TPS2553 on the board |
| Pico | in sockets, removable | soldered flat |
| Build guide | docs/build-lite.md | docs/build-pro.md |
Both use the same pinout and run the same firmware.
Lite — perfboard wiring drawing | ![]() Pro — PCB, top |
![]() Lite — enclosure | ![]() Pro — enclosure |
How it works
Proxmox host FanCtrl3
┌────────────────────────┐ USB cable ┌──────────────────────────────────────┐
│ CPU temp ─► fanctl │ power + data │ Pico: curve, hysteresis, failsafe │
│ daemon ────┼───────────────►│ ├─ PWM ×3 ──► open collector/drain │
│ TEMP 54.0 every 5 s │◄───────────────│ ├─ tach ×3 ◄── fans │
│ STATUS, alarms │ │ └─ DS18B20 ◄── ambient probe │
└────────────────────────┘ │ │
│ VBUS ─► TPS2553 ─► 12V boost ─► fans │
│ (≈0.5 A) │
└──────────────────────────────────────┘The link is plain text over USB CDC — TEMP 54.0, STATUS, SET 1 40 — so it can
be driven by hand from any terminal. Full protocol: docs/firmware.md.
Power budget
The whole controller lives on one USB 2.0 port, which is allowed to supply 500 mA. The design is sized for three low-power 120 mm PWM fans rated at up to 0.6 W each (for example Noctua NF-P12 redux-1300 PWM):
3 × 0.6 W = 1.8 W at 12 V → ÷ 0.85 converter efficiency + ≈ 0.15 W for the Pico ≈ 0.45 A from the port.
[!CAUTION] Fans rated above 0.6 W each will not fit this budget. The TPS2553 limits the fan side to 465–570 mA and reports
FAULT, but the fans will not reach full speed. Check the rated input power of your fans before you build.
Getting started
- Pick a variant and order the parts — docs/bill-of-materials.md.
- Build the board — Lite or Pro.
- Print the enclosure — docs/enclosure.md.
- Flash the firmware — docs/firmware.md:
MicroPython for
RPI_PICO, thenfirmware/flash.sh. - Install the host side on Proxmox — docs/host-proxmox.md:
bash sh host/install.sh # as root on the Proxmox host fanctl status fanctl calibrate # finds the lowest duty each fan still spins at
Repository layout
| Path | What is inside |
|---|---|
hardware/tools/ | generators — the design lives in code: design_pro.py and design_lite.py are the single source of truth |
hardware/pro/ | KiCad project of the Pro PCB, schematic PDF, fabrication/ Gerbers + drill ZIP and BOM, preview/ 3D renders |
hardware/lite/ | Lite schematic (KiCad + PDF), perfboard drawing (SVG) and wiring table |
hardware/enclosure/ | parametric OpenSCAD enclosure and ready STL files for both variants |
firmware/ | MicroPython for the Pico: logic.py (no hardware, testable) and main.py (pins) |
host/ | fanctl daemon and CLI, udev rule, systemd unit, installer |
sim/ | the controller on a pseudo-terminal, for testing the host side without hardware |
tests/ | everything that runs without hardware: tests/run_all.sh |
docs/ | documentation |
Documentation
- Hardware design — circuit description, pinout, design decisions
- Bill of materials — both variants, with suggested shop links
- Building FanCtrl3 Lite — perfboard assembly
- Building FanCtrl3 Pro — ordering the PCB and hand soldering
- Enclosure — printing and assembly
- Firmware — flashing, control behaviour, serial protocol
- Host software on Proxmox — installation and
fanctl - Development — regenerating the outputs, running the tests
Contact and contributions
Ideas, improvements, a better circuit, a build report or a question — all welcome. Open an issue on this repository or write to support@fractal8.eu. See CONTRIBUTING.md.
Support the project
FanCtrl3 is built in spare time. If it is useful to you, you can support its development through GitHub Sponsors — it helps pay for parts and prototype boards.
Licence
MIT — see LICENSE. This covers the hardware design files, the firmware and the host software.
Parts
39| Qty | Value | Footprint | References |
|---|---|---|---|
| 5 | 10k | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R2, R6, R13, R14, R15 |
| 4 | 100k | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R3, R7, R8, R9 |
| 4 | 4k7 | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R10, R11, R12, R16 |
| 4 | M3 | MountingHole:MountingHole_3.2mm_M3 | H1, H2, H3, H4 |
| 3 | 10u 25V | Capacitor_SMD:C_1206_3216Metric_Pad1.33x1.80mm_HandSolder | C2, C4, C5 |
| 3 | 2N7002 | Package_TO_SOT_SMD:SOT-23_Handsoldering | Q1, Q2, Q3 |
| 2 | 100n | Capacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolder | C1, C7 |
| 2 | 51k | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R1, R4 |
| 1 | 100u 25V | Capacitor_THT:CP_Radial_D6.3mm_P2.50mm | C6 |
| 1 | 10u | Inductor_SMD:L_Changjiang_FNR5040S | L1 |
| 1 | 220p | Capacitor_SMD:C_0805_2012Metric_Pad1.18x1.45mm_HandSolder | C3 |
| 1 | 91k | Resistor_SMD:R_0805_2012Metric_Pad1.20x1.40mm_HandSolder | R5 |
| 1 | DS18B20 | TerminalBlock:TerminalBlock_Xinya_XY308-2.54-3P_1x03_P2.54mm_Horizontal | J4 |
| 1 | FAN1 | Connector_Molex:Molex_KK-254_AE-6410-04A_1x04_P2.54mm_Vertical | J1 |
| 1 | FAN2 | Connector_Molex:Molex_KK-254_AE-6410-04A_1x04_P2.54mm_Vertical | J2 |
| 1 | FAN3 | Connector_Molex:Molex_KK-254_AE-6410-04A_1x04_P2.54mm_Vertical | J3 |
| 1 | LM27313XMF | Package_TO_SOT_SMD:SOT-23-5_HandSoldering | U3 |
| 1 | Raspberry Pi Pico | Module:RaspberryPi_Pico_SMD_HandSolder | U1 |
| 1 | SS14 | Diode_SMD:D_SMA_Handsoldering | D1 |
| 1 | TPS2553DBV | Package_TO_SOT_SMD:SOT-23-6_Handsoldering | U2 |
Questions
How big is the FanCtrl3-Pro PCB?
It measures 90 × 60 mm and has 2 copper layers, 1.6 mm thick.
What parts does the FanCtrl3-Pro use?
39 parts, built around the LM27313XMF, DS18B20, TPS2553DBV and SS14. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.
Where can I download the FanCtrl3-Pro KiCad files?
From the mikagosz/FanCtrl3 repository on GitHub, at the commit this page was made from: the board is hardware/pro/FanCtrl3-Pro.kicad_pcb and its schematic hardware/lite/FanCtrl3-Lite.kicad_sch. PCBKit opens the board in the browser, with nothing to install.
Can I use the FanCtrl3-Pro design in my own project?
Its repository publishes it under the MIT licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).
Similar boards
- 4 layers66 × 90 mm

- 2 layers75 × 60 mm

Circuit design
heresiarch/esp32-wifi-eth-gateway
This is proof of concept of a Wifi to Ethernet Gateway with ESP32
10 parts1Apache-2.0 - 2 layers85 × 45 mm

- 6 layers140 × 100 mm

Sbc baseboard
calicopizzadelivery/sbc-development-baseboard
Baseboard for remote management of an attached SBC: K64 MCU as USB HID to the target and Ethernet to the workstation, six switched USB-A ports, isolated SPDT relays, level-shifted console, switched target power
271 partsApache-2.0 - 4 layers100 × 60 mm

- 4 layers106 × 110 mm

RearCircuitBoard 10
ssbingo/samba-solar-track
Samba Solar Track – Solarnachführung mit Sturmschutz: Handbuch, Platine und Gehäuse für den Nachbau (10,1-Zoll-Version)
329 parts - 4 layers42 × 100 mm

Psu
xdylanm/modular-system-psu
A PSU for a modular Eurorack system, featuring +/-12V and 5V rails, USB-C input, and a regulated USB-A output.
68 partsMIT - 2 layers139 × 139 mm

Breeze electronics design
microdynamics-robot-quadcopter/breeze_electronics_design
This project is created and managed by EDA softwares, which contains the breeze quadcopter's component library, footprint library, schematic, printed circuit boards, etc.
107 parts13GPL-3.0


