Endlosschleife in Case Anweisung in Methode

Pneumatik

Level-2
Beiträge
46
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Endlosschleife in Case Anweisung in einer Methode

Hallo zusammen,

ich programmiere immernoch mit einer Beckhoff CX Steuerung und Twincat3.

Alles was ich mache habe ich durch anlesen und testen gelernt. Bei meinem jetzigen Problem habe ich mal wieder das Gefühl etwas nicht ganz richtig verstanden zu haben.
Die Case Anweisung wird nicht so zurückgesetzt wie ich vermuten würde.

Sollverhalten:
Nach Initialisierung und aktivieren von "bCloseGripper" soll die Methode "Close" einmal durchlaufen werden. Nach Abschluss in Schritt 999 wird der Rückgabewert Close=1 gesetzt und deaktiviert einen erneuten Aufruf der Methode "Close".

Istverhalten:
nSwitchClose geht alle Schritte von 0,10,15,20,30,999 nacheinander in einer Endlosschleife durch.

Frage:
Wie kann es sein dass, wenn der nSwitchClose definitiv auch den Wert 999 annimmt,der Rückgabewert Close das erneute Ausführen der Methode nicht verhindert. Übersehe ich etwas bei der zyklischen Abarbeitung? (Der Code ist teilweise in den Schritten 10-30 gekürzt)


Methodenaufruf zum testen in der Main:
Code:
IF bInitiated AND bCloseGripper THEN        
    fbGripperSMC.Close();
    bCloseGripper:=NOT (fbGripperSMC.Close(Close=>Closed)=1);
END_IF

Die Methoden "Close"
Code:
CASE nSwitchClose  OF    
    0:    
    bStart:=TRUE;
      bError:=FALSE;        
    IF bStart AND NOT bBusy THEN
        bStart                := FALSE;
        bBusy                 := TRUE;
        bError                := FALSE;
        nErrId                := 0;
        nSwitchClose        := 10;
    ELSIF (bStart AND  bBusy) THEN
         bError        := TRUE;
        //SubModul is in use
        nErrId        := 1011000;
    ELSE
        //unkown error
        bError        := TRUE;
    END_IF

    10:
    //If Initialised start movement, else initialise
    OSMC_output.9:=TRUE; //    Servo Motor an
    OSMC_output.0:=1;//nWert.0; Auswahl der Bewegungsdaten
    OSMC_output.1:=1;//nWert.1; Auswahl der Bewegungsdaten
    OSMC_output.2:=0;//nWert.2; Auswahl der Bewegungsdaten
    OSMC_output.3:=1;//nWert.3; Auswahl der Bewegungsdaten
    nSwitchOpen:=15;
    
    15:
    fbTONClose1(PT:=T#1S);
    fbTONClose1( IN:= NOT fbTONClose1.Q);
    IF fbTONClose1.Q THEN
        OSMC_output.10:=TRUE; // Auszuwählende Step einscannen und Bewegung starten
        nSwitchOpen:=20;
    END_IF;


    
    20: 
    IF ((NOT ISMC_inputPort.8) AND ( DINT_TO_REAL(ABS(ISMC_CurrentPos-ISMC_TargetPos))<nErrorMargin)) THEN //Inputport.8 = BUSY 
        nSwitchClose:=30;
    END_IF
    
    
    30:
    IF ISMC_inputPort.8=FALSE THEN // If not busy (=movement finished) go to Step 999
        nSwitchClose:=999;
        OSMC_output.9:=FALSE; //Motor aus
        OSMC_output.10:=FALSE;//Scan nach neuen Bewegungsbefehlen aus
    END_IF
    
    999:
    bBusy                     := FALSE;
    bError                    := FALSE;
    nErrId                    := 1;
    Close                    := 1;
    nSwitchClose            := 0;
END_CASE;

Vielen Dank!
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Dein Problem sind die Überlegungen deiner Schrittkette und deren Weiterschaltbedingungen.
Beispiel :
Code:
CASE nSwitchClose  OF    
    0:    
    bStart:=TRUE; [COLOR=#ff0000][B] // <- hier setzt du bStart[/B][/COLOR]
      bError:=FALSE;        
    IF bStart AND NOT bBusy THEN [B][COLOR=#ff0000] // <- dadurch ist diese Bedingung dann auch sofort erfüllt[/COLOR][/B]
        bStart                := FALSE;
        bBusy                 := TRUE;
        bError                := FALSE;
        nErrId                := 0;
        nSwitchClose        := 10; [COLOR=#ff0000][B]// und du setzt dadurch dann auch gleich Schritt=10[/B][/COLOR]

in Schritt 10 gehst du sofort nach Schritt 15
in Schritt 15 wird der Timer bedingt bearbeitet
usw.

Gruß
Larry
 
Daß die Schrittkette sich endlos selber neu starten kann habe ich auch sofort gesehen, doch eigentlich sollte nach Wunsch des TE die Close-Methode nach dem Schritt 999 durch das "Close:=1" gar nicht wieder aufgerufen werden, so daß sie sich nicht wiederholen kann. Allerdings ruft er das Close() zweimal auf und beim ersten mal ignoriert er den Rückgabewert - das Programm bekommt also gar nicht mit, daß nach Schritt 999 Close=1 ist und beim zweiten Aufruf startet sich die Schrittkette wieder selber - allerdings sehe ich nicht, wo da Close wieder auf 0 gesetzt wird?

Harald
 
@_Eddi_: Na klar! Danke :). Fühle mich gerade etwas bescheuert. Ich habe die Methode bereits xMal umgeschrieben und mehrere Stunden in der Methode nach Fehlern gesucht um diese scheinbar willkürlichen Abarbeitungen zu verstehen.

@Larry Laffer: bStart wird später von einem anderen Baustein gesteuert und nur bereits als Platzhalter integriert. Das die Schrittkette beim start der Methode aktuell direkt gestartet wird ist gewollt. Aber danke für den Hinweis.

Ich merke mal wieder, dass es äußerst ineffektiv ist, sich alleine ohne jemanden der mindestens die gleiche Erfahrung hat in eine programmiertechnische Aufgabe einzuarbeiten. Dank euch geht dann aber doch ;). Nochmals Danke an alle!
 
Zurück
Oben