Phase Template: tank-iterative-dose¶
Iteratively dose reagent and re-read pH until the target is reached
(or max_doses is exhausted). Use this phase when a single-pass pH
correction is not reliable: sharp titration curves, uncertain
starting pH, or when a small steady-state offset matters. Each
iteration doses for dose_time, waits mix_time for mixing, then
re-reads the pH sensor. Terminates successfully when
|pH − target| <= ph_tolerance.
This is the feedback-controlled counterpart to tank-ph-adjust.
Where to find it¶
System endpoint → Equipment Library → Phases → select tank-iterative-dose.
graph TD
Start([initial]) --> INIT[init<br/>dose_count := 0]
INIT --> SA[start_agitator]
SA --> RP[read_ph]
RP --> EV{evaluate<br/>ph_ok? dose_limit?}
EV -->|"ph_ok OR dose_limit<br/>priority 0"| STOPA[stop_agitator]
EV -->|"NOT ph_ok AND<br/>NOT dose_limit<br/>priority 1"| DOSE[dose<br/>++dose_count]
DOSE -->|"dose.T >= dose_time"| CD[close_dose]
CD --> MS[mix_settle]
MS -.->|"mix_settle.T >= mix_time<br/>(loop back)"| RP
STOPA --> Done([complete])
See Phases for the diagram conventions. The dashed back-edge is the iteration loop.
What you see when it runs¶
| Element | Meaning |
|---|---|
| Active step | Cycles through read_ph → evaluate → dose → close_dose → mix_settle and back each iteration |
| Shared variables | dose_count (incremented each dose), current_ph (captured in read_ph) |
| Parameters | target_ph, ph_tolerance, dose_time, mix_time, max_doses, agitator_speed |
HMI screenshot pending
An annotated capture of a running tank-iterative-dose phase mid-iteration will be added here.
Parameters¶
| Parameter | Type | Unit | Range | Default | Required |
|---|---|---|---|---|---|
target_ph |
REAL | pH | 2.0-12.0 | — | yes |
ph_tolerance |
REAL | pH | 0.1-2.0 | 0.3 |
no |
dose_time |
TIME | — | 3s-1m |
— | yes |
mix_time |
TIME | — | 5s-1m |
— | yes |
max_doses |
INT | — | 1-20 | — | yes |
agitator_speed |
REAL | % | 20-100 | 60 |
no |
TIME parameters take duration strings ("45s", "1m30s", "5m"),
not bare numbers.
Required control modules¶
| Role | Module type | Description |
|---|---|---|
ph_sensor |
analog-sensor | Tank pH measurement |
wfi_valve |
discrete-valve | Reagent addition valve (on/off) |
agitator |
analog-control | Tank agitator for mixing between doses |
Capability: mixing.
How it works¶
Each scan the SFC engine:
initzeroesdose_count.start_agitatorwritesagitator_speedto the agitator.read_phcaptures the current pH intocurrent_ph.evaluateis the loop decision step with two priority-ordered transitions:priority 0(exit) if|current_ph - target_ph| <= ph_toleranceORdose_count >= max_dosespriority 1(continue) if the pH is outside tolerance AND the dose counter has headroom
- On the continue branch,
doseopenswfi_valve, holds fordose_time, and incrementsdose_count.close_dosecloses the valve.mix_settleholds formix_time, then loops back toread_phvia the dashed back-edge. - On the exit branch,
stop_agitatorzeroes the agitator before the phase completes.
This is an iterative phase with safety counter. The max_doses
counter is the primary safeguard against a sensor fault or an
unreachable target looping forever. Verify it is set in the recipe
formula. Pair
with hardware-limit alarms on the dosed PV and a timeoutSeconds
backstop. See
Phases § Iterative phase with safety counter.
Used in recipes¶
Try it¶
- HMI endpoint → Batch Execution → + New →
sim-iterative-dose-m1→ Start - Click into the phase detail and watch the active step cycle
through the loop:
read_ph→evaluate→dose→close_dose→mix_settle→ back toread_ph - Open Data endpoint → Trends on
ph_sensor.PVto see the staircase as each dose pushes pH closer to target - Watch
dose_countincrement each iteration on the phase detail - Verify the phase exits via the
priority 0branch once the pH is withinph_tolerance