Open-source differential solar thermal controller. ESP32-S3 + ATmega32U4, 4× PT1000 sensing, TRIAC pump control, relay valves, W5500 Ethernet, RS-485, ESPHome. Designed for dual-tank hot water systems.
Loading README and project media…
A fully open-source, ESP32-S3 based differential solar thermal controller with dual-tank switching, PT1000 sensing, TRIAC pump control, and Ethernet/MQTT connectivity.
DiSoCon2 is a modular, open-hardware differential solar thermal controller designed to intelligently manage a domestic solar hot water system with multiple storage tanks. It replaces proprietary "dumb" controllers with a fully integrated, home-automation-aware solution built around the ESP32-S3 and ATmega32U4.
The system reads four PT1000 platinum resistance sensors (solar collector, primary tank, secondary tank, return line), computes temperature differentials, and drives pumps and 3-way valves accordingly — all while reporting live data to Home Assistant via MQTT or Ethernet.
V2 integrates the control logic and the analog temperature measurement circuitry onto a single board, eliminating the inter-board wiring of V1 and improving signal integrity.
| Feature | Detail |
|---|---|
| Temperature sensing | 4× PT1000 via precision OPV front-end (MCP6004, ±0.1% resistors) + DS18B20 OneWire bus |
| Pump control | 2× TRIAC outputs (BTA41-600B + MOC3021) for 230V AC pumps, with zero-cross synchronization |
| Valve control | 2× relay outputs (SRD-05VDC) for 3-way motorized valves, optoisolated via PC817C |
| Connectivity | W5500 Ethernet (SPI) + ESP32-S3 onboard WiFi/BLE |
| Field bus | RS-485 half-duplex via MAX13487E (auto-direction), with 120Ω termination and SMBJ6.8A TVS protection |
| User interface | 20×4 I2C LCD + 5-button keypad (UP / DOWN / LEFT / RIGHT / OK) read via ADS1115 |
| Power supply | HLK-PM01 mains-to-5V module + BL1117-33CX LDO for 3.3V logic; USB-C 5V input as alternative |
| Safety | Anti-freeze logic, overheating protection, fuse-protected AC input, snubber networks on all TRIAC outputs |
| Firmware | ESPHome YAML on ESP32-S3; ATmega32U4 Arduino firmware for analog front-end |
The project is split into two physically separate boards that connect via a 10-pin IDC ribbon:
┌─────────────────────────────────────────────────┐
│ CONTROL BOARD (Full Board V2) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ ATmega │ │ ESP32-S3 │ │ W5500 │ │
│ │ 32U4 │◄─► (main │ │ Ethernet │ │
│ │ PT1000 │ │ ESPHome)│ │ Controller │ │
│ │ front-end│ └────┬─────┘ └───────────────┘ │
│ └──────────┘ │ │
│ ┌──────────┐ ┌────┴─────┐ ┌───────────────┐ │
│ │ MCP6004 │ │ MAX13487 │ │ ADS1115 │ │
│ │ 4ch OPV │ │ RS-485 │ │ Button ADC │ │
│ └──────────┘ └──────────┘ └───────────────┘ │
└─────────────────────┬───────────────────────────┘
│ 10-pin ribbon (CN3)
┌─────────────────────┴───────────────────────────┐
│ POWER BOARD (Power Board V2) │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌───────────┐ │
│ │ HLK-PM01 │ │ 2× BTA41 │ │ 2× SRD │ │
│ │ AC→5V │ │ TRIAC pumps │ │ relays │ │
│ └──────────┘ │ + MOC3021 │ │ valves │ │
│ │ + snubber │ └───────────┘ │
│ ┌──────────┐ └──────────────┘ │
│ │ ZeroCross│ MB10S bridge + LTV-817C │
│ │ detector │ → ZEROCROSS signal to ESP32 │
│ └──────────┘ │
└─────────────────────────────────────────────────┘
TEMP-TX / TEMP-RX). Has its own USB-C (USB4) for independent firmware upload and an ICSP header (H9) for UPDI/ISP programming.SPI1_MOSI/MISO/SCK/CS). Reset line (RST_NET) and interrupt line (INT_NET) connected to dedicated ESP32-S3 GPIOs.SN74LVC1G125 (U4) level shifter on the RO output to convert from 5V to 3.3V logic for ESP32-S3 RX.PD2(RXD1) → TEMP-RX on ESP32; PD3(TXD1) → TEMP-TX.OPV_ENB line (PC7 / PE2) allows the ATmega to power-gate the entire OPV section.TEMP_ENB1–4) built from 4.7kΩ / 4.7kΩ resistor pairs allow the ATmega to multiplex or disable channels individually.OPV_ENB.Relay section (Valve 1 & Valve 2):
VALVOLA1/2 signals, 3.3V-fed via 1kΩ) and the relay driver side (5VUSB referenced). Output resistor 1kΩ.TRIAC circuits (Pump 1 & Pump 2) — identical topology:
Zero-cross detection:
ZEROCROSS signal — a pulse train at twice the mains frequency (100Hz for 50Hz mains) that is routed to the ESP32-S3 for phase-synchronised TRIAC firing.| Pin | Signal | Direction | Description |
|---|---|---|---|
| 1 | MOTORE2 | PB → CB | Pump 2 control signal |
| 2 | MOTORE1 | PB → CB | Pump 1 control signal |
| 3 | ZEROCROSS | PB → CB | Zero-cross detection pulse |
| 4 | 5V | PB → CB | 5V power from HLK-PM01 |
| 5 | 3V3 | CB → PB | 3.3V logic reference |
| 6 | 5VUSB | CB → PB | USB 5V (relay coil supply) |
| 7 | — | — | (reserved/GND) |
| 8 | VALVOLA1 | CB → PB | Valve 1 control |
| 9 | VALVOLA2 | CB → PB | Valve 2 control |
| 10 | GND | — | Common ground |
CB = Control Board, PB = Power Board
Each PT1000 connects to a 3-pin screw terminal on the Control Board (CN6–CN9). The sensor is wired in a 2-wire configuration to the OPV input. For best accuracy, use matched cable runs and consider the per-channel gain/offset calibration available in the ATmega firmware.
| Connector | Sensor Location | Signal |
|---|---|---|
| CN9 | Solar collector (panel) | IN+1 → TEMP_OUT1 |
| CN8 | Primary storage tank | IN+2 → TEMP_OUT2 |
| CN6 | Return / secondary circuit | IN+3 → TEMP_OUT3 |
| CN7 | Secondary tank / boiler outlet | IN+4 → TEMP_OUT4 |
The ESP32-S3 implements the following logic layers in ESPHome:
MOTORE1 (solar pump) when ΔT exceeds a configurable threshold; deactivates with hysteresis.VALVOLA1 / VALVOLA2 to direct hot fluid to the tank with the lowest temperature, maximising energy storage.MOTORE2 manages heat exchange with the gas boiler loop based on secondary tank differentials.ZEROCROSS interrupt for reduced EMI and inrush.DiSoCon/
├── 3D Model/ # 3D renders and model files
├── Hardware/ # Schematics, PCB Gerbers, EasyEDA sources
│ ├── SCH_Full_Board_V2.0.pdf # Control board schematic (6 pages)
│ └── SCH_Power_Board_V2.0.pdf # Power board schematic (2 pages)
├── Images/ # Board renders, photos, diagrams
├── Software/ # Firmware source code
│ ├── ESPHome YAML # ESPHome configuration for ESP32-S3
│ └── ATmega32U4/ # Arduino sketch for PT1000 co-processor
├── LICENSE
└── README.md
# Clone the repo
git clone https://github.com/carletz/DiSoCon
# Flash ESPHome (first time via USB)
esphome run Software/main.yaml
# Subsequent updates via OTA (Ethernet or WiFi)
Add the device to ESPHome dashboard. All sensors, pumps, and valve states are automatically exposed as Home Assistant entities. MQTT topics follow ESPHome conventions.
This project involves mains voltage (230V AC). Working with mains voltage is potentially lethal.
This project is provided for educational and inspiration purposes only. The author(s) accept no responsibility for damage to equipment, persons, or property arising from the use of this design.
Any real-world installation must be performed by a qualified electrician in compliance with local electrical codes and safety regulations (e.g. IEC 60364 in Europe).
By using this material you acknowledge it is offered as-is, without warranty of any kind.
| Version | Date | Notes |
|---|---|---|
| V2.0 | March 2026 | Integrated control + analog measurement on single board; ATmega32U4 co-processor; EasyEDA redesign |
| V1.0 | April 2025 | Separate controller and temperature measurement boards |
carletz — @carletz on GitHub
This work — hardware schematics, PCB designs, firmware, and documentation — is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License (CC BY-NC-SA 4.0).
You are free to:
Under the following terms:
See LICENSE for the full license text.