Case Study: PLC Sequential Bottle Filling Station with Fault Detection and Manual Override

A full industrial bottling sequence controller built using OpenPLC Editor and IEC 61131-3 Structured Text (ST)

Project Overview

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.

Problem

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.

Solution

Control System Architecture:
  • BottleSensor — Digital BOOL input; confirms bottle presence at the fill station before the sequence is permitted to advance from Step 1
  • ProcessStep — Integer state register; drives the step-based sequence execution engine, with each value mapping to a discrete machine state and its associated output conditions
  • FillValve — Discrete BOOL output; asserted during Step 2 for the duration of the FillTimer preset, then de-asserted before capping begins
  • Capper — Discrete BOOL output; activated during Step 3 under CapTimer control to actuate the capping mechanism for a defined dwell period
  • ConveyorMotor — Discrete BOOL output; pulsed during Step 4 under ReleaseTimer control to index the conveyor and advance the finished bottle out of the fill station
  • BottleCount — Integer accumulator; incremented at the completion of each successful full cycle to track total production output
  • FaultTimer — TON instance; monitors Step 1 dwell time — if BottleSensor remains de-asserted beyond the preset fault window, ProcessFault is set and the sequence halts
  • FaultAlarm — Discrete BOOL output; asserted on any ProcessFault condition to signal operators via indicator or SCADA interface
  • ManualMode — BOOL input; when asserted, suspends automatic sequence execution and transfers output control to the ManualFill, ManualCap, and ManualRelease operator inputs

Structured 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.

Project Screenshots

Variables Used

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

Core Structured Text Logic

(* 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.

Testing & Debugging

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:

Challenges Faced

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.

Key Learning Outcomes

Tools Used