PackML Structured Text Programming
By Mequonite
PackML is an acronym for Packaging Machine Language. It is a subset of the guidelines and standards published by OMAC. This article uses the standards established in the PackML definition to present Structured Text Programming for implementing the PackML standard for the Automatic Operation of a machine.
PackML does an excellent job of defining an 18 State representation of what a machine is doing (Output Variable) while in automatic operation.
Graphical - Flow Diagram - PackML
The 18 states represented in the PackML model
State
Number Description
0 = UNDEFINED
1 = CLEARING
2 = STOPPED
3 = STARTING
4 = IDLE
5 = SUSPENDED
6 = EXECUTE
7 = STOPPING
8 = ABORTING
9 = ABORTED
10 = HOLDING
11 = HELD
12 = UNHOLDING
13 = SUSPENDING
14 = UNSUSPENDING
15 = RESETTING
16 = COMPLETING
17 = COMPLETE
Input Conditions for PackML
The PackML Standard uses 9 operator or machine input conditions (Input Variables) to manipulate or update the 18 available output states. The 9 input conditions are represented as:
Input Description
1 In Auto
2 ESTOP Okay
3 Reset
4 Start
5 Stop
6 Hold
7 Clear
8 Starved
9 Cycle Stop
Interface
PackML Function Block
FUNCTION_BLOCK FB50 // PackML Function Block VAR_INPUT // Nine Operator or Logically Derived Inputs IN_AUTO : BOOL := FALSE; // Activate or Deactivate Machine --- Axis Enables --- ESTOP_OKAY : BOOL := TRUE; // Issue an ESTOP to Abort Operation, waiting for a Clear to proceed RESET : BOOL := FALSE; // Issue a Reset to establish IDLE condition START : BOOL := FALSE; // Issue Start to establish Production (Execute) State STOP : BOOL := FALSE; // Issue Stop to Halt movement HOLD : BOOL := FALSE; // Accept Hold to Pause production state CLEAR : BOOL := FALSE; // Issue Clear to reset ESTOP (Aborted) condition STARVED : BOOL := FALSE; // Accept Starved to wait for upstream product flow CYCLE_STOP : BOOL := FALSE; // Issue Complete to run out production and idle for next run END_VAR
VAR_IN_OUT // 17 PackML V3 States + UDEFINED or BYPASS State : INT; // UNDEFINED, CLEARING, STOPPED, STARTING, IDLE, SUSPENDED, EXECUTE, // STOPPING, ABORTING, ABORTED, HOLDING, HELD, UNHOLDING, // SUSPENDING, UNSUSPENDING, RESETTING, COMPLETING, COMPLETE END_VAR
VAR_OUTPUT END_VAR
VAR_TEMP // Temporary Variables CLEARED : BOOL; Reset_trig : BOOL; Start_trig : BOOL; Stop_trig : BOOL; Clear_trig : BOOL; Abort_trig : BOOL; First_Pass : BOOL; Reset_ONS : BOOL; Start_ONS : BOOL; Stop_ONS : BOOL; Clear_ONS : BOOL; Abort_ONS : BOOL; END_VAR VAR // Static Variables or embedded FB's like TON, CTU, TOF, etc... END_VAR
// Start of Function Block Program IF NOT First_Pass THEN State := 0; // Set PackML state to (0) UNDEFINED on Power Up First_Pass := TRUE; END_IF;
// Configure the ONE Shot control bits IF RESET AND NOT Reset_ONS THEN Reset_trig := TRUE; ELSE Reset_trig := FALSE; END_IF; Reset_ONS := RESET; IF START AND NOT Start_ONS THEN Start_trig := TRUE; ELSE Start_trig := FALSE; END_IF; Start_ONS := START; IF STOP AND NOT Stop_ONS THEN Stop_trig := TRUE; ELSE Stop_trig := FALSE; END_IF; Stop_ONS := STOP; IF CLEAR AND NOT Clear_ONS THEN Clear_trig := TRUE; ELSE Clear_trig := FALSE; END_IF; Clear_ONS := CLEAR; IF (NOT IN_AUTO OR NOT ESTOP_OKAY) AND NOT Abort_ONS THEN Abort_trig := TRUE; ELSE Abort_trig := FALSE; END_IF; Abort_ONS := (NOT IN_AUTO OR NOT ESTOP_OKAY); // Check for a STOP command IF ((State <> 9(*ABORTED*)) OR (State <> 8(*ABORTING*)) OR (State <> 2(*STOPPED*))) AND Stop_trig THEN State := 7(*STOPPING*); END_IF;
// Check for ABORT command <-- Loss of either IN_AUTO or ESTOP_OKAY IF State <> 9(*ABORTED*) AND Abort_trig THEN State := 8(*ABORTING*); END_IF;
// Check for loss of ESTOP_OKAY IF NOT ESTOP_OKAY OR NOT IN_AUTO THEN CLEARED := FALSE; END_IF; CASE State OF 0: // UNDEFINED: // Bypass PackML IF IN_AUTO THEN State := 9(*ABORTED*); END_IF;
1: // CLEARING: ; // State for hanlding application specific Motion 2: // STOPPED: IF Reset_trig THEN State := 15(*RESETTING*); END_IF; 3: // STARTING: ; // State for hanlding application specific Motion
4: // IDLE: IF Start_trig THEN State := 3(*STARTING*); END_IF;
5: // SUSPENDED: IF NOT STARVED THEN State := 14(*UNSUSPENDING*); END_IF;
6: // EXECUTE: IF HOLD THEN State := 10(*HOLDING*); END_IF; IF STARVED THEN State := 13(*SUSPENDING*); END_IF; IF CYCLE_STOP THEN State := 16(*COMPLETING*); END_IF;
7: // STOPPING: ; // State for hanlding application specific Motion 8: // ABORTING: ; // All neccessary axis stops ; // State for hanlding application specific Motion 9: //ABORTED: // Comparable to a Bypass of Auto when Aborted IF IN_AUTO AND ESTOP_OKAY AND CLEARED THEN State := 2(*STOPPED*); // Axis Enabled, Ready for Reset END_IF; IF IN_AUTO AND ESTOP_OKAY AND Clear_trig THEN State := 1(*CLEARING*); END_IF;
IF NOT IN_AUTO THEN State := 0(*UNDEFINED*); END_IF; 10: // HOLDING: ; // State for hanlding application specific Motion 11: // HELD: IF Start_trig OR NOT HOLD THEN State := 12(*UNHOLDING*); END_IF; 12: // UNHOLDING: ; // State for hanlding application specific Motion 13: // SUSPENDING: ; // State for hanlding application specific Motion 14: // UNSUSPENDING: ; // State for hanlding application specific Motion
15: // RESETTING: ; // State for hanlding application specific Motion
16: // COMPLETING: ; // State for hanlding application specific Motion 17: // COMPLETE: IF Reset_trig THEN State := 15(*RESETTING*); END_IF; ELSE; END_CASE; END_FUNCTION_BLOCK
Vj 2 weeks ago
Where should we declare the state numbers in the program.?
Also this is informative. Can you upload some more programs,Like sorting,pick and place etc?
Thanks