Skip to the content
PCBKitNew board
4 layers94.5 × 99.8 mmValveController, the printed circuit board in 3D

ValveController

afewyards/HydroMix

A mains-powered, Zigbee-connected controller for a hydronic 3-way mixing valve — it regulates the supply-water temperature of a floor heating/cooling system and keeps regulating autonomously if the Zigbee link goes down.

Size
94.5 × 99.8 mm
Copper layers
4
Thickness
1.6 mm
Parts
123
Nets
99
Pads
423
Tracks, vias
821, 506
Pours
14
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
15 Jul 2026
Updated
18 Oct 2026

Overview

ValveController is an open-source printed circuit board by afewyards, from the afewyards/HydroMix repository on GitHub, published under the MIT licence. It is a 4-layer board of 94.5 × 99.8 mm with 123 parts on 99 nets, routed with 821 tracks and 506 vias.

It is built around the ESP32-C6-WROOM-1-N4, IRM-03-5 and Z0103MN, with the IS31FL3730-QFLS2-TR, TPS61040DBV and HCPL-354-06AE among its other parts. Its parts include 41 resistors, 22 capacitors, 15 diodes, 10 connectors and 8 ICs. It belongs with the ESP32 and RISC-V boards of this library.

Main components

12

README

README.md

ValveController

A mains-powered, Zigbee-connected controller for a hydronic 3-way mixing valve — it regulates the supply-water temperature of a floor heating/cooling system and keeps regulating autonomously if the Zigbee link goes down.

One repo, three parts: a custom KiCad PCB (ESP32-C6), ESP-IDF firmware with a host-testable control core, and a Zigbee2MQTT converter.

Status: Firmware 2.0.0 (rev-B: HydroMix2 identity, AUX 24VAC outputs, iPWM2 pump drive, on-board 8×8 display) is implemented on this branch and passes the full host-side unit suite (23/23); on-target bring-up is pending assembled boards, per firmware/REVB_BRINGUP.md. Firmware 1.7.0 remains the released, OTA-deployed firmware (2026-08-11) on the currently-installed board. PCB rev A — the board 2.0.0 targets — is layout-complete and fab-ready (4-layer, 100 % routed, DRC clean); boards ordered 2026-08-12, not yet assembled/bench-tested (the schematic/PCB title block labels this board revision "A"; firmware docs call it rev-B — the 1.x board predates the lettering). Personal project.

ValveController 3D render

What it does

A 3-way valve mixes SOURCE water (the hot or cold secondary side of a heat exchanger) with RETURN water from the floor loop to produce SUPPLY water at a target temperature. The controller:

  • Auto-detects mode (heating / cooling / idle) from a heat-exchanger inlet sensor — the host never has to tell it which season it is.
  • Regulates supply temperature with a feed-forward mixing model + PI trim, hard-bounded to floor-safe limits (17–35 °C).
  • Drives an ESBE ARA661 230 V 3-point actuator through two solid-state (opto-triac) channels.
  • Reads 5× DS18B20 probes (supply, return, source, and two heat-exchanger points) over 1-Wire.
  • Exposes everything over Zigbee (Router role) for monitoring, tuning, the regulation-enable toggle, and OTA — with a first-class Home Assistant / Zigbee2MQTT integration.
  • Runs fully standalone when Zigbee is unavailable, with a supply "governor" that de-escalates any temperature excursion toward safe recirculation regardless of mode.

⚠️ The counter-intuitive safety rule

Valve position 0 % = full recirculation (return water only — thermally harmless). 100 % = full source (full hot or cold). Parking the valve "closed" (100 %) would run the floor at full source temperature and is dangerous — so the safe park/idle position is mid-travel (~50 %), and a resync always drives toward the 0 % end, never the source end. See the design spec for the full rationale.

Hardware

Custom single-board design in KiCad (pcb/). Rev A highlights:

BlockParts
MCUESP32-C6-WROOM-1-N4 (RISC-V, 802.15.4 Zigbee radio, 4 MB flash)
Power230 V AC → Mean Well IRM-03-5 (5 V) → TLV75733 LDO (3.3 V); USB-C 5 V is diode-OR'd in (B5819W) so the board bench-powers and flashes over USB-C with no mains
Pump interfaceTPS61040 boost to 24 V, driving a Wilo Para ST 15-7-50 iPWM2 circulator over its PWM/feedback interface
Valve drive2× channel: MOC3063S zero-cross opto-triac → Z0103MN triac, switching the 230 V 3-point actuator; RC snubbers + X2 safety caps
AUX outputs2× CPC1035N PhotoMOS channels (24 VAC) with HCPL-354 loop-open/short detection
Mains protectionVaristor (B72210S) + fuse
Sensing5× DS18B20 on dedicated 1-Wire connectors (4.7 k pull-ups)
I/OTactile button, 8×8 LED matrix (KWM-20881AGB + IS31FL3730 driver), USB-C — native USB-Serial-JTAG (power, flash, console, JTAG in one port)
ConnectorsPhoenix pluggable terminal blocks (mains in, actuator) + 5 sensor headers

Full parts list: pcb/ValveController.csv. Custom 3D component models live in pcb/3dmodels/; board.step (repo root) is the assembled-board export.

Firmware

ESP-IDF 5.5.x, plain C on FreeRTOS. See firmware/README.md for the full build/flash/monitor guide, GPIO map, partition/OTA scheme, console commands, and gestures.

The control logic lives in a pure-C, IDF-free component (firmware/components/ctrl_core/) so it compiles and unit-tests on the host (macOS/Linux) before any hardware is involved:

  • feedforward — exact mixing physics, (T_set − T_return) / (T_source − T_return)
  • pi — PI trim with conditional anti-windup
  • governor — outermost safety stage; ramps toward recirculation on any supply excursion
  • mode_detect — heating/cooling/idle with asymmetric dwell + hysteresis
  • degradation — sensor-fault fallback ladder
  • pos_estimator, interlock, alarm, config_map

The IDF-side glue (firmware/main/) wires that core to hardware: sensors_hw, valve_hw, zigbee, ota, ui, console, control_task, config.

Quick start:

bash
. ~/esp/esp-idf/export.sh
cd firmware
idf.py set-target esp32c6       # first time only
idf.py build
idf.py -p <PORT> flash monitor  # over USB-C; Ctrl+] to exit the monitor

Host-side control tests (plain CMake + Unity, no hardware): firmware/test_host/.

Zigbee / Home Assistant

Router role · manufacturer Knife · model HydroMix.

  • EP1 — Basic, Identify, On/Off (water_running = regulation enable, driven by the host's pump/flow automation), Thermostat (local temp = supply; setpoints clamped 17–35 °C; mode is auto-detected, host SystemMode writes accepted-but-ignored), Analog Output (manual position, writable only while regulation is off), OTA client, and a manufacturer-specific cluster (0xFC00) exposing ~10 tunables, a self-clearing resync, and read-only alarm/fault bitmaps.
  • EP2–EP6 — Temperature Measurement for supply, return, source, HX-A, HX-B.

z2m/valvectl.mjs is the external Zigbee2MQTT converter (friendly entity names, tunables as settings, alarms as binary sensors, OTA index). The manufacturer OTA-publishing steps are documented in the comment header of that file.

Repository layout

text
ValveController/
├── pcb/                        KiCad project (schematic, board, DRC rules, BOM)
│   ├── 3dmodels/               custom STEP models
│   ├── Kleist2.pretty/         project footprint library
│   └── backups/                local pre-edit snapshots (git-ignored)
├── firmware/                   ESP-IDF application
│   ├── main/                   IDF glue (sensors, valve, zigbee, ota, ui, console)
│   ├── components/ctrl_core/   pure-C control logic (host-testable)
│   └── test_host/              Unity unit tests
├── z2m/valvectl.mjs             Zigbee2MQTT external converter
├── docs/superpowers/           design spec + implementation plan
├── analysis/                   design review reports (schematic, PCB layout)
└── board.step                  assembled-board 3D export

Safety

⚠️ This board switches 230 V AC mains. All bench work — firmware, sensor reads, triac-drive verification — can be done on USB-C power alone; do not connect mains until the drive channels are verified per firmware/BENCH_CHECKLIST.md. And keep the position convention in mind: the safe idle is mid-travel, not "closed."

Documentation


Personal project by Thierry Kleist. Released under the MIT License.

Parts

123
QtyValueFootprintReferences
1610kResistor_SMD:R_0402_1005MetricR2, R3, R7, R8, R9, R13, R16, R20, R21, R22, R24, R26, R27, R28, R29, R39
7100nFCapacitor_SMD:C_0402_1005MetricC2, C7, C8, C14, C16, C17, C20
6100Resistor_SMD:R_0402_1005MetricR12, R34, R35, R36, R37, R38
5100Resistor_SMD:R_1206_3216MetricR15, R17, R40, RS1, RS2
51770966TerminalBlock_Phoenix:TerminalBlock_Phoenix_PTSM-0,5-3-2.5-V-THR_1x03_P2.50mm_VerticalJ8, J9, J10, J11, J12
54700Resistor_SMD:R_0402_1005MetricRS4, RS5, RS6, RS7, RS8
5PEC3205CSDiode_SMD:D_SOD-323FD8, D9, D10, D11, D12
44.7kResistor_SMD:R_0402_1005MetricR18, R19, R23, R25
4MountingHoleMountingHole:MountingHole_3.2mm_M3_ISO7380H1, H2, H3, H4
310uFCapacitor_SMD:C_0805_2012MetricC4, C5, C6
31990986Kleist2:TerminalBlock_Phoenix_SPT-2,5-3-H-5.0_1x03_P5.00mm_HorizontalJ2, J3, J14
31uFCapacitor_SMD:C_0402_1005MetricC3, C15, C19
34.7nF X1/Y2Capacitor_THT:C_Rect_L13.0mm_W5.0mm_P10.00mm_FKS3_FKP3_MKS4C18, CS1, CS2
2100kResistor_SMD:R_0402_1005MetricR32, R33
2180Resistor_SMD:R_0402_1005MetricRL1, RL2
21kResistor_SMD:R_0402_1005MetricR30, R31
22.2uFCapacitor_SMD:C_1206_3216MetricC10, C11
2360Resistor_SMD:R_0603_1608MetricRG3, RG4
2470Resistor_SMD:R_0402_1005MetricRL3, RL4
25.1kResistor_SMD:R_0402_1005MetricR5, R6
2CPC1035NPackage_SO:SOP-4_3.8x4.1mm_P2.54mmQ6, Q7
2HCPL-354-06AEPackage_SO:SO-4_4.4x3.6mm_P2.54mmU8, U9
2MBR130LSFT1GDiode_SMD:D_SOD-123FD4, D5
2MOC3063S-TA1Kleist:MOC306XS_LTO-LQ3, Q4
2SMF33ADiode_SMD:D_SOD-123FD20, D21
2SMF51CADiode_SMD:D_SOD-123FD18, D19
2Z0103MNPackage_TO_SOT_SMD:SOT-223D2, D3
1100uFCapacitor_SMD:C_1210_3225MetricC1
110nFCapacitor_SMD:C_0402_1005MetricC12
110uHInductor_SMD:L_Taiyo-Yuden_NR-40xxL1
113.3kResistor_SMD:R_0402_1005MetricR11
11990999Kleist2:TerminalBlock_Phoenix_SPT-2,5-4-H-5.0_1x04_P5.00mm_HorizontalJ15
12.2kResistor_SMD:R_1206_3216MetricR14
1249kResistor_SMD:R_0402_1005MetricR10
14.7uFCapacitor_SMD:C_0805_2012MetricC9
146205000000Fuse:Fuse_Littelfuse-NANO2-462F2
182pFCapacitor_SMD:C_0402_1005MetricC13
1A6S-1102-HButton_Switch_SMD:SW_DIP_SPSTx01_Slide_Omron_A6S-110x_W8.9mm_P2.54mmSW3
1B72210S0271K101Varistor:RV_Disc_D12mm_W5.4mm_P7.5mmR1
1BZT52B27Diode_SMD:D_SOD-123FD7
1CSD17313Q2Kleist2:CSD17313Q2Q5
1ESP32-C6-WROOM-1-N4Kleist:MOD28_ESP32-C6-WROOM-1_EXPU5
1IRM-03-5Converter_ACDC:Converter_ACDC_MeanWell_IRM-03-xx_THTU1
1IS31FL3730Package_DFN_QFN:QFN-24-1EP_4x4mm_P0.5mm_EP2.5x2.5mmU7
1KWM-20881AGBKleist2:LED_Matrix_8x8_20mmDS1
1KleistLabs_Logo_8mm_CopperKleist2:KleistLabs_Logo_8mm_CopperG1
1QR_HydroMix_SilkOnDarkKleist2:QR_HydroMix_250um_SilkOnDarkG2
1RB160MM-60TRDiode_SMD:D_SOD-123FD6
1TL9320AF400QGKleist2:SW_SPST_TL9320SW1
1TLV75733PPackage_SON:WSON-6-1EP_2x2mm_P0.65mm_EP1x1.6mm_ThermalViasU2
1TPS61040Package_SON:WSON-6-1EP_2x2mm_P0.65mm_EP1x1.6mm_ThermalViasU6
1USB4145-03-0170-CKleist2:USB_C_Receptacle_GCT_USB4145-03-0170-C_Vertical_SMTJ13
1USBLC6-2SC6Package_TO_SOT_SMD:SOT-23-6U10

Questions

How big is the ValveController PCB?

It measures 94.5 × 99.8 mm and has 4 copper layers, 1.6 mm thick.

What parts does the ValveController use?

123 parts, built around the ESP32-C6-WROOM-1-N4, IRM-03-5, Z0103MN and IS31FL3730-QFLS2-TR. 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 ValveController KiCad files?

From the afewyards/HydroMix repository on GitHub, at the commit this page was made from: the board is pcb/ValveController.kicad_pcb and its schematic pcb/ValveController.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the ValveController 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 layers30 × 40.8 mmDrone fc, the printed circuit board in 3D

    Drone fc

    neilpate/Drone

    A learning project: build a quadcopter from scratch — own hardware, own firmware, no existing flight stack.

    37 partsApache-2.0
  • 2 layers90 × 98.5 mmIO Board, the printed circuit board in 3D

    IO Board

    FREILab/easyVerwaltungHardware

    Hardware und Firmware für alle Geräte im Bezug zu easyVerwaltung

    77 parts2
  • 2 layers65 × 30 mmMicroBars, the printed circuit board in 3D

    MicroBars

    ADDTDR/MicroBarALS317

    Small bragrh display board based on is31fl3730 driver and als317 led display

    28 parts
  • 2 layers89.7 × 67.5 mmEnvOpenSensor, the printed circuit board in 3D

    EnvOpenSensor

    Envious-Data/EnvOpenEnvSensor

    a simple sensor pcb with a display to show some environment conditions

    375 partsGPL-3.0
  • 2 layers39.7 × 14 mmPD24, the printed circuit board in 3D

    PD24

    TheBadZhang/PD24

    一个可以通过PD诱骗BOOST升压到24V(通过修改反馈电阻可调)输出的工具

    34 parts
  • 4 layers50 × 42 mmReceiver, the printed circuit board in 3D

    Receiver

    JMET04/aicad-agent

    Deterministic CAD/EDA agent plugin for 2D drawings, AutoCAD, SolidWorks, KiCad, review gates and auditable delivery.

    46 parts1MIT
  • 2 layers110 × 170 mmAnalog board, the printed circuit board in 3D

    Analog board

    Automation-group/FatigueCantileverBend_PIU-5

    74 parts
  • 8 layers90 × 120.4 mmArtix dc scm, the printed circuit board in 3D

    Artix dc scm

    antmicro/artix-dc-scm

    Experimental Xilinx Artix-7 driven Data Center Security Communication Module

    546 parts72Apache-2.0