Central operating function

A central operating function, such as the incremental encoder of the CP2219-1025-0030 BlowMolding Panel PC, can always be connected to exactly one task. The ManualOperation Control in the HMI allows you to select this central operating function. On the PLC side, it must also be defined how the interaction should take place logically.

1. Implement the interfaces I_AdaptableSeqExt and an interface derived from I_RuntimeInterface in a class (here FB_Sample as an example). This class represents the location where you want to program the manual function.
FUNCTION_BLOCK FB_Sample IMPLEMENTS I_AdaptableSeqExt, I_OneTaskInterface
2. Create an instance of FB_ManualWheels in the FB_Sample.
3. Optional (if not already available): Also create general manual functions for axes, for example.
VAR
    fbManualWheel:      FB_ManualWheel;

    fbManual1Hmi:       FB_ManualFunctionHmi;
    fbManual1:          FB_ManualBaseWork;
    fbManual2Hmi:       FB_ManualFunctionHmi;
    fbManual2:          FB_ManualBaseWork;
END_VAR
4. Instantiate your class (here still FB_Sample).
5. Optional (if not already present): Also create instances of type FB_CP22xx_1025 and FB_CP22xx_1025Hmi for integration of the panel PC I/O.
VAR
    fbSample:           FB_Sample;

    fbPanel:            FB_CP22xx_1025;
    fbPanelHmi:         FB_CP22xx_1025Hmi;
END_VAR
6. Append the instance of FB_Sample to the runtime.
7. Optional (if not already present): Also append the instances of the panels to the runtime.
fbRuntime.Append(fbSample, 0);
fbRuntime.Append(fbPanel, fbPanelHmi);
8. Initialize manual functions (including those of the wheel) in the Init()-method of FB_Sample.
9. Then assign the class FB_Sample to the external implementation of the wheel manual function.
METHOD Init : HRESULT


F_SucceededHr(fbManual1.Init(fbAxis1, fbManual1Hmi), Init);
F_SucceededHr(fbManual2.Init(fbAxis2, fbManual2Hmi), Init);
F_SucceededHr(fbManualWheel.Init(fbPanel.Wheel), Init);

fbManualWheel.ExternalState := THIS^;
10. Insert the cycle call of the manual functions into a Cyclic()-method of FB_Sample.
11. Also specify when the manual function should be selectable.
METHOD Cyclic


fbManual.Enable1 := bManualMode OR bSetupMode
fbManual.Enable2 := bManualMode OR bSetupMode
fbManualWheel.Enable := bManualMode OR bSetupMode;

fbManualWheel.Cyclic();
fbManual1.Cyclic();
fbManual2.Cyclic();
12. Add a new method called ExtAdaptSeq() to the class FB_Sample so that it can be called from fbManualWheel.
METHOD ExtAdaptSeq
VAR_INPUT
    bInit:         BOOL;                    // TRUE, if the external states should insert themself to iMaster
    iMaster:       I_AdaptableSeqMaster;    // Interface on the state master
END_VAR
13. In this new method, define an initialization with the transfer of the manual functions that are to be selectable from the wheel.
IF bInit THEN
    fbManualWheel.AppendManual(fbManual1);
    fbManualWheel.AppendManual(fbManual2);
ELSE
    // Wheel control logic will be placed here
END_IF
14. Program the logic of your manual function.
The following sample implements a Jog command with control of the Override via the position of the wheel.
METHOD ExtAdaptSeq
VAR_INPUT
    bInit:          BOOL;                    // TRUE, if the external states should insert themself to iMaster
    iMaster:        I_AdaptableSeqMaster;    // Interface on the state master
END_VAR
VAR
    iqAxis:         I_Axis; 
    fOverride:      LREAL; 
    iSeq:           I_AdaptableSeqItf;
END_VAR
VAR_INST    
    iqAxisLast:     I_Axis;
    fbTrigCmd:      FB_Trigger;
END_VAR


IF bInit THEN
    // ...
ELSE
    // fetch selected manual function
    IF fbManual1.State.IsActive THEN
        iqAxis := fbAxis1; 
        iSeq := fbManual1.State;
    ELSIF fbManual2.State.IsActive THEN
        iqAxis := fbAxis2; 
        iSeq := fbManual2.State; 
    ELSE
        iqAxis := 0;
    END_IF
    
    // trigger on selecting and changing
    fbTrigCmd.CLK := iqAxis <> 0 AND iqAxis = iqAxisLast;
    fbTrigCmd.Cyclic();
    
    // on selecting a function
    IF fbTrigCmd.RQ THEN
        // setup wheel behaviour, see FB_CP22xx_Wheel
        fbPanel.Wheel.Leds.GuidingMid := 0;
        fbPanel.Wheel.Leds.GuidingMidWindow := 1.0;
        fbPanel.Wheel.Leds.GuidingMax := 100.0;
        fbPanel.Wheel.Leds.GuidingMin := -100.0;
        fbPanel.Wheel.Leds.FillMode := TRUE;
        fbPanel.Wheel.Enc.LimitOverflow := TRUE;
        
        fbPanel.Wheel.Enc.PositionScale := 2;
        fbPanel.Wheel.Enc.SetZero();
        
        fbPanelHmi.WheelClaimed := TRUE;
        
    // on active usage
    ELSIF fbTrigCmd.CLK THEN
        
        // stop axis on wheel pressing
        IF fbPanel.Wheel.Press.In THEN
            fbPanel.Wheel.Enc.SetZero();
        END_IF
        
        // hold wheel --> deselect manual function
        IF fbPanel.Wheel.Press.Q THEN
            iSeq.Jump(iMaster.Idx(2));    // Idle, see FB_ManualWheel.States()
            iSeq.Done := TRUE;
            RETURN;
        END_IF
        
        // avoid commanding opposite direction before axis has stopped
        IF iqAxis.Axis.Jog.IsJoggingM THEN
            fbPanel.Wheel.Enc.PositionMax := 0;
        ELSIF iqAxis.Axis.Jog.IsJoggingP THEN
            fbPannel.Wheel.Enc.PositionMin := 0;
        ELSIF NOT iqAxis.Axis.Jog.IsStopping AND fbPanel.Wheel.Enc.Velocity = 0 THEN
            fbPanel.Wheel.Enc.PositionMax := 100.0;
            fbPanel.Wheel.Enc.PositionMin := -100.0;
        END_IF
        
        // apply override
        fOverride := LIMIT(-100.0, fbPanel.Wheel.Enc.Position, 100.0);
        fbPanel.Wheel.Leds.GuidingValue := fOverride;
        iqAxis.Axis.Power.Override := ABS(fOverride);

        // determine direction
        IF fOverride > 0 THEN
            iqAxis.JogPositive(TRUE);
        ELSIF fOverride < 0 THEN
            iqAxis.JogNegative(TRUE);
        ELSE
            iqAxis.JogNegative(FALSE);
            iqAxis.JogPositive(FALSE);
        END_IF
        
    // on leaving the selection
    ELSIF fbTrigCmd.FQ THEN
        iqAxisLast.Axis.Power.Override := 100.0;
        iqAxisLast.JogNegative(FALSE);
        iqAxisLast.JogPositive(FALSE);

        fbPanelHmi.WheelClaimed := FALSE;

        fbPanel.Wheel.Leds.FillMode := FALSE;
        fbPanel.Wheel.Leds.GuidingValue := -1000;
    END_IF
    
    iqAxisLast := iqAxis;
END_IF