A full industrial bottling sequence controller built using OpenPLC Editor and IEC 61131-3 Structured Text (ST)
This project implements a multi-stage, state-machine-driven automated bottle filling station representative of real-world packaging and manufacturing line control systems. The controller manages the complete bottle handling sequence across discrete process steps — bottle presence detection, timed liquid fill, capper actuation, conveyor release, and batch counting — while incorporating fault detection with automatic process halt, and a dedicated manual override mode for maintenance and commissioning operations. The full solution was authored in IEC 61131-3 Structured Text within OpenPLC Editor and validated through forced-input simulation testing.
Automated bottling lines require deterministic, sequentially-ordered process control where each stage must complete successfully before the next can begin. Any deviation from expected conditions — a missing bottle, a timer overrun, or a failed actuator response — must be detected immediately and result in a controlled process halt to prevent product damage, equipment wear, or downstream line contamination. Simultaneously, the system must support operator intervention via manual override without compromising the integrity of the automatic control logic or requiring a full program restart to return to normal operation. Designing a control architecture that handles all three concerns — sequencing, fault safety, and dual-mode operation — within a single coherent PLC program was the core engineering challenge of this project.
FillTimer preset, then de-asserted before capping beginsCapTimer control to actuate the capping mechanism for a defined dwell periodReleaseTimer control to index the conveyor and advance the finished bottle out of the fill stationBottleSensor remains de-asserted beyond the preset fault window, ProcessFault is set and the sequence haltsProcessFault condition to signal operators via indicator or SCADA interfaceManualFill, ManualCap, and ManualRelease operator inputsStructured Text was selected as the implementation language over Ladder Logic due to the complexity of managing a multi-step state machine with concurrent timer instances, conditional fault branching, and dual-mode output arbitration within the same scan cycle. The explicit control flow available in Structured Text — conditional blocks, integer state comparisons, and inline timer calls — provided significantly cleaner and more maintainable logic than equivalent Ladder networks, which would have required extensive cross-referencing of coils and contacts across multiple rungs to represent the same behavior.
VAR_INPUT
BottleSensor : BOOL;
StartButton : BOOL;
ResetButton : BOOL;
ManualMode : BOOL;
ManualFill : BOOL;
ManualCap : BOOL;
ManualRelease : BOOL;
END_VAR
VAR_OUTPUT
FillValve : BOOL;
Capper : BOOL;
ConveyorMotor : BOOL;
FaultAlarm : BOOL;
END_VAR
VAR
ProcessStep : INT;
BottleCount : INT;
FillTimer : TON;
CapTimer : TON;
ReleaseTimer : TON;
FaultTimer : TON;
ProcessFault : BOOL;
END_VAR
(* Step-based sequence control *) Step 1 → Wait for bottle Step 2 → Fill bottle Step 3 → Cap bottle Step 4 → Release bottle Fault Detection: If no bottle is detected for too long, system stops and triggers alarm. Manual Mode: Operator can manually control outputs for maintenance and testing.
System validation was conducted entirely within the OpenPLC runtime environment using the integrated simulator and real-time variable debugger. All digital inputs were exercised via forced-variable injection to replicate field conditions across every process stage without requiring physical hardware. The following test scenarios were executed and confirmed:
BottleSensor was forced HIGH to simulate bottle arrival at the fill station, triggering ProcessStep advancement from Step 1 to Step 2 as expectedFillTimer, CapTimer, and ReleaseTimer TON instances were verified to assert their respective outputs for the correct preset durations before advancing the state registerProcessStep transitions were monitored in real time to confirm correct sequential ordering with no step skipping or re-entry under normal operating conditionsBottleSensor LOW beyond the FaultTimer preset — ProcessFault was set and FaultAlarm asserted correctly with all process outputs de-energisedManualMode was asserted mid-sequence to confirm automatic output control was suspended and individual outputs responded correctly to ManualFill, ManualCap, and ManualRelease inputs without cross-contamination from the sequence logicResetButton was verified to clear ProcessFault, de-assert FaultAlarm, and return ProcessStep to Step 1 within the same scan cycle, restoring the system to a ready state without requiring a program reload
The primary engineering challenge was designing a state machine that could handle fault injection and manual override without introducing undefined output states or unintended actuator activation during mode transitions. In early iterations, switching into ManualMode mid-sequence left residual timer state and output assertions from the previous step partially active, creating conflicting output conditions. This was resolved by implementing an explicit output de-energisation block at the top of the manual mode branch — ensuring all automatic outputs were unconditionally cleared before operator control inputs were evaluated, regardless of which ProcessStep was active at the time of the mode switch.
A secondary challenge involved ensuring TON timer instances reset correctly between sequence cycles. Timers that were not explicitly reset before re-entry into their associated steps retained elapsed time from the previous cycle, causing immediate .Q assertion on re-entry and skipping the intended dwell period entirely. This was corrected by resetting each TON's IN pin to FALSE for at least one scan cycle at step exit — a subtle but critical requirement of how IEC 61131-3 TON blocks handle state internally. Identifying and resolving this behaviour deepened my understanding of function block instance lifecycles within the PLC scan cycle model.
.Q output behaviour across scan cycles in a sequential context