HVAC_getting_started_guide.md

August 23, 2026 · View on GitHub

HVAC Getting Started

General

This guide aims to get you acquainted with the principles applied in the HVAC function blocks and how they are designed to work together. An implementation of scenario C can be found in the project under program PRG_HVAC.

Scenario A: Floor heating

This scenario assumes a single floor heating system with one thermostat and one pump. To control this system the following logical components are required:

  • a thermostat that measures the temperature in the room and allows setting the desired temperature.
  • a pump that controls the flow of water through the floor heating circuit.
  • a heat source that produces warm water when the pump is on.

Scenario B: 2 Floor heating circuits

Building upon scenario A, consider a scenario where there is not one floor heating circuit but two. In a real life situation this could for example be the floor heating on the first floor and the floor heating on the second floor, each with its own thermostat.

Scenario C: 1 Floor heating circuit and 2 radiators on the same collector

Not all buildings leverage floor heating in every single room. In many setups radiators are used to heat multiple rooms in a building. This scenario covers such an example and assumes a thermostat in every room heated by a radiator:


:information_source: Due to the lack of PID logic in the function blocks the target temperature will always overshoot. This is only the case for radiators and not floor heating as they generate heat much faster.


Getting the timings right

Three timings shape the chain, and they are set at three different declaration sites. Two of them interact, which is easy to miss because each one looks self-contained where it is written:

TimingWhereWhat it does
ValveCycleTimeFB_HVAC_COLLECTOR_MQTT FB_initHolds the pump off after heat is first requested, so a valve can open before there is flow.
MIN_ONTIME / MIN_OFFTIMEFB_HVAC_PUMP_MQTT FB_initMinimum run and minimum pause, so the pump cannot short-cycle.
MIN_ONTIME / MIN_OFFTIMEFB_HVAC_BURNER_MQTT FB_initThe same, for the heat source.

The pump's minimum on-time outlives the demand that started it. Once the pump is running it keeps running until MIN_ONTIME has elapsed, however quickly the thermostat is satisfied. So on a collector, whatever closes the valves has to wait for the pump rather than for the thermostat — otherwise the pump spends the rest of its minimum on-time pushing against a manifold that is closing.

The approach is to wire it, not to tune it:

fbPump2Collector.PUMP_MIN_ONTIME_ACTIVE := fbPump2.MIN_ONTIME_ACTIVE;

Scenario A has no valve at all — the thermostat drives the pump directly — so it is not exposed to this. Scenario B and Scenario C are.

:bulb: On real hardware, a differential bypass on the manifold is the belt to this braces: it gives the pump a path no matter what the control logic believes.