Zentrale Bedienfunktion

Eine zentrale Bedienfunktion, wie beispielsweise der Inkremental-Geber des CP2219-1025-0030 BlowMolding-Panel-PCs, kann immer mit genau einer Aufgabe verbunden werden. Hierfür bietet das ManualOperation Control im HMI die Anwahl dieser zentralen Bedienfunktion. Auf Seite der PLC muss zusätzlich definiert werden, wie die Interaktion logisch stattfinden soll.

1. Implementieren Sie die Schnittstellen I_AdaptableSeqExt und eine von I_RuntimeInterface abgeleitete Schnittstelle in einer Klasse (hier beispielhaft FB_Sample). Diese Klasse stellt den Ort dar, an dem Sie die Handfunktion programmieren möchten.
FUNCTION_BLOCK FB_Sample IMPLEMENTS I_AdaptableSeqExt, I_OneTaskInterface
2. Legen Sie im FB_Sample eine Instanz des FB_ManualWheels an.
3. Optional (sofern nicht bereits vorhanden): Legen Sie ebenfalls allgemeine Handfunktionen für z.B. Achsen an.
VAR
    fbManualWheel:      FB_ManualWheel;

    fbManual1Hmi:       FB_ManualFunctionHmi;
    fbManual1:          FB_ManualBaseWork;
    fbManual2Hmi:       FB_ManualFunctionHmi;
    fbManual2:          FB_ManualBaseWork;
END_VAR
4. Instanziieren Sie ihre Klasse (hier weiterhin FB_Sample).
5. Optional (sofern nicht bereits vorhanden): Legen Sie ebenfalls Instanzen vom Typ FB_CP22xx_1025 und FB_CP22xx_1025Hmi zur Anbindung des Panel-PC-IOs an.
VAR
    fbSample:           FB_Sample;

    fbPanel:            FB_CP22xx_1025;
    fbPanelHmi:         FB_CP22xx_1025Hmi;
END_VAR
6. Hängen Sie die Instanz des FB_Sample an die Runtime an.
7. Optional (sofern nicht bereits vorhanden): Hängen Sie ebenfalls die Instanzen des Panels an die Runtime an.
fbRuntime.Append(fbSample, 0);
fbRuntime.Append(fbPanel, fbPanelHmi);
8. Initialisieren Sie Handfunktionen (inkl. der des Rades) in der Init()-Methode des FB_Sample.
9. Weisen Sie anschließend die Klasse FB_Sample der externen Implementierung der Rad-Handfunktion zu.
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. Fügen Sie den Zyklusaufruf der Handfunktionen in eine Cyclic()-Methode des FB_Sample ein.
11. Legen Sie zusätzlich fest, wann die Handfunktion anwählbar sein soll.
METHOD Cyclic


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

fbManualWheel.Cyclic();
fbManual1.Cyclic();
fbManual2.Cyclic();
12. Fügen Sie eine neue Methode namens ExtAdaptSeq() der Klasse FB_Sample hinzu, damit sie vom fbManualWheel aufgerufen werden kann.
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. Definieren Sie in dieser neuen Methode eine Initialisierung mit der Übergabe der Handfunktionen die vom Rad anwählbar sein sollen.
IF bInit THEN
    fbManualWheel.AppendManual(fbManual1);
    fbManualWheel.AppendManual(fbManual2);
ELSE
    // Wheel control logic will be placed here
END_IF
14. Programmieren Sie die Logik ihrer Handfunktion.
Das folgende Beispiel implementiert einen Jog-Befehl mit Steuerung des Override über die Stellung des Rades.
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