Capstone Project: Programming a Complete Automated Packaging System
Project Overview: An Automated Packaging System
This final lesson brings together everything from the previous eleven lessons into a complete industrial project: an automated packaging system that fills bags with product, seals them, and sends them to a case packer.
The system consists of four stations connected by a conveyor:
- Bag placement: an operator places an empty bag on the conveyor
- Filling station: a hopper dispenses product into the bag by weight
- Sealing station: a heat sealer closes the bag
- Case packing: sealed bags are counted and diverted into cases of 12
This is a realistic packaging line found in food, chemical, and agricultural plants across the Middle East and worldwide.
Requirements Analysis: Inputs and Outputs
Digital Inputs: start button (I0.0), stop button NC (I0.1), emergency stop NC (I0.2), bag-at-fill sensor (I0.3), bag-at-seal sensor (I0.4), sealer home (I0.5), sealer down (I0.6), bag-at-exit photoeye (I0.7).
Digital Outputs: conveyor motor (Q0.0), fill gate solenoid (Q0.1), sealer extend (Q0.2), diverter (Q0.3), green lamp (Q0.4), red lamp (Q0.5), buzzer (Q0.6).
Analog Inputs: load cell for bag weight (AI0, 4-20 mA, 0-5 kg), thermocouple for sealer temperature (AI1, 0-300 degrees C).
Analog Output: conveyor VFD speed reference (AQ0, 0-10V).
Program Design: Stages and Sequencing
The main program uses a state machine with these stages:
| State | Name | Action |
|---|---|---|
| 0 | IDLE | All outputs off, waiting for start |
| 1 | STARTING | Pre-checks: sealer at temperature, sensors clear |
| 2 | CONVEYOR_RUN | Run conveyor until bag reaches fill station |
| 3 | FILLING | Stop conveyor, open fill gate, monitor weight |
| 4 | TRANSFER | Close gate, run conveyor to sealer |
| 5 | SEALING | Stop conveyor, extend sealer, hold for seal time |
| 6 | DISCHARGE | Retract sealer, run conveyor to exit |
| 7 | CASE_COUNT | Count bag, divert if case full, return to state 2 |
Each transition has a clear condition: start button for IDLE to STARTING, sealer temperature above 180 degrees for STARTING to CONVEYOR_RUN, bag sensor for CONVEYOR_RUN to FILLING, target weight reached for FILLING to TRANSFER, and so on.
Writing the Code: Structured Text for Main Stages
TYPE E_SystemState :
( IDLE := 0, STARTING := 1, CONVEYOR_RUN := 2, FILLING := 3,
TRANSFER := 4, SEALING := 5, DISCHARGE := 6, CASE_COUNT := 7,
FAULTED := 99 );
END_TYPE
PROGRAM PRG_Main
VAR
eState : E_SystemState := E_SystemState.IDLE;
tonStartCheck : TON; tonSealHold : TON; tonDiverter : TON;
ctuBags : CTU;
rBagWeight : REAL; rSealTemp : REAL;
rTargetWeight : REAL := 1.0;
END_VAR
rBagWeight := ScaleLinear(nWeightRaw, 0.0, 5.0, 0, 27648);
rSealTemp := ScaleLinear(nSealTempRaw, 0.0, 300.0, 0, 27648);
IF NOT bEmergencyStop OR NOT bStopButton THEN
eState := E_SystemState.IDLE;
bConveyorMotor := FALSE; bFillGateOpen := FALSE; bSealerExtend := FALSE;
END_IF;
CASE eState OF
E_SystemState.IDLE:
bConveyorMotor := FALSE; bFillGateOpen := FALSE; bSealerExtend := FALSE;
IF bStartButton THEN eState := E_SystemState.STARTING; END_IF;
E_SystemState.STARTING:
tonStartCheck(IN := TRUE, PT := T#2s);
IF rSealTemp >= 180.0 AND bSealerHome AND tonStartCheck.Q THEN
tonStartCheck(IN := FALSE);
eState := E_SystemState.CONVEYOR_RUN;
END_IF;
E_SystemState.CONVEYOR_RUN:
bConveyorMotor := TRUE; nConveyorSpeed := 8000;
IF bBagAtFill THEN eState := E_SystemState.FILLING; END_IF;
E_SystemState.FILLING:
bConveyorMotor := FALSE; bFillGateOpen := TRUE;
IF rBagWeight >= (rTargetWeight - 0.02) THEN
bFillGateOpen := FALSE;
eState := E_SystemState.TRANSFER;
END_IF;
E_SystemState.TRANSFER:
bConveyorMotor := TRUE; nConveyorSpeed := 12000;
IF bBagAtSeal THEN bConveyorMotor := FALSE;
eState := E_SystemState.SEALING; END_IF;
E_SystemState.SEALING:
bSealerExtend := TRUE;
tonSealHold(IN := bSealerDown, PT := T#2s);
IF tonSealHold.Q THEN bSealerExtend := FALSE;
tonSealHold(IN := FALSE); eState := E_SystemState.DISCHARGE; END_IF;
E_SystemState.DISCHARGE:
IF bSealerHome THEN bConveyorMotor := TRUE; nConveyorSpeed := 16000;
IF bBagAtExit THEN eState := E_SystemState.CASE_COUNT; END_IF;
END_IF;
E_SystemState.CASE_COUNT:
ctuBags(CU := TRUE, RESET := FALSE, PV := 12);
bConveyorMotor := FALSE;
eState := E_SystemState.CONVEYOR_RUN;
END_CASE;
END_PROGRAM
HMI Screen: The Operator Interface
The main HMI screen is divided into four zones:
Header bar: system name, date/time, active alarms count, user login status.
Process graphic (center): simplified diagram showing conveyor, filling station with weight display, sealing station with temperature display, and case packer with bag count. Each station is color-coded (gray=idle, green=running, red=fault).
Control panel (right): Start/Stop buttons, speed selection, target weight entry with numeric keypad, batch size entry, and fault reset button.
Status bar (bottom): current state name, production count, elapsed run time, last fault description.
Key HMI tag update rates: weight and state at 250ms, temperature and bag count at 500ms, target weight input on change only. Alarms include emergency stop (critical), sealer overtemp above 250 degrees (high), sealer undertemp below 170 (medium), and weight overfill (high).
Testing and Commissioning
Commissioning follows three phases:
Phase 1 - I/O Checkout (no program): activate each sensor and verify the correct PLC input LED. Force each output and verify the field device responds. Test analog inputs with a calibrated signal source. Document on checkout sheets.
Phase 2 - Functional Testing (program running, no product): press Start and verify the startup sequence. Manually trigger sensors and verify correct state transitions. Test all stop conditions. Verify HMI displays and alarm activation.
Phase 3 - Production Trial (with product): verify fill weight accuracy over 20 bags. Check seal quality visually and with pull tests. Verify case count over 3 full cases. Measure cycle time against specification. Run continuously for 1 hour to catch intermittent issues.
Create a commissioning record with signed I/O checkout sheets, test results, production trial data, final PLC program backup, and any punch-list items.
Summary and Next Steps
This project demonstrated the complete lifecycle of a PLC automation system: requirements analysis, I/O documentation, state machine design, Structured Text programming, HMI design, and structured commissioning.
The twelve lessons covered: PLC fundamentals and hardware (1-2), Ladder Logic and Structured Text programming (3-4), data types, timers, and counters (5-6), modular programming and analog processing (7-8), motor control and communications (9-10), troubleshooting and project integration (11-12).
To continue advancing: practice building this system in CODESYS (free simulator), study PID closed-loop control for temperature and flow regulation, learn safety PLCs and SIL-rated programming, explore servo motion control, and investigate SCADA/MES integration for factory-wide data management.
Every industrial project follows this pattern: understand the process, document the I/O, design the sequence, write modular code, build the operator interface, and test systematically. Master this pattern, and you can automate any machine.