Skip to content

Function Blocks

FB_BaseFB

(abstract, implements I_BaseFB)

Contains property backers for all I_BaseFB properties. This is the most basic building block of all framework function blocks. Can be directly inherited-if so, entry point is up to the developer.

Info

See I_BaseFB for more information.

Methods

Method Return Type Access Description
Marker null PUBLIC Adds a message to the global trace log and sets its Flags to 1
Trace null PUBLIC Adds a message to the global trace log
TraceWithJson null PUBLIC Adds a message to the global trace log along with additional JSON object

Trace()

1
2
3
4
METHOD PUBLIC Trace
VAR_INPUT
    Message : T_MaxString;
END_VAR

Message should be the textual description of the debug message.

TraceWithJson()

1
2
3
4
5
METHOD PUBLIC TraceWithJson
VAR_INPUT
    Message : T_MaxString;
    Json    : T_MaxString;
END_VAR

Message should be the textual description of the debug message. Json should be a properly formatted JSON object.

FB_ComponentBase

(abstract, extends FB_CyclicFB, implements I_ComponentBase)

Contains property backers for all I_ComponentBase properties as well as basic housekeeping code for all component-level function blocks.

All PROTECTED methods can and usually should be overridden for component-specific functionality (HMI commands, event handling, etc.) and then called using SUPER^.Method().

Info

See I_ComponentBase and FB_CyclicFB for more information.

CreateEvents()

METHOD PROTECTED CreateEvents

If a component has its own specific events defined, override this method to initialize them and then call SUPER^.CreateEvents() to initialize the base component events.

HMICommunication()

METHOD PROTECTED HMICommunication

Override and SUPER^ call this method to implement component-specific HMI commands, status, configuration items. The base method uses a predefined local HMICommandActive_Descendant as an interlock to ensure only one command is fired at a time, whether it's a base command or a component-specific command. The base method also provides HMICommandActive_Base for you to use in your custom method extensions.

Info

See ST_ComponentBase_HMI for more information.

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
SUPER^.HMICommunication();
HMICommand_MyComponent_RT(CLK := (ComponentBase_HMI.Status.HMIControlAvailable AND NOT HMICommandActive_Base) AND (MyComponent_HMI.Command.MyCommand XOR MyComponent_HMI.Command.MyOtherCommand));

//Signal to FB_ComponentBase that a command is active
HMICommandActive_Descendant := ComponentBase_HMI.Status.HMIControlAvailable AND (MyComponent_HMI.Command.MyCommand OR MyComponent_HMI.Command.MyOtherCommand OR MyComponent_HMI.Command.Jog);

//Process Momentary HMI requests
IF HMICommand_MyComponent_RT.Q THEN
    IF MyComponent_HMI.Command.MyCommand THEN
        MyCommand();
    ELSIF MyComponent_HMI.Command.MyOtherCommand THEN
        MyOtherCommand();
    END_IF
END_IF

//Handle non-momentary commands such as jogging
IF ComponentBase_HMI.Status.HMIControlAvailable AND NOT HMICommand_MyComponent_RT.Q THEN
    IF MyComponent_HMI.Command.Jog THEN
        MyComponent.Jog();
    END_IF
END_IF

//Update HMI status info
MyComponent_HMI.Status.Red   := Red;
MyComponent_HMI.Status.Green := Green;
MyComponent_HMI.Status.Blue  := Blue;

Initialize()

METHOD PROTECTED Initialize

In cases where a custom component contains one or many other components within, override Initialize() and interlock the SUPER^.Initalize() call with the InitComplete property of your subcomponent(s). CyclicLogic() should also be overridden and the calls to subcomponents' CyclicLogic() placed within. Through a long and complicated call chain, this pattern will ensure subcomponent(s) have initialized completely before your custom component reports InitComplete = TRUE.

Example

1
2
3
4
5
6
7
8
9
METHOD PROTECTED FINAL Initialize : BOOL;

IF NOT (MySubcomponent1.InitComplete AND MySubcomponent2.InitComplete) THEN
    RETURN;
END_IF

IF SUPER^.Initialize() THEN
    Initialize := TRUE;
END_IF
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
METHOD PUBLIC FINAL CyclicLogic

MySubcomponent1.CyclicLogic();
MySubcomponent2.CyclicLogic();

//My custom component's code/state machine here

SUPER^.CyclicLogic();

_Busy  := MainState <> Idle AND MainState <> Error;
_Error := MainState = Error AND MainState <> Reset;

Monitoring()

METHOD PROTECTED Monitoring

Override this method to add event handling to your custom component.

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
METHOD PROTECTED Monitoring

SUPER^.Monitoring();

//ErrorID 1 - MC_MoveVelocity
IF BasicAxis.MC_MoveVelocity.Error AND NOT BasicAxisAlarms[E_BasicAxis.MoveVelocityError].bRaised THEN
    RaiseAlarmWithStrings(Alarm := BasicAxisAlarms[E_BasicAxis.MoveVelocityError], UDINT_TO_STRING(BasicAxis.ErrorID), '');
ELSIF NOT BasicAxis.MC_MoveVelocity.Error AND BasicAxisAlarms[E_BasicAxis.MoveVelocityError].bRaised THEN
    BasicAxisAlarms[E_BasicAxis.MoveVelocityError].Clear(0, 0);
END_IF

//ErrorID 2 - MC_MoveRelative
IF BasicAxis.MC_MoveRelative.Error AND NOT BasicAxisAlarms[E_BasicAxis.MoveRelativeError].bRaised THEN
    RaiseAlarmWithStrings(Alarm := BasicAxisAlarms[E_BasicAxis.MoveRelativeError], UDINT_TO_STRING(BasicAxis.MC_MoveRelative.ErrorID), '');
ELSIF NOT BasicAxis.MC_MoveRelative.Error AND BasicAxisAlarms[E_BasicAxis.MoveRelativeError].bRaised THEN
    BasicAxisAlarms[E_BasicAxis.MoveRelativeError].Clear(0, 0);
END_IF

_CurrentAlarmSeverity := F_GetMaxSeverityRaised(Alarms := BasicAxisAlarms, CurrentSeverity := CurrentAlarmSeverity);

RaiseAlarm()

1
2
3
4
METHOD PROTECTED RaiseAlarm
VAR_IN_OUT
    Alarm : FB_TcAlarm;
END_VAR
Raises an alarm with no arguments

RaiseAlarmWithStrings()

1
2
3
4
5
6
7
8
9
METHOD PROTECTED RaiseAlarmWithStrings
VAR_IN_OUT
    Alarm : FB_TcAlarm;
END_VAR

VAR_INPUT
    String_1 : STRING;
    String_2 : STRING;
END_VAR
Raises an alarm with optional contextual information. In actuality the event being raised takes 3 string arguments, but the component's Name is automatically passed as the first argument.

RaiseEventWithStrings()

1
2
3
4
5
6
7
8
9
METHOD PROTECTED RaiseEventWithStrings
VAR_IN_OUT
    Alarm : FB_TcAlarm;
END_VAR

VAR_INPUT
    String_1 : STRING;
    String_2 : STRING;
END_VAR
Raises an event with optional contextual information. In actuality the event being raised takes 3 string arguments, but the component's Name is automatically passed as the first argument. Events do not set the Error bit when they are raised.

FB_ControlSource

(abstract, extends FB_CyclicFB, implements I_PackML_ExternalController)

A control source refers to any external device or system which needs to command a state/mode change or be notified of such a change by any I_PackML_Control. These are usually submodules of otherwise descendants of FB_PackML_BaseModule.

Examples of such a device are pushbutton groups, HMIs, or SCADA systems.

Info

See FB_CyclicFB and I_PackML_ExternalController for more information.

Tip

By extending FB_ControlSource and overriding CyclicLogic(), custom behavior can be designed to fit a particular need.

Properties

Property Type Access Description
Registered BOOL R Flag indicating that the function block has been successfully registered with a submodule

CyclicLogic() Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
IF NOT _InitComplete THEN
    _InitComplete := Initialize();
    RETURN;
END_IF

//Copy the module to the local mode and state
MainPMLControl_Standard.CurrentMode  := ipModule.CurrentMode;
MainPMLControl_Standard.CurrentState := ipModule.CurrentState;
FOR i := 1 TO 5 DO
    MainPMLControl_Standard.ModeNames[i] := F_UnitModeToString(TO_DINT(i));
END_FOR

//Process requests
R_HMICommand(CLK := (MainPMLControl_Simplified.ResetPressed XOR MainPMLControl_Simplified.StartPressed XOR MainPMLControl_Simplified.StopPressed) XOR
                    (MainPMLControl_Standard.StateCommand <> E_PMLCommand.ePMLCommand_Undefined AND MainPMLControl_Standard.StateCommandLast <> MainPMLControl_Standard.StateCommand) XOR
                    (MainPMLControl_Standard.ModeCommandLast <> MainPMLControl_Standard.ModeCommand));

IF R_HMICommand.Q THEN
    MainPMLControl_Standard.ModeCommandLast  := MainPMLControl_Standard.ModeCommand;
    MainPMLControl_Standard.StateCommandLast := MainPMLControl_Standard.StateCommand;
    IF MainPMLControl_Simplified.ResetPressed AND MainPMLControl_Simplified.ResetPermissive AND MainPMLControl_Standard.CurrentState = E_PMLState.ePMLState_Aborted THEN
        ipModule.ChangeState(Tc3_PackML_V2.E_PMLCommand.ePMLCommand_Clear);
    ELSIF MainPMLControl_Simplified.ResetPressed AND MainPMLControl_Simplified.ResetPermissive THEN
        ipModule.ChangeState(Tc3_PackML_V2.E_PMLCommand.ePMLCommand_Reset);
    ELSIF MainPMLControl_Simplified.StartPressed AND MainPMLControl_Simplified.StartPermissive THEN
        IF MainPMLControl_Standard.CurrentState = Tc3_PackML_V2.E_PMLState.ePMLState_Idle THEN
            ipModule.ChangeState(Tc3_PackML_V2.E_PMLCommand.ePMLCommand_Start);
        ELSIF MainPMLControl_Standard.CurrentState = Tc3_PackML_V2.E_PMLState.ePMLState_Held THEN
            ipModule.ChangeState(Tc3_PackML_V2.E_PMLCommand.ePMLCommand_Unhold);
        END_IF
    ELSIF MainPMLControl_Simplified.StopPressed AND MainPMLControl_Simplified.StopPermissive THEN
        ipModule.ChangeState(Tc3_PackML_V2.E_PMLCommand.ePMLCommand_Stop);
    ELSIF ipModule.StateCommand <> MainPMLControl_Standard.StateCommand THEN
        ipModule.StateCommand := MainPMLControl_Standard.StateCommand;
    ELSIF ipModule.ModeCommand <> MainPMLControl_Standard.ModeCommand THEN
        ipModule.ModeCommand := MainPMLControl_Standard.ModeCommand;
    END_IF
END_IF

//Set the permissives for each button
MainPMLControl_Simplified.StartPermissive :=
    MainPMLControl_Standard.CurrentState = Tc3_PackML_V2.E_PMLState.ePMLState_Idle OR MainPMLControl_Standard.CurrentState = Tc3_PackML_V2.E_PMLState.ePMLState_Held;

MainPMLControl_Simplified.StopPermissive :=
    (MainPMLControl_Standard.CurrentState <> Tc3_PackML_V2.E_PMLState.ePMLState_Stopped AND MainPMLControl_Standard.CurrentState <> Tc3_PackML_V2.E_PMLState.ePMLState_Clearing AND
    MainPMLControl_Standard.CurrentState <> Tc3_PackML_V2.E_PMLState.ePMLState_Aborted AND MainPMLControl_Standard.CurrentState <> Tc3_PackML_V2.E_PMLState.ePMLState_Aborting AND
    MainPMLControl_Standard.CurrentState <> Tc3_PackML_V2.E_PMLState.ePMLState_Idle AND MainPMLControl_Standard.CurrentState <> Tc3_PackML_V2.E_PMLState.ePMLState_Undefined);

MainPMLControl_Simplified.ResetPermissive :=
    MainPMLControl_Standard.CurrentState = Tc3_PackML_V2.E_PMLState.ePMLState_Complete OR MainPMLControl_Standard.CurrentState = Tc3_PackML_V2.E_PMLState.ePMLState_Stopped OR
    MainPMLControl_Standard.CurrentState = Tc3_PackML_V2.E_PMLState.ePMLState_Aborted;

FB_CyclicFB

(abstract, extends FB_BaseFB, implements I_CyclicFB)

Contains property backers for all I_CyclicFB properties. CyclicLogic() is introduced as the entry point.

Info

See I_BaseFB and FB_BaseFB for more information.

Success

No code should be written in the body of function blocks extending. FB_CyclicFB. While nothing will break by doing so, it violates the design pattern of the framework.

FB_PackML_BaseModule

(abstract, extends FB_CyclicFB, implements I_PackML_BaseModule, I_PackML_Control)

Methods

General

Method Return Type Access Description
CreateEvents null PROTECTED Initializes base component events
Initialize BOOL PROTECTED Basic initialization routine
RegisterComponent null PROTECTED Adds a given I_ComponentBase to the list of components in a submodule Must be done before InitComplete is set
RegisterExternalController BOOL PUBLIC Takes an instance of I_PackML_ExternalController and adds it to an internal collection of external controllers. External controllers are, for example, HMI or pushbutton aggregation function blocks.
RegisterSubmodule BOOL PROTECTED Adds a given I_PackML_BaseModule as a child of a submodule Must be done before InitComplete is set
StateComplete null PROTECTED Signal to PackML state machine sequencer that this module can advance to the next state. This is normally called automatically by the state sequencer.
ModeChanged null PROTECTED Method called by Base on Mode change. One Cycle call.
StateChanged null PROTECTED Method called by Base on State change. One Cycle call.
CreateEvents()

METHOD PROTECTED CreateEvents

If a module has its own specific events defined, override this method to initialize them and then call SUPER^.CreateEvents() to initialize the base component events.

Initialize()

METHOD PROTECTED Initialize

The base Initialize() method handles some basic tasks like setting pointers, counting the number of submodules/components, and most importantly ensuring any children are completely initialized before itself returning TRUE.

When creating an Equipment Module, override this method and implement your own routine. Many times it makes sense to use a state machine to make sure things are called in order and only as required. In fact, the base Initialize() does this using the predefined local SequenceState as the indexer. A second predefined local DescendantSequenceState can be used for indexing a state machine in your overridden Initialize().

!!!! example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
METHOD PROTECTED FINAL Initialize : BOOL
VAR
    i : UDINT; //Generic iteration value
END_VAR

CASE DescendantSequenceState OF
    0:
        // Define the interfaces to the different subunits (Must take place before SUPER^.initialize call)
        FOR i := 1 TO SPT_PackMLBase.Parameters_PackML_Base.MAX_NO_OF_SUBMODULES DO
            ipSubModules[i] := ipSubModules_Init[i];
        END_FOR

        FOR i := 1 TO SPT_PackMLBase.Parameters_PackML_Base.MAX_NO_OF_COMPONENTS DO
            ipComponents[i] := ipComponents_Init[i];
        END_FOR

        LogModuleModeChanges    := FALSE;
        LogModuleStateChanges   := FALSE;
        DescendantSequenceState := DescendantSequenceState + 10;
    10:
        CustomModes(eMode                          := 4,
                    sName                          := 'My Custom Mode',
                    bDisableClearing               := FALSE,
                    bDisableStarting               := FALSE,
                    bDisableSuspended              := TRUE,
                    bDisableStopping               := FALSE,
                    bDisableAborting               := FALSE,
                    bDisableHolding                := TRUE,
                    bDisableHeld                   := TRUE,
                    bDisableUnholding              := TRUE,
                    bDisableSuspending             := TRUE,
                    bDisableUnsuspending           := TRUE,
                    bDisableResetting              := FALSE,
                    bDisableIdle                   := FALSE,
                    bDisableCompleting             := TRUE,
                    bDisableComplete               := TRUE,
                    bEnableUnitModeChangeStopped   := TRUE,
                    bEnableUnitModeChangeIdle      := TRUE,
                    bEnableUnitModeChangeSuspended := FALSE,
                    bEnableUnitModeChangeExecute   := TRUE,
                    bEnableUnitModeChangeAborted   := TRUE,
                    bEnableUnitModeChangeHeld      := FALSE,
                    bEnableUnitModeChangeComplete  := FALSE,
                    bError                         =>,
                    nErrorId                       =>);
    20:
        FOR i := 1 TO 4 DO
            ModeNames[i] := F_UnitModeToString(UDINT_TO_DINT(i));
        END_FOR

        DescendantSequenceState := DescendantSequenceState + 10;
    30:
        IF SUPER^.Initialize() THEN
            Initialize                 := TRUE;
        END_IF
END_CASE

RegisterComponent()

Prior to v3.2.2, components were added to submodules by iterating through a preinitialized array of I_ComponentBase and adding them another internal array. This was typically the first step in the submodule initialization process. RegisterComponent() gives the option to add components to the internal array one at a time. This can improve readability when the number of components grows large.

RegisterExternalController()

Established a two-way link between an I_PackML_ExternalController and this submodule. Allows for external control of mode/state as well as notification of such changes via callback.

! info See FB_ControlSource for more information.

1
2
3
4
METHOD FINAL RegisterExternalController : BOOL
VAR_INPUT
    Controller : I_PackML_ExternalController;
END_VAR
RegisterSubmodule()

Prior to v3.2.2, child submodules (e.g. Equipment Modules under a Machine Module) were added to submodules by iterating through a preinitialized array of I_PackML_BaseModule and adding them another internal array. This was typically the first step in the submodule initialization process. RegisterSubmodule() gives the option to add submodules to the internal array one at a time. This can improve readability when the number of submodules grows large.

Alarm Handling

Method Return Type Access Description
AbortImmediate null PROTECTED Sequence to execute when a submodule or component faults. Ending PackML state will be E_PMLState.ePMLState_Aborted
AbortImmediateError null PROTECTED Sequence to execute when a submodule or component faults. Ending PackML state will be E_PMLState.ePMLState_Aborted and an event will be raised
HoldControlled null PROTECTED Sequence to execute when a submodule or component faults. Ending PackML state will be E_PMLState.ePMLState_Held
HoldImmediate null PROTECTED Sequence to execute when a submodule or component faults. Ending PackML state will be E_PMLState.ePMLState_Held
StopControlled null PROTECTED Sequence to execute when a submodule or component faults. Ending PackML state will be E_PMLState.ePMLState_Stopped
StopImmediate null PROTECTED Sequence to execute when a submodule or component faults. Ending PackML state will be E_PMLState.ePMLState_Stopped
SuspendControlled null PROTECTED Sequence to execute when a submodule or component faults. Ending PackML state will be E_PMLState.ePMLState_Suspended
SuspendImmediate null PROTECTED Sequence to execute when a submodule or component faults. Ending PackML state will be E_PMLState.ePMLState_Suspended

Info

The method which will be called on submodule or component fault depends on the severity of the event and the behavior defined by the subcomponent/component's ParentResponseDefinitions property.

AbortImmediateError()

1
2
3
4
5
METHOD PROTECTED AbortImmediateError
VAR_INPUT
    Name     : STRING;
    IsModule : BOOL;
END_VAR
Name will be included in the event text. If IsModule is TRUE, a SubModuleError is raised. If FALSE a ComponentError is raised.

HMI

Method Return Type Access Description
AllowHMIControl null PROTECTED Signal to this module that external functions via HMI should be allowed
BlockHMIControl null PROTECTED Signal to this module that external functions via HMI should be blocked
HMICommunication null PROTECTED Called cyclically; Handles HMI command requests
HMIPermissions null PROTECTED Called cyclically; sets whether or not HMI commands are allowed based on current PackML mode

Notes AllowHMIControl()

1
2
3
4
METHOD PROTECTED FINAL AllowHMIControl
VAR_INPUT
    ThisModuleOnly : BOOL; //! If TRUE, only the PackML module itself is controllable. If FALSE, all components become controllable as well
END_VAR

HMICommunication() METHOD PROTECTED HMICommunication

Override and SUPER^ call this method to implement component-specific HMI commands, status, configuration items. The base method uses a predefined local HMICommandActive_Descendant as an interlock to ensure only one command is fired at a time, whether it's a base command or a component-specific command. The base method also provides HMICommandActive_Base for you to use in your custom method extensions.

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
SUPER^.HMICommunication();
HMICommand_MyEquipmentModule_RT(CLK := (PackMLBaseModule_HMI.Status.HMIControlAvailable AND NOT HMICommandActive_Base) AND (MyEquipmentModule_HMI.Command.MyCommand XOR MyEquipmentModule_HMI.Command.MyOtherCommand));

//Signal to FB_PackMLBaseModule that a command is active
HMICommandActive_Descendant := PackMLBaseModule_HMI.Status.HMIControlAvailable AND (MyEquipmentModule_HMI.Command.MyCommand OR MyEquipmentModule_HMI.Command.MyOtherCommand);

//Process Momentary HMI requests
IF HMICommand_MyEquipmentModule_RT.Q THEN
    IF MyEquipmentModule_HMI.Command.MyCommand THEN
        MyCommand();
    ELSIF MyEquipmentModule_HMI.Command.MyOtherCommand THEN
        MyOtherCommand();
    END_IF
END_IF

//Update HMI status info
MyEquipmentModule_HMI.Status.Red   := Red;
MyEquipmentModule_HMI.Status.Green := Green;
MyEquipmentModule_HMI.Status.Blue  := Blue;

Monitoring

Method Return Type Access Description
ComponentMonitor null PROTECTED Called cyclically; checks components for faults and calls appropriate reaction method
SubModuleMonitor null PROTECTED Called cyclically; checks submodules for faults and calls appropriate reaction method

Primary & Acting States

Method Return Type Access Description
Aborted null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Aborted
Complete null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Complete
Execute null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Execute
Held null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Held
Idle null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Idle
Stopped null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Stopped
Suspended null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Suspended
Undefined null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Undefined. Should not normally be called.
Aborting null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Aborting
Clearing null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Clearing
Completing null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Completing
Holding null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Holding
Resetting null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Resetting
Starting null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Starting
Stopping null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Stopping
Suspending null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Suspending
Unholding null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Unholding
Unsuspending null PROTECTED Called cyclically according to PackML state; logic/sequence associated with PackML state E_PMLState.ePMLState_Unsuspending

Info

The private method StateControl will automatically call the method that corresponds with the module's PackML state. These methods are typically overriden and replaced with customized machine logic.

Set NoStateTasksToComplete to TRUE to indicate to the state sequencer that there are things left to do before advancing states. Set StateTasksComplete when your machine logic is completed. Both of these variables are reinitialized when the state is advanced, so no additional management is necessary.

Call SUPER^.State() at the end of your method override so that the base method can take care of housekeeping.

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
METHOD PROTECTED FINAL Clearing

CASE SequenceState OF
    0:
        NoStateTasksToComplete := FALSE;
        SequenceState          := SequenceState + 10;
    10:
        //Reset any alarms that get latched
        UnwindAlarms[E_Unwind.StartTimeout].Clear(0, 0);
        SequenceState := SequenceState + 10;
    20:
        // Enable here
        Axis.Enable();

        // Check enabled here
        IF Axis.Enabled THEN
            SequenceState := SequenceState + 10;
        END_IF
    30:
        StateTasksComplete := TRUE;
END_CASE

SUPER^.Clearing();

FB_TraceLog

(Global-declared in library GVL Tracing)

Provides methods for adding events to the trace log. Includes throttling mechanism to limit the number of events per PLC scan (default 100 per scan; see Parameters_Tracing).

Automatically collects context information which is appended to the JSON attribute of the event which is raised.

Example message

image

JSON attribute

image

Methods

Method Return Type Access Description
AddEntry null PUBLIC Adds a basic message to the trace log
AddEntryWithJson null PUBLIC Adds a message to the trace log and appends a given JSON object the event attributes

AddEntry()

1
2
3
4
5
6
METHOD PUBLIC AddEntry
VAR_INPUT
    Source  : T_MaxString;
    Message : T_MaxString;
    Flags   : UDINT;
END_VAR

Source should be used to specify where the trace message is coming from (FB name, etc.) This is handled automatically for you if using the wrapper methods in FB_BaseFB. Message is the the textual description of your event. Flags has no defined purpose but can be used, for instance, to signal to listeners that this event should be highlighted or handled in a different way.

AddEntryWithJson()

1
2
3
4
5
6
7
METHOD PUBLIC AddEntryWithJson
VAR_INPUT
    Source  : T_MaxString;
    Message : T_MaxString;
    Flags   : UDINT;
    Json    : T_MaxString;
END_VAR

Behaves exactly the same way as AddEntry() but takes an additional argument Json which will be automatically appended to the JSON attribute of the event (ExtendedInfo). This can be used to provide even more contextual information than is automatically provided.