PLC portfolio project

ALT-1 Assembly & Leak Test Machine

A simulated special purpose machine that presses a cap onto a cast valve body and leak tests the assembly. It is controlled by an IEC 61131-3 program running on the OpenPLC soft PLC, and a plant simulator takes the place of the machine.

View source on GitHub Functional description (.pdf)

The ALT-1 plant simulator panel mid-cycle: PLC connected, machine running, part serial 3, cap press extended with the solenoid on, and the event log showing the latest signal changes.
The plant simulator panel, with the PLC running a cycle.

Overview

The hypothetical product is a small cast aluminium valve body. A cap is pressed onto the body, and the assembly is pressure decay leak tested before it is released.

Stations

  1. Load and identify The operator loads a part and presses Start. The machine assigns a serial number.
  2. Cap fit and press A pneumatic cylinder presses the cap on. Position sensors confirm travel, with a timeout fault.
  3. Leak test The machine runs a test on a leak test instrument and handles pass, fail, timeout and instrument fault.
  4. Unload Good parts would go to the good lane. Failed parts would go to a locked reject bin.

Control system architecture

Control system architecture The OpenPLC runtime runs a ladder main program, which calls the FB_Sequence function block. The runtime polls the plant simulator over Modbus TCP on localhost port 5020, writing 5 coils and 1 register and reading 9 discrete inputs. The simulator models the machine and is driven from an operator panel or terminal commands through one command queue. Soft PLC · OpenPLC runtime v4 Docker container, cyclic task every 20 ms main · Ladder Physical I/O, permissives, interlocks Run control and fault latching The only layer that drives outputs FB_Sequence · Structured Text Steps 0 to 50, abort to step 90 Sets request bits, never drives outputs Running Load_Ready sensors Req_Press_Extend Leak_Testing Serial Modbus TCP localhost:5020 5 coils + 1 register 9 discrete inputs PLC is the client, polls every 20–50 ms Plant simulator · plant_sim.py Python, standard library only Modbus server + machine model Cap press, 0.4 s travel each way Push buttons, guard, e-stop Pallet, part and serial display Operator panel Tkinter window Fault injection Terminal Text commands Type help Same commands, one queue
The PLC program and the plant simulator run on one PC and talk over Modbus TCP.
Soft PLC
OpenPLC runtime v4 in Docker
Languages
Ladder (main program), Structured Text (function blocks)
Scan
Cyclic task, 20 ms
Plant link
Modbus TCP, localhost:5020, 9 inputs, 5 coils, 1 register

Two layers

The ladder layer owns the physical I/O, permissives and interlocks, and is the only layer that drives outputs. The Structured Text sequence only sets request bits. It can ask for the cylinder to extend; the interlock layer decides whether it does.

Ladder rung calling FB_Sequence A ladder rung with a Running contact feeding the FB_Sequence function block. Its inputs are Running, Load_Ready, Part_Present, CapPress_Extended, CapPress_Retracted and Fault_Active. Its Req_Press_Extend output drives the CapPress_Req_Extend coil, and its other outputs go to FB_SEQUENCE.step, Part_Serial and Lamp_LeakTest. Running FB_SEQUENCE FB_Sequence Running Load_Ready Part_Present Press_Extended Press_Retracted Fault_Active Req_Press_Extend Step Serial Leak_Testing Load_Ready Part_Present CapPress_Extended CapPress_Retracted Fault_Active FB_SEQUENCE.step Part_Serial Lamp_LeakTest CapPress_Req_Extend
Rung 6 of the ladder program. The sequence's extend request goes to CapPress_Req_Extend, not to the solenoid; rung 7 turns it into CapPress_Extend only while the machine is running.

Machine sequence

StepNameMoves on when
0IdlePart loaded and machine running
10Press extendPress extended
20Press dwell500 ms dwell done
30Press retractPress retracted
40Leak test (stub)3 s stub timer done
50UnloadPart removed
90AbortedPart removed and no fault active
Machine sequence flow Step 0 Idle goes to step 10 Press extend when a part is loaded, assigning a serial number. Step 10 goes to 20 Press dwell when the press is extended, 20 to 30 Press retract after 500 ms, 30 to 40 Leak test when the press is retracted, and 40 to 50 Unload after 3 s. Step 50 returns to 0 when the part is removed. Stopping the machine during steps 10 to 40 goes to step 90 Aborted, which returns to 0 once the part is removed and no fault is active. 0Idle Load_Ready, serial +1 10Press extend Press extended 20Press dwell 500 ms dwell 30Press retract Press retracted 40Leak test (stub) 3 s stub timer 50Unload Part removed, next part Stop 90Aborted Part removed and no fault
The normal cycle runs down the left. Stopping during steps 10 to 40 aborts the part.

Plant simulator

plant_sim.py pretends to be the machine. It is a Modbus TCP server written in standard-library Python, with an operator panel and a terminal command line. It also injects faults, such as a jammed press, a slow press or a stuck sensor.

python3 sim/plant_sim.py
python3 sim/plant_sim.py --no-gui --port 5020 --travel 0.4
The plant simulator panel while the PLC runs a machine cycle.

Factory acceptance test

The functional description defines 30 tests, FAT-01 to FAT-30, each with an action and an expected result. They were run by hand against the plant simulator, driving the machine from its operator panel and checking how the PLC responded. Faults that would be hard to create on demand, such as a jammed press, a slow press or a stuck position sensor, were created with the simulator's fault injection.

The plant simulator panel with the Press jammed fault injected. The event log shows CapPress_Extend switching on, then Lamp_Running and CapPress_Extend switching off and Lamp_Fault switching on. The Fault and Reset available lamps are lit and the Reset button is enabled.
A cap press extend timeout created with fault injection. With the press jammed, the extend request times out, the machine stops and the fault latches.

What the tests cover

GroupTestsWhat they prove
Run controlFAT-01 to 10 Start seals in; Stop, an open guard or the e-stop stops the machine; the machine doesn't restart until Start is pressed again.
Cap pressFAT-11 to 18 Extend and retract timeouts and sensor conflicts latch a fault; reset is disabled until the press is home; a press not home at power-up is caught.
Machine sequenceFAT-19 to 25 A full cycle runs step by step, each part gets a new serial number, stopping mid-cycle aborts the part.
Status outputsFAT-26 to 30 The fault, reset and leak test lamps show the true state, and the serial number reaches the panel.

What testing found

Through testing I discovered that a part could be taken off the pallet during the leak test without any fault being shown, so an untested part could leave the machine unnoticed. As a fix, the PLC now drives a leak test lamp, Lamp_LeakTest, during step 40, and the Unload function is disabled while a leak test is being conducted. FAT-28 checks both.

Extensions

  • Simulated leak test instrument protocol and fault cases
  • Recipe handling for product variants
  • Separate load and press stations with pallet transfer
  • Visual inspection and supervisory HMI with OEE reporting
  • Automated test harness with chaos simulation