Skip to content

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 endpointEquipment LibraryPhases → 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 &gt;= dose_time"| CD[close_dose]
    CD --> MS[mix_settle]
    MS -.->|"mix_settle.T &gt;= 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_phevaluatedoseclose_dosemix_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:

  1. init zeroes dose_count.
  2. start_agitator writes agitator_speed to the agitator.
  3. read_ph captures the current pH into current_ph.
  4. evaluate is the loop decision step with two priority-ordered transitions:
    • priority 0 (exit) if |current_ph - target_ph| <= ph_tolerance OR dose_count >= max_doses
    • priority 1 (continue) if the pH is outside tolerance AND the dose counter has headroom
  5. On the continue branch, dose opens wfi_valve, holds for dose_time, and increments dose_count. close_dose closes the valve. mix_settle holds for mix_time, then loops back to read_ph via the dashed back-edge.
  6. On the exit branch, stop_agitator zeroes 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

  1. HMI endpointBatch Execution+ Newsim-iterative-dose-m1Start
  2. Click into the phase detail and watch the active step cycle through the loop: read_phevaluatedoseclose_dosemix_settle → back to read_ph
  3. Open Data endpointTrends on ph_sensor.PV to see the staircase as each dose pushes pH closer to target
  4. Watch dose_count increment each iteration on the phase detail
  5. Verify the phase exits via the priority 0 branch once the pH is within ph_tolerance