-
Notifications
You must be signed in to change notification settings - Fork 38
Aquapath
The Aquapath V1 keeps two independent water reservoirs (left and right) at a target temperature, each with its own pump, heating element, fan cooler and AS006 flow/temperature probe.
| Machine ID | 9 |
| Schema | aquapath_v1.yaml |
| Code | aquapath/ |
In the tables below, <side> stands for left or right: every reservoir setting exists once per side.
| Role | Terminal | Purpose |
|---|---|---|
| 0 | EK1100 | Bus coupler |
| 1 | EL2008 | Pump, heating and cooling relays (DO1–4 left, DO5–8 right; DO3 and DO7 unused) |
| 2 | EL4002 | Fan speed, 0–10 V (AO1 left, AO2 right) |
| 3 | EL3024 | AS006 flow and temperature probes (AI1–2 left, AI3–4 right) |
The AS006 maps 4–20 mA to 0–15 l/min and −25–125 °C. Roles are assigned in Identification.
Each reservoir runs the same controller. The rule it exists to enforce: never heat without proven flow, and keep the water moving until the heat has been carried away.
flowchart LR
subgraph TEMP["Temperature"]
TS["AS006 temperature<br/>EL3024"]:::hardware
D["<a href='https://github.com/qitechgmbh/control/blob/jse-control-v2/qitech_control/src/machines/aquapath/controller/mod.rs'>Demand</a><br/>target vs. actual"]:::control
H["<a href='https://github.com/qitechgmbh/control/blob/jse-control-v2/qitech_control/src/machines/aquapath/controller/heater.rs'>Heater</a><br/><a href='https://github.com/qitechgmbh/control/blob/jse-control-v2/qitech_control_core/src/controllers/pid.rs'>PID</a> duty, 12 s PWM<br/>only with proven flow"]:::control
C["<a href='https://github.com/qitechgmbh/control/blob/jse-control-v2/qitech_control/src/machines/aquapath/controller/cooling.rs'>Cooling</a><br/>fan ramp: Low, Ramp, Max<br/>only with flow"]:::control
HR["Heating relay EL2008"]:::hardware
CR["Cooling relay EL2008<br/>fan speed EL4002"]:::hardware
TS --> D
D -- "too cold" --> H
D -- "too warm" --> C
H --> HR
C --> CR
end
subgraph FLOW["Flow"]
FS["AS006 flow<br/>EL3024"]:::hardware
P["<a href='https://github.com/qitechgmbh/control/blob/jse-control-v2/qitech_control/src/machines/aquapath/controller/pump.rs'>Pump controller</a><br/>priming, low-flow trip,<br/>after-run"]:::control
PR["Pump relay EL2008"]:::hardware
FS --> P --> PR
end
FLOW -- "flow state" --> TEMP
classDef frontend fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
classDef control fill:#dcfce7,stroke:#15803d,color:#14532d
classDef framework fill:#fef3c7,stroke:#b45309,color:#78350f
classDef lib fill:#ede9fe,stroke:#6d28d9,color:#4c1d95
classDef hardware fill:#f1f5f9,stroke:#475569,color:#0f172a
Defaults marked fixed are constants in controller/config.rs and can't be changed at runtime. The other parameters are config properties. Config writes outside the listed range are rejected; the controller additionally clamps some values, as noted.
Controller (controller/mod.rs) computes the error target − actual and picks the demand:
- Heat if the error is above the heating tolerance,
- Cool if the water is warmer than target plus the cooling tolerance,
- Hold otherwise (deadband).
The minimum settable target is the ambient calibration, limited to 10–80 °C: the loop can't cool below ambient. Changing the ambient calibration raises any target below the new minimum.
| Parameter | Unit | Default | Description |
|---|---|---|---|
Target temperature<side>_target_temperature
|
°C | 25 | Control tab, Set Target Temperature. Config accepts 0–80; the controller clamps the value to the minimum settable target…80 °C. |
Ambient temperature calibrationambient_temperature_calibration
|
°C | 22 | Config tab, Ambient Calibration. Shared by both sides, clamped to 10–80 °C (the UI offers 10–40). Use Current Sensor Temp takes the lower of the two reservoir temperatures and is only enabled below 30 °C. |
Heating tolerance<side>_tolerance_config.heating
|
°C | 0.4 | Heat when the water is more than this below target. Clamped to 0–10. |
Cooling tolerance<side>_tolerance_config.cooling
|
°C | 0.8 | Cool when the water is more than this above target. Clamped to 0–10. |
| Minimum temperature | °C | 10 | Fixed. Below it, running cooling is cut. Also the lower limit of the settable target. |
| Maximum temperature | °C | 80 | Fixed. Above it, a running heater is cut. Also the upper limit of the target. |
Writing a target temperature, a tolerance or a PID gain resets that side's PID state and PWM window and queues a Thermal Control Reset notice.
HeaterController (controller/heater.rs) drives the heating relay:
- The PID (
pid.rs, plainupdatewithout anti-windup) turns the error into a duty cycle, clamped to 0–1. - The heater is on for
duty × 12 sat the start of each 12 s PWM window. - If the error is 4 °C or more, the heater skips the duty cycle and runs continuously.
- In the deadband the heater is switched off and the PID is reset, so the integral can't wind up.
- The heater only runs with proven flow (see Pump); losing it cuts the heater in the same cycle.
- Power is reported as 700 W while the relay is closed, 0 W otherwise. The energy is integrated in Wh (
<side>_total_energy); the Control tab shows the sum of both sides in kWh. Both reset when the backend restarts.
| Parameter | Unit | Default | Description |
|---|---|---|---|
Kp<side>_pid_config.kp
|
– | 0.16 | Proportional gain (duty per °C of error). Clamped to 0–5. |
Ki<side>_pid_config.ki
|
– | 0.02 | Integral gain. Clamped to 0–5. |
Kd<side>_pid_config.kd
|
– | 0.0 | Derivative gain. Clamped to 0–5. |
| PWM period | s | 12 | Fixed. Length of the duty-cycle window. |
| Full-power error | °C | 4 | Fixed. From this error on, the heater runs continuously. |
| Heating element power | W | 700 | Fixed. Nominal power used for the power and energy values; not measured. |
The Reset to Default buttons on the Config tab write 0.16 / 0.02 / 0.0 for the PID and 0.4 / 0.8 for the tolerances.
CoolingController (controller/cooling.rs) switches the cooling relay and sets the fan speed. It only runs when the demand is Cool, the machine is in Auto and flow is present (at least 0.2 l/min with the pump on). The fan is only driven once the relay has really closed; the relay dwell can delay that.
The fan speed follows how far the water is above target (actual − target):
| Offset | Mode | Fan speed |
|---|---|---|
| below 2 °C | Low | Linear from the minimum fan speed (20) at 0.8 °C to 60 % of max at 2 °C |
| 2–4 °C | Ramp | Linear from 60 % to 100 % of max |
| 4 °C or more | Max | 100 % of max |
When cooling stops, the fan is set to 0 and the mode becomes empty (null).
| Parameter | Unit | Default | Description |
|---|---|---|---|
Max revolution speed<side>_fan_max_revolutions
|
% | 100 | Config tab. Upper limit of the fan ramp, 0–100 (100 = 10 V at the EL4002). The Control tab shows the fan speed as a percentage of this value. |
| Ramp start | °C | 0.8 | Fixed. Offset at which the Low segment starts from the minimum speed. It doesn't follow the configurable cooling tolerance. |
| Near band | °C | 2 | Fixed. End of the Low segment. |
| Full band | °C | 4 | Fixed. From here on, the fan runs at max. |
| Minimum fan speed | % | 20 | Fixed. Start of the Low segment (limited to the max). |
PumpController (controller/pump.rs) owns the pump relay, the flow probe and the flow timers:
-
Request: the Control tab's Pump switch sends
pump.start_<side>_pumporpump.stop_<side>_pump. A change of the request resets the PID and PWM window. - Permission: the relay only closes when the pump is allowed. Entering Auto grants the permission; nothing withdraws it again.
- Priming: the low-flow trip is armed 15 s after the pump relay closes.
- Low-flow trip: if the flow then stays below 0.2 l/min for 5 s, the pump request is cleared (the switch falls back to Off) and a Pump Turned Off notice is queued.
-
Flow proven: once the flow is at least 0.2 l/min with the pump on, a timer starts. After the settle duration the flow counts as proven and the heater may run. Until then
<side>_heating_startup_wait_activeis true while the loop wants heat, and the Control tab shows Thermal Delay with the remaining time. -
After-run: if the pump request is withdrawn (pump Off, or Standby) while the heater is on or was on within the settle duration, the pump keeps running for the settle duration (
<side>_pump_cooldown_active,<side>_pump_cooldown_remaining).
| Parameter | Unit | Default | Description |
|---|---|---|---|
Thermal safety delay<side>_thermal_flow_settle_duration
|
s | 10 | Config tab, Thermal Safety Delay. How long flow must be present before heating, and how long the pump runs on after heating. 0–30. Only applied when written in Standby. The controller starts with 10 s; the config property itself defaults to 0 until it's written. The Config tab shows the value in effect. |
Pump cooldown min temperature<side>_pump_cooldown_min_temperature
|
°C | 45 | Config tab. 10–80, only applied when written in Standby. The controller starts with 45 °C; the config property defaults to 32. The value is stored and published, but the control loop doesn't evaluate it. |
| Minimum flow for thermal interlocks | l/min | 0.2 | Fixed. Less flow counts as no flow. |
| Pump startup grace period | s | 15 | Fixed. Priming time before the low-flow trip is armed. |
| Low-flow grace period | s | 5 | Fixed. How long the flow may stay too low before the pump is stopped. |
controller/io.rs wraps the terminals:
-
Relay: one EL2008 output that remembers its last command. The pump uses a plain relay. -
DwellRelay: the heating and cooling relays. After a switch, the relay holds its state for a minimum time, so the contacts don't chatter. Safety cut-offs (flow interlock, hard limits, Standby) useforce_off, which ignores the dwell. -
FanOutput: writes the fan value ÷ 10 to the EL4002. -
FlowSensorandTemperatureSensor: one AS006 channel each on the EL3024; errors read as 0.
| Parameter | Unit | Default | Description |
|---|---|---|---|
| Relay minimum on time | s | 5 | Fixed. A closed heating or cooling relay stays closed at least this long (except for safety cut-offs). |
| Relay minimum off time | s | 5 | Fixed. An open relay stays open at least this long. |
Timer (controller/timing.rs) is a restartable one-shot timer. The durations are passed in on every call, so settings changed at runtime apply immediately.
| Timer | Owner | Starts | Used for |
|---|---|---|---|
running_since |
Pump | Pump relay closes | 15 s priming before the low-flow trip |
low_flow_since |
Pump | Flow drops below 0.2 l/min after priming | 5 s low-flow grace period |
flow_valid_since |
Pump | Flow present with the pump on | Flow proven after the settle duration |
cooldown |
Pump | Request withdrawn while the heater is recently active | After-run for the settle duration |
last_active |
Heater | Every cycle the heater is on | "Recently active" check for the after-run |
QiTech Control · GitHub · Framework wiki · Lib wiki · Report a docs problem
Getting Started
Guides
Machines
Developers
Related