// Process Control · Food & Dairy

The evaporator that cooks for days and cleans itself in hours.

A five-effect dairy evaporator concentrates product around the clock: under vacuum, against steam, through a hundred automated valves and two dozen pumps. And when the run ends, it washes itself in place: caustic, acid, sanitizer, rinses, sprayballs, all sequenced automatically. We've engineered these systems down to the word level, including migrating this one from a legacy PLC-5 to ControlLogix and PlantPAx, where the entire sequence lives as data you can read: one table, one row per step.

MODE STEP CHUNK PINS DEVICES
// The system01

One machine, two jobs: make product, then prove it's clean.

CIP (clean-in-place) means the plant is washed without taking a single pipe apart. A four-tank CIP skid supplies the evaporator: rinse water, recovered rinse, caustic, and acid, dosed to strength, heated to temperature, pushed through every product path, and verified by conductivity before a drop goes to drain.

RINSE LT314 RECOVERY LT313 CAUSTIC LT312 ACID LT311 // CIP skid: 4 tanks, level + conductivity + temperature on each circuit DP72 caustic dose DP71 acid dose DP73 sanitizer dose supply header: one valve pin per tank per step PP PP210 · VFD speed = chunk word 58 HEAT EX TCV530 plant steam temp SP = word 8 EVAPORATOR 5 effects · TVR · vacuum E1 E2 E3 E4 E5 sprayballs: their own fwd/rev sub-sequence CT522 · return conductivity is it still caustic, or just water? FV135 divert recover chemical to drain: only once conductivity says spent
// the CIP circuit: tanks → VFD supply pump → steam heat exchanger → evaporator → conductivity-verified return
field devices ~200 automated valves ~100 pumps ~25 PID loops 12+ I/O racks 4 over EtherNet/IP platform ControlLogix · PlantPAx migrated from PLC-5
// The sequencing engine02

The whole sequence is data. The ladder just plays it.

Every step of every mode owns a 64-word block of DINTs: a chunk. One pointer move copies the active step's chunk into evaluation, and from there the decode is mechanical: bits become valve and pump commands, whole words become PID setpoints and VFD velocity references. To change the process, you change the table; the ladder never moves.

SeqData_ModeCIP the pinning chart, in memory step 11 · 64 words step 12 · 64 words step 13 · 64 words one flat DINT array per mode COP · 64 DINTs ptr = step × 64 SeqData_Active the step under evaluation words 0–5 192 peg bits word 6 · step time words 7–55 setpoints & thresholds words 56–61 VFD velocity refs XIC(word.bit) VALVES & PUMPS ~100 FV · ~25 PP → PCmd_Open/Start TON preset STEP TIMER + advance conditions MOV word PID LOOPS 12+ PIDE → PSet_SP MOV word VFD DRIVES PSet_SpeedRef → pump speed // one COP instruction per scan decides everything the plant is doing right now
// mode → step → pointer → chunk → devices · the decode never changes; only the data does

A chunk per step

Each step is 64 DINTs: six bit-packed "peg words," a step-time preset, and fifty-plus engineering values. The sequencer computes a pointer (step number times block length, clamped to the array) and copies that block into SeqData_Active. The active chunk is the state of the plant.

COP(Mode[ptr], Active[0], 64)

Bits become valves

Peg words 0–5 carry 192 pins, each hard-mapped to one output: CIP skid valves, tank feeds, divert valves, dosing pumps, vacuum and discharge pumps, even PID-enable and peer-PLC handshake bits. The decode is a rack of one-bit rungs: examine the pin, command the device. Nothing else touches an output.

XIC(Active[0].21) → FV121.PCmd_Open

Words become setpoints

Whole DINTs in the same chunk are engineering values: supply temperature for the steam heat exchanger, tank fill levels with deadbands, pressure and flow setpoints for a dozen PIDE loops, and velocity setpoints written straight to the VFDs, like word 58 driving the CIP supply pump's speed reference every step.

MOV(Active[58], PP210.PSet_SpeedRef)

The chart is the program

The chunks are authored in the pinning chart: a workbook with one sheet per mode, one row per step, one column per pin and setpoint. A macro downloads the arrays to the ControlLogix over RSLinx. Process engineers tune the sequence; nobody edits ladder to do it.

Excel → download → ControlLogix
// the engine, in the actual instructions, recovered from the running program CPT(Seq_Ptr, Step_Num * Blk_Len) // pin the active step (clamped to the array) COP(SeqData_ModeCIP[Seq_Ptr], SeqData_Active[0], 64) COP(SeqDesc_ModeCIP[Step_Num], SeqDesc_Active, 1) // live step text for the HMI banner XIC(SeqData_Active[0].4) OTE(EVP_FV164.PCmd_Open) // a bit is a valve… XIC(SeqData_Active[2].11) OTE(EVP_PP243.PCmd_Start) // …or a pump MOV(SeqData_Active[58], EVP_PP210.PSet_SpeedRef) // a word is a VFD velocity setpoint… MOV(SeqData_Active[35], EVP_PC418_PIDE.PSet_SP) // …or a PID setpoint LEQ(EVP_CT521_AIn.Val, SeqData_Active[44]) // …or the proof required to advance: XIC(SeqData_Active_Tmr.DN) MOV(43, Step_Num) // timer done AND conductivity at target → next step
// Modes & steps03

Nine modes take it from cold steel to clean steel.

The operator picks a product and presses start. Everything after that (pulling vacuum, establishing water recirculation, bringing on steam, production, and the wash that follows) is the same engine walking different tables.

// SysMode: one active mode, each with its own step table 01 PRODUCT skim / permeate 02 VACUUM 3 vac pumps 03 WATER recirc · seal 04 HEAT steam · ramp 05 PRODUCTION days at a time 06 END push out 07 CIP skim · permeate 08 SD secure 09 EMERGENCY SD overrides from anywhere: its own two-step table, everything to a safe state
// modes 01–08 walk forward on proof; mode 09 preempts all of them
// Inside mode 07 · the wash04

Fifty-plus steps of chemistry, verified as it runs.

The skim CIP recipe, straight from the running system. Timed steps run their clock; quality-gated steps also wait for proof (a conductivity target hit, a tank level made, a flow confirmed) before the engine pins the next chunk.

02–03Check chemical makeup, fill rinse & recovery tankscaustic and acid tanks dosed to conductivity targets before anything movesgate: makeup OK
05Pre-rinse with reclaimed waterrecovered rinse from the last wash does the dirty first pass; fresh water stays in the tank90 s + level
08–14Caustic pre-wash, recirculate, rinse to drainload step holds for conditions · 720 s recirculation through every product path · sprayball sub-sequence720 s + sprays
22–30Caustic main wash → recovery flush360 s wash, then chemical recovered back to its tank until return conductivity drops to the reclaim targetgate: CT ≤ target
33–38Acid wash → recovery flushacid recirculation with sprays, recovered the same way, held until return conductivity reaches the reclaim target360 s + gate
40–42Rinse to drain with sprays, water recirculationramped setpoints re-establish the water loop while sprays finish the vessel interiortimed
44–46Dose, recirculate, and rinse sanitizer600 s sanitizer recirculation with sprays, then rinsed to drain600 s
48End CIPsystem message, totals to the historian, back to mode selection: clean and provabledone
// mode 07B runs the same engine with the acid-first permeate recipe: a different table, the same ladder

Steps advance on proof

Every step carries its own advance criteria in the chunk: a timer preset in word 6, plus thresholds like "return conductivity at or below the reclaim target" in words 43–44. Debounce timers keep a splash of rinse water from faking a clean signal. Steps that can't prove themselves don't pass.

Sub-sequences overlay the main one

Sprayball forward/reverse and chemical dosing run as their own little step engines with their own chunk arrays. Their active chunks are OR-ed bitwise with the main chunk before the device rungs, so a dosing overlay can hold a feed valve open while the main sequence keeps walking, and the HMI shows both banners at once.

Pause without losing your place

A paused system freezes step timers and advancement while every device holds its pinned state. Because the state is the chunk, pausing is trivial and resuming is exact. Branch steps jump the step number directly, so recovery paths and re-washes reuse the same table rows.

// The pinning chart05

A complex sequence you can put your finger on.

One workbook, one sheet per mode, one row per step, one column per pin. Reading across a row tells you exactly what the plant is doing in that step; reading down a column tells you the life story of one valve through the whole wash. That's the entire engineering interface to a 50-plus-step sequence.

StepDescriptionPeg W0Peg W1Peg W2Time sSupply °FLvl SP %VFD Hz
05Pre-Rinse Started · Reclaimed Water901605045.0
09Caustic Load Step · Pre-Wash316030.0
12Recirculating Caustic (Pre-Wash)72052.5
15Rinse to Drain Reclaim Water4801605045.0
26Caustic Wash36052.5
30Spray Subsequence on Caustic048.0
46Recirculate Sanitizer with Spray60042.0
// tap any peg word value to decode its 32 output bits: e.g. step 12's word 1 = 270401 = bits 0·6·13·18 → FV188 second-effect steam · FV246 discharge divert · FV259 condensate divert · FV135 CIP return divert · every value decodes to named hardware

Three details make this chart more than documentation. It downloads itself: a macro writes the arrays straight into the ControlLogix, so the sheet and the PLC can never quietly disagree. It carries its own history: every row keeps the reference pin from the original PLC-5 program, so the migration could be verified bit-for-bit against two decades of proven sequence behavior. And it's the single source of truth: commissioning tweaks, new products, changed chemistry: each one is a revision-numbered row edit in the chart, with the ladder untouched.

// I/O, drives & the operator06

Under the sequence: four racks, two networks, and a faceplate for everything.

The engine is only as good as the iron underneath it, and the picture the operator gets of it. Both were rebuilt on standards: distributed I/O over EtherNet/IP and the full PlantPAx object library from device to screen.

Distributed I/O

A local ControlLogix chassis plus three remote racks (1756 I/O at the evaporator and CIP skid, FLEX I/O at the far end), all over EtherNet/IP, with per-module comms watchdogs feeding the diagnostics program. Roughly two dozen I/O modules serve ~200 field devices: dozens of analog channels and hundreds of discrete points.

1756 · 1794 FLEX · EtherNet/IP

Drives & peer PLCs

VFDs take their velocity setpoints from the chunk; an SMC soft starter sits on the same network as a generic Ethernet module. Peg word 5 even carries handshake pins to neighboring controllers: the plant's receiving and utility PLCs get production/acknowledge signals as part of the same step data as everything else.

VFD · SMC · 3 peer PLCs · MSG

A PlantPAx object per device

Every valve, motor, drive, and loop is a PlantPAx Add-On Instruction (sixty-odd solenoid valve objects, a bank of four-state divert clusters, a mix-proof valve, two dozen motors, a dozen PIDE loops), each with its standard faceplate, simulation mode, and alarm shelf. Operators learn one device once and know them all.

P_ValveSO · P_VSD · P_PIDE · P_D4SD
interlock groups 100+ P_Intlk permissive groups 100+ P_Perm solenoid valves 60+ P_ValveSO 4-state diverts 15+ P_D4SD PIDE loops 12+ controller tags 700+ simulation built-in, per device
// Contact07

Have a complex sequence that's ready for a modern platform?

Evaporators, batching, CIP, legacy PLC migrations: tell us what's running your process today, and we'll show you how we'd make it readable, provable, and changeable again.

Start a conversation