TwinCat3 ST Ablaufsteuerung funktioniert nicht!

kon86

Level-1
Beiträge
22
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,
momentan habe ich ein beiläufiges Projekt in meiner Firma welches mit einer BECKHOFF CX8190 sowie einer Vielzahl von Digitalen Eingangsmodulen (EL1809) sowie Ausgangsmodulen (EL2809)
realisiert werden soll.
Ich selber hatte noch nie Erfahrungen mit diesem System sowie auch keine mit der Sprache "Strukturierter Text" (komme aus der C/C++ und Assembler- Sparte).

Nun gut jetzt zu dem groben Aufbau meines Modells,

Die Anlage soll quasi als Durchgangsprüfer fungieren, ein Signal soll über einen Ausgang in unserem Fall ein Modul vom Typ EL2809 rausgeschickt werden.
Der Ausgang hat eine zu prüfende Leitung vor sich durch die er 24V DC schickt, am anderen Ende dieser Leitung ist ein EL1809 verbaut.
Dieser soll Prüfen ob dort Spannung anliegt, bzw. ob die Leitung "Durchgang" hat.

Soweit so gut. Ich habe das Programm bis jetzt sauber aufgeteilt in Variablenlisten, Hauptprogramm(MAIN) sowie einzelne Programme welche als Methoden fungieren, diese rufe ich in der MAIN nacheinander auf. Alle Variablen wurden auch korrekt mit den jeweiligen Modulen (EL 1809 und EL 2809) verknüpft.

Mein Problem ist nun, ich würde gerne alle Leitungen einmal durchprüfen lassen und dies nacheinander. Wenn eine Leitung geprüft wurde soll diese für den nächsten Ablauf gesperrt werden(so dass diese nicht mehr angelaufen wird). Zudem soll das Ergebnis des Tests in einem String gespeichert werden.

Jedoch habe ich folgende Probleme:
- die Zählervariable welche die einzelnen IF -Schleifen "aktiviert" zählt nicht korrekt
- die PLC läuft immer wieder nacheinander den Ablauf durch
- die Prüfschritte werden nicht bis zum Ende durchgeführt

hier ein Auszug aus meinem Code:


Variablen:
Code:
PROGRAM DSP_Modul
VAR
    // delay für verzögerung 
    delay1 : TON;
    delay2 : TON;
    delay3 : TON;
    delay4 : TON;
    delay5 : TON;
    delay6 : TON;
    delay7 : TON;
    delay8 : TON;
    delay9 : TON;
    delay10 : TON;
    delay11 : TON;
    delay12 : TON;
    
    
    testStep: INT :=0; // Geändert
    
END_VAR

Ablauf:
Code:
 ;// Prüfungsabschnitt der einzelnen Stecker- PINS beginnt


testStep:= testStep +1; // Geändert

//Signal.In_DSP_KL30_UB := TRUE;
    testStep := 1; // Inkrementierung zum nächsten Testablauf
    //1:
    
        //CHANNEL 1
        //zu KL 31 GND 
    IF testStep = 1  THEN
        Signal.Out_DSP_A1     := TRUE; //CHANNEL 2 
        delay1(IN :=TRUE, PT :=T#1S); // DELAY 1 SEKUNDE
        
        IF delay2.Q THEN
            IF Signal.Out_DSP_A1 AND Signal.In_DSP_KL31_GND THEN
                StringList.Str_DSP_KL30_UB := 'A2 nach KL30 ERFOLGREICH';
            
            ELSIF Signal.Out_DSP_A1 AND NOT Signal.In_DSP_KL31_GND  THEN
                StringList.Str_DSP_KL30_UB := 'A2 nach KL30 FEHLGESCHLAGEN';
            END_IF
    
        
            Signal.Out_DSP_A1 := FALSE; // Ausgang sendet 0;
            delay2(IN := FALSE); //Delay FALSE
        
            testStep := testStep +1; // Inkrementierung zum nächsten Testablauf
            
            END_IF
     END_IF
    testStep := testStep +1; // Inkrementierung zum nächsten Testablauf
    Signal.Out_DSP_A1 := FALSE; // Ausgang sendet 0;
    
        //CHANNEL 2
        //zu KL 31 GND 
    IF testStep = 2  THEN
        Signal.Out_DSP_A2     := TRUE; //CHANNEL 2 
        delay1(IN :=TRUE, PT :=T#1S); // DELAY 1 SEKUNDE
        
        IF delay2.Q THEN
            IF Signal.Out_DSP_A2 AND Signal.In_DSP_KL30_UB THEN
                StringList.Str_DSP_KL30_UB := 'A2 nach KL30 ERFOLGREICH';
            
            ELSIF Signal.Out_DSP_A2 AND NOT Signal.In_DSP_KL30_UB  THEN
                StringList.Str_DSP_KL30_UB := 'A2 nach KL30 FEHLGESCHLAGEN';
            END_IF
            
        Signal.Out_DSP_A2 := FALSE; // Ausgang sendet 0;
        delay2(IN := FALSE);
        
        testStep := testStep +1; // Inkrementierung zum nächsten Testablauf
        
        END_IF
     END_IF
    
    
    
    //3:
    
    IF testStep = 3 THEN
        //CHANNEL 3
        // zu LS-Stecker 6
        Signal.Out_DSP_A7     := TRUE; //CHANNEL 5 x
        delay3(IN :=TRUE, PT :=T#1S); // DELAY 1 SEKUNDEN
        
        IF delay3.Q THEN
            IF Signal.Out_DSP_A7 AND Signal.In_DSP_LS_Stecker_6 THEN
                StringList.Str_DSP_A7 := 'A7 nach LS-Stecker 6 ERFOLGREICH';
            
            ELSIF Signal.Out_DSP_A7 AND NOT Signal.In_DSP_LS_Stecker_6 THEN
                StringList.Str_DSP_A7 := 'A2 nach LS-Stecker 6 FEHLGESCHLAGEN';
            END_IF
            
        Signal.Out_DSP_A7 := FALSE; // Ausgang sendet 0;
        delay3(IN := FALSE);
        
        testStep := testStep +1; // Inkrementierung zum nächsten Testablauf
        
        END_IF
    END_IF
    //4:
    IF testStep = 4 THEN
        //CHANNEL 4
        // zu LS-Stecker 4
         Signal.Out_DSP_A8     := TRUE; //CHANNEL 5 x
         delay4(IN :=TRUE, PT :=T#1S); // DELAY 1 SEKUNDE
            
         IF delay4.Q THEN
            IF Signal.Out_DSP_A8 AND Signal.In_DSP_LS_Stecker_4 THEN
                StringList.Str_DSP_A8 := 'A8 nach LS-Stecker 4 ERFOLGREICH';
                
            ELSIF Signal.Out_DSP_A8 AND NOT Signal.In_DSP_LS_Stecker_4 THEN
                StringList.Str_DSP_A8 := 'A8 nach LS-Stecker 4 FEHLGESCHLAGEN';
            END_IF
                
        Signal.Out_DSP_A8 := FALSE; // Ausgang sendet 0;
        delay4(IN := FALSE);
        testStep := testStep +1; // Inkrementierung zum nächsten Testablauf 
        END_IF
    END_IF
    //5:

Ich hoffe ihr habt einen Tipp oder eine Idee für mich um dieses Problem zu lösen.



Viele Grüße

Kon
 
Zuletzt bearbeitet:
Hallo,

für mich sieht das so aus, als ob du unter deinem ersten Teststep deinen Schrittzähler bereits um 1 erhöhst und das ohne eine Bedigung.

Als Tipp würde ich dir empfehlen das Ganze über einen Case zu lösen und die zyklischen Aufrufe deiner Timer ausserhalb der Schrittkette zu platzieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Erstmal würde ich anstatt If-Abfragen ein CASE verwenden, aber das ist Geschmakssache. Dann, wie soll da irgendwas gehen? Du setzt in jedem Zyklus den Schrittzähler bedingungslos auf 0 und dann, wie von snf schon bemerkt auf 1. Er fängt also in jedem Zyklus wieder von vorne an.
 
Du schreibst deinen Case mit Testschritten:

Case Teststep of:
1: ....
2: ....

End_Case


// cyclic calls
delay1(PT:= t#1s);
delay2(PT:= ...);
usw.

Innerhalb deiner Schritte setzt du dann die Eingänge delay1.in := true bzw. := false und frägst die Ausgänge über delay1.q = true ab.
 
Okay das Modell mit dem Case probiere ich gerade,

Und ja ich habe es im Code oben soeben korrigiert
Du setzt in jedem Zyklus den Schrittzähler bedingungslos auf 0 und dann, wie von snf schon bemerkt auf 1. Er fängt also in jedem Zyklus wieder von vorne an.
danke habe es beim probieren wohl geändert und übersehen.
 
1. Dir ist bewußt, das eine SPS, anders als C++ oder anderer code immer zyjklisch arbeitet? D,h., ist das Programm am Ende angelangt, beginnt es wieder am Anfang.
2. Erhöhen der Step-Var immer nur an eriner Stelle, am besten in der I...then abfrage und zwar, wenn das Ergebnis vorliegt. Du hast vor und nach dem ersten Step die Erhöhung auch außerhalb von if...then stehen (wohl auch ein Relikt)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So Ich weis nicht ganz ob ich das mit den Delays so richtig verstanden haben (musste nochmal die Doku bemühen) aber ich habe jetzt folgenden Ablauf der erstmal so abläuft wie ich es haben will!

Hier der Code:
Code:
PROGRAM DSP_ModulVAR
    // delay für verzögerung 
    delay1 : TON;
    delay2 : TON;
    delay3 : TON;
    delay4 : TON;
    delay5 : TON;
    delay6 : TON;
    delay7 : TON;
    delay8 : TON;
    delay9 : TON;
    delay10 : TON;
    delay11 : TON;
    delay12 : TON;
    
    
    testStep: INT :=1; // geht ab 1 los
    


END_VAR

Und der Haupt- Code
Code:
CASE testStep OF 

    // 1. Ablauf
    1: Signal.Out_DSP_A1     := TRUE; //CHANNEL 1 , Ausgang sendet 1
        delay1(IN :=TRUE, PT :=T#1S); // DELAY 1 SEKUNDE
        
        IF delay1.Q THEN
            IF Signal.Out_DSP_A1 AND Signal.In_DSP_KL31_GND THEN
                StringList.Str_DSP_KL30_UB := 'A2 nach KL30 ERFOLGREICH';
            
            ELSIF Signal.Out_DSP_A1 AND NOT Signal.In_DSP_KL31_GND  THEN
                StringList.Str_DSP_KL30_UB := 'A2 nach KL30 FEHLGESCHLAGEN';
            END_IF
    
        
            Signal.Out_DSP_A1 := FALSE; // Ausgang sendet 0
            delay1(IN := FALSE); //Delay FALSE
        
            testStep := testStep +1; // Inkrementierung zum nächsten Testablauf
        END_IF
        
        
    // 2. Ablauf    
     2:    Signal.Out_DSP_A2     := TRUE; //CHANNEL 2 , Ausgang sendet 1 
            delay2(IN :=TRUE, PT :=T#1S); // DELAY 1 SEKUNDE
            
            IF delay2.Q THEN
                IF Signal.Out_DSP_A2 AND Signal.In_DSP_KL30_UB THEN
                    StringList.Str_DSP_KL30_UB := 'A2 nach KL30 ERFOLGREICH';
                
                ELSIF Signal.Out_DSP_A2 AND NOT Signal.In_DSP_KL30_UB  THEN
                    StringList.Str_DSP_KL30_UB := 'A2 nach KL30 FEHLGESCHLAGEN';
                END_IF
            
                Signal.Out_DSP_A2 := FALSE; // Ausgang sendet 0;
                delay2(IN := FALSE);
            
                testStep := testStep +1;
            END_IF     
    
    // 3. Ablauf
    3: Signal.Out_DSP_A7     := TRUE; //CHANNEL 5 x
        delay3(IN :=TRUE, PT :=T#1S); // DELAY 1 SEKUNDEN
        
        IF delay3.Q THEN
            IF Signal.Out_DSP_A7 AND Signal.In_DSP_LS_Stecker_6 THEN
                StringList.Str_DSP_A7 := 'A7 nach LS-Stecker 6 ERFOLGREICH';
            
            ELSIF Signal.Out_DSP_A7 AND NOT Signal.In_DSP_LS_Stecker_6 THEN
                StringList.Str_DSP_A7 := 'A2 nach LS-Stecker 6 FEHLGESCHLAGEN';
            END_IF
        
            
            Signal.Out_DSP_A7 := FALSE; // Ausgang sendet 0;
            delay3(IN := FALSE);
            
            testStep := testStep +1; // Inkrementierung zum nächsten Testablauf
        END_IF


END_CASE
 
Hey Ralle, ja das mit dem Zyklischen ist mir bewusst (geworden :D), ich arbeite jetzt zum ersten mal damit. Leider ist der Kollege der sich damit auskannte nicht mehr in der Firma.
Das bereitet mir echt Kopfschmerzen (weil nicht gewöhnt aus C und CPP) :ROFLMAO:

ich habe es nun so gelöst das ich in der Deklaration sage die Var :=1
und dann im Ablauf einfach erhöhe.

Mir ist bewusst das dies warscheinlich nicht die feine englische Art ist, aber es funktioniert für meine Zwecke.:rolleyes:
 
Du kannst dir auch ein Startsignal definieren, z.B. eine Bool eines Eingangs.
Wenn der Eingang True wird, bildest du eine Flanke und mit der Flanke setzt du dann die Step-Var auf 1.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja das wäre eine Idee, ich wollte eh noch über die Visualization oder Über einen externen Taster (realen) den Ablauf Starten. Denn jedesmal in die TwinCat Software zu gehen und dies einzeln zu Triggern ist nicht so schön.
 
Geht es darum, "konfektionierte" Kabel (Kabel, die an einem Ende oder wahrscheinlicher an beiden Enden mit SteckVerbindungen versehen sind) zu prüfen?
Ich finde es eher "sparsam", nur zu prüfen, ob die erwarteten Verbindungen bestehen und dabei nicht hinzuschauen, welcher Eingang bzw. welche Eingänge einen Durchgang melden.
Ungewollte Verbindungen zwischen einzelnen Leitern werden nicht erkannt. Auch, wenn Leiter vertauscht sind, wird nicht festgehalten, welche.
Gerade, wenn der Prüfling nicht OK ist, wäre es zweckmässig, den/die Fehler aussagekräftig zu dokumentieren - oder soll der Reparateur den Prüfling dann "zu Fuss" durchmessen?
 
Nicht ganz, der Prüfling ist ein kompletter Einschub bzw. Rack. Es werden Kabel genutzt aber die sind Marke Eigenbau.

Zum Thema "sparsam" jeder Aus und Eingang werden jeweilig einzeln geprüft es wird immer nur ein Ausgang geschalten. Sobald er die IF- Schleife verlässt wird er "verblockt" mit der VAR testStep.
Zum Thema Doku, ersichtlich ist es doch in meinem Code das Strings für "ERFOLG" oder "MISSERFOLG" beschrieben werden. Der jeweilige Prüfpfad wird doch in der String-Var gespeichert.

Das Projekt befindet sich am Anfang und letztendlich wird keine Person mehr nötig sein um dies zu testen, bis auf das anschlißen natürlich.
 
Zurück
Oben