TIA Zeitverzögerung einer Schrittkette unter Verwendung von case in SCL

Marros93

Level-1
Beiträge
3
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Forum,

dies ist mein erster Beitrag hier und ich hoffe ihr könnt mir weiterhelfen. Ich habe zwar schon Zeitverzögerung in SCL gefunden und Schrittkette mit case unter SCL. Aber beides in Kombination noch nicht. Deshalb meine Frage:

Ich will eine Schrittkette in SCL mit der Case-Anweisung programmieren und jeden Schritt verzögern. Mein Code funktioniert im ersten Durchlauf wunderbar aber im zweiten Durchlauf springt er ohne Verzögerung weiter, weil er laut meiner Analyse den Timer nicht zurücksetzt.

Code:
    CASE #SelectStep OF
        0:
            #ActualStep[1] := TRUE; //Setzen des Timers des aktuellen Schritts
            #ActualStep[3] := FALSE; //Rücksetzen des Timers des vorherigen Schritts
            #StepNumber := 1;
            #StepText := 1;
            #LocalTimer[1](IN := #ActualStep[1],
                           PT := #StepTime,
                           Q => #SelectNextStep[1],
                           ET => #tempStepTime[1]);
            #actualStepTime := #tempStepTime[1];
            IF #SelectNextStep[1] THEN //Weiterschaltbedingung
                #SelectStep := #SelectStep + 1;
            END_IF;
           
            // Statement section case 1
            ;
        1:
            #ActualStep[2] := TRUE; //Setzen des Timers des aktuellen Schritts
            #ActualStep[1] := FALSE; //Rücksetzen des Timers des vorherigen Schritts
            #StepNumber := 2;
            #StepText := 2;
            #LocalTimer[2](IN := #ActualStep[2],
                           PT := #StepTime,
                           Q => #SelectNextStep[2],
                           ET => #tempStepTime[2]);
            #actualStepTime := #tempStepTime[2];
            IF #SelectNextStep[2] THEN //Weiterschaltbedinugng
                #SelectStep := #SelectStep + 1;
            END_IF;
            // Statement section case 2
            ;
        2:
            #ActualStep[3] := TRUE; //Setzen des Timers des aktuellen Schritts
            #ActualStep[2] := FALSE; //Rücksetzen des Timers des vorherigen Schritts
            #StepNumber := 3;
            #StepText :=3;
            #LocalTimer[3](IN := #ActualStep[3],
                           PT := #StepTime,
                           Q => #SelectNextStep[3],
                           ET => #tempStepTime[3]);
            #actualStepTime := #tempStepTime[3];
            IF #SelectNextStep[3] THEN //Weiterschaltbedingung
                #SelectStep := 0;
            END_IF;
            // Statement section case 3
            ;
END_CASE

Ich habe auch schon versucht am Ende der ersten Case-Anweisung den Timer zurückzusetzen doch das funktioniert auch nicht. Beispiel fogt hier:
Code:
    CASE #SelectStep OF
        0:
            #ActualStep[1] := TRUE; //Setzen des Timers des aktuellen Schritts
            #ActualStep[3] := FALSE; //Rücksetzen des Timers des vorherigen Schritts
            #StepNumber := 1;
            #StepText := 1;
            #LocalTimer[1](IN := #ActualStep[1],
                           PT := #StepTime,
                           Q => #SelectNextStep[1],
                           ET => #tempStepTime[1]);
            #actualStepTime := #tempStepTime[1];
            IF #SelectNextStep[1] THEN //Weiterschaltbedingung
                #SelectStep := #SelectStep + 1;
            END_IF;
           #ActualStep[1] := FALSE; //Rücksetzen des Timers 
            // Statement section case 1
            ;
 
Programmiere Einen Timer ausserhalb deiner Case Anweisung und diesen Timer triggerst du immer dann neu wenn sich deine Schrittnummer ändert. Und in den Schritten dann als Transition
Code:
IF CurrentStepTime > StepTime THEN
...
 
Du musst das Programm so umbauen daß die Timer immer aufgerufen werden und nicht nur bedingt im Schritt.

Was für eine CPU hast Du? Bei den S7-1x00 CPU verhalten sich die Timer anders als bei S7-300/400

Hrald
 
Vielen Dank für die Antworten.

Dass ich die Timer außerhalb aufrufe hatte ich auch probiert, doch es hat nicht funktioniert. Allerdings hatte ich die Timer als Temp deklariert...

Jetzt rufe ich die Timer außerhalb auf und sie sind als static deklariert und es funktioniert wie erhofft und gewollt.

Die verwendete CPU ist übrigens eine S7-1516.

Vielen Dank für eure schnelle Hilfe :D
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
Das Problem ist, dass er den Timer nur ausführt wenn er in dem Schritt ist. Sowas funktioniert nicht.
Entweder du baust dir deinen Timer selbst durch einen Zähler und z.B. SPS Takt (da kannst du ja bis 100ms runtergehen das sollte für eine Schrittkettenverzögerung genau genug sein).

Code:
#"100ms_fm"(CLK:="Clock_10Hz");
#Schrittwechsel(CLK := #step <> #Step_alt);


IF #Schrittwechsel.Q THEN
    #Schrittzeit := 0;
END_IF;


IF #"100ms_fm".Q THEN
            #Schrittzeit += 1;
        END_IF;
        
CASE #step OF
        
    1:
        // Aktion
        
        // Weiterschaltbedingung
        IF #Schrittzeit = 150 THEN  // in diesem fall 15 sekunden
            #step += 1;
        END_IF;
        
    2:
        // Aktion
        
        // Weiterschaltbedingung
        IF #Schrittzeit = 230 THEN  // in diesem fall 23 sekunden
            #step += 1;
        END_IF;
    3:
        // Aktion
        
        // Weiterschaltbedingung
        IF #Schrittzeit = 55 THEN  // in diesem fall 5,5 sekunden
            #step += 1;
        END_IF;
        
END_CASE;


#Step_alt := #step;

oder du rufst ihn im Vorfeld auf.

Als weitere frage:
Warum beschreibst du in jeder Case den Schrittzähler StepNumber?
du hast doch durch die Caseanwendung schon den Schrittzähler select_step?

grüße

Balu
 
Anhand den Variablen StepNumber und StepText soll später aus einem ini-File der Schrittext gelesen werden. Deshalb definiere ich zusätzlich StepNumber. Vermutlich geht dasselbe auch mit der Variable SelectStep, da hast du Recht.
 
Wir machen das mit den Schrittketten so, dass beim aktivieren vom Schritt der Timer zurückgesetzt wird mit RESET_TIMER(). So genügt auch 1 Timer, da ja immer nur 1 Schritt aktiv ist.

Code:
    105:
        // -------------------------------------------------------------
        // Verz. nach Greifer offen
        // -------------------------------------------------------------        
        // Schritt wurde aktiviert
        IF #s_xFP_neue_Nr THEN
            // Schritt-Timer reseten
            RESET_TIMER(#s_TON_Step);
        END_IF;
        
        // Wartezeit starten
        #s_TON_Step(IN := TRUE,
                    PT := #c_tVerz_nach_Greifer_offen);
        
        // Warten bis der Greifer geschlossen ist
        IF #s_TON_Step.Q OR "DB_WS_Ctrl".Schrittablauf.Steuerung.cmd_Einzelschritt THEN
            // Hub nach oben fahren
            "DB_WS_Ctrl".Schrittablauf.Schrittnr.akt := 110;
        END_IF;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dein Problem ist, der IEC Timer sieht am Start-Eingang durch diese Art der Programmierung keinen 1->0->1 Durchgang.
Bei ersten Aufruf, erkennt dieser innerhalb der SK den Wechsel von 0->1 ...
Da aber nun bei Aktivierung von den weiteren Schritten keinen 1-> 0 Wechsle erkannt wird und bei erneuten Durchlauf der SK in dem Schritt wo dieser Timer Programmiert ist auch kein 0->1 Wechsel kommt, sieht der Timer dies so als ob dieser immer noch aktiv wäre und der Timer abgelaufen wäre und somit bleibt der Ausgang Q "high" ...

Möglichkeit wäre, mit dem Q den nächsten Schrittmerker zwar zu setzen aber dafür sorgen das der aktuelle Schritt nochmals mit 0 am Starteingang durch rennt und dann weiter schalten ...
 
Wir machen das mit den Schrittketten so, dass beim aktivieren vom Schritt der Timer zurückgesetzt wird mit RESET_TIMER(). So genügt auch 1 Timer, da ja immer nur 1 Schritt aktiv ist.

Code:
    105:
        // -------------------------------------------------------------
        // Verz. nach Greifer offen
        // -------------------------------------------------------------        
        // Schritt wurde aktiviert
        IF #s_xFP_neue_Nr THEN
            // Schritt-Timer reseten
            RESET_TIMER(#s_TON_Step);
        END_IF;
        
        // Wartezeit starten
        #s_TON_Step(IN := TRUE,
                    PT := #c_tVerz_nach_Greifer_offen);
        
        // Warten bis der Greifer geschlossen ist
        IF #s_TON_Step.Q OR "DB_WS_Ctrl".Schrittablauf.Steuerung.cmd_Einzelschritt THEN
            // Hub nach oben fahren
            "DB_WS_Ctrl".Schrittablauf.Schrittnr.akt := 110;
        END_IF;

Sorry für meine Kommentare, die eher weniger was mit dem Topic zu tun haben, aber warum programmiert man Verfahrensabläufe in SCL ?
 
aber warum programmiert man Verfahrensabläufe in SCL ?
Weil manche CPUen, wie z.B. die S7-1200, nur eine begrenzte Auswahl an Programmiervarianten zur Verfügung stellen.
Weil man vielleicht SCL am sichersten beherrscht.
Weil man nicht immer gleich mit Kanonen auf Spatzen schießen möchte.

Wird wohl die vielfältigsten Gründe dafür geben, wenn man mal über den eigenen Tellerrand schaut.
;)
 
@Draco:
Warum denn nicht ? Gerade mit CASE hat man eine gute Möglichkeit, eine Schrittkette in SCL / ST elegant umzusetzen ... UND ... man kann auch recht gut erkennen, wo die Schrittkette aktuell steht ...

Gruß
Larry

Schrittketten die du einmal umsetzt und nie wieder antastest, wie zB eine StateMachine. Aber im vorliegenden Beispiel lese ich was vom Greifer und Hubbewegungen. Soetwas in SCL umzusetzen zeugt von Unprofessionalität oder massiven Versuchen, 3,50€ an der Hardware zu sparen, weswegen man dann eine 1200 anstatt einer 1500 einkauft - was schlußendlich auf dasselbe hinausläuft.

wenn man mal über den eigenen Tellerrand schaut
... entdeckt man, daß solche Anwendungen bei sachgemäßer Umsetzung mit GRAPH und PRODIAG-Mitteln abgebildet werden. Ich hatte mal ne Anfrage, eine Verpackungsmaschine glaube ich aus 5 oder 6 Sektionen zu optimieren, die von der Taktzeit nicht im Soll lag, und ständig irgendwo in den Schritten mit unmotivierten Fehlermeldungen ausstieg bzw. sich verlaufen wollte. Der Programmierer hatte zwar eine 1511 zuer Verfügung, hat aber alle 6 Sektionen als Schrittketten in SCL programmiert. Die Schrittketten enthielten wohl auch Alternativ- und Parallelzweige und jede so an die 60 Schritte. Ich habe damals gesagt, daß ich diesen Job nur unter der Voraussetzung machen werde, daß das gesamte Program nach TRANSLINE-Standard umgebaut wird.
 
Zuletzt bearbeitet:
Können Sie mich bitte aufklären warum das in SCL nicht von Professionalität zeugt?

Ich kann den Grund nennen warum ich sowas nicht in SCL programmiere:
Alles was sich bewegt wird irgendwann kaputt ... War schon immer so und wird auch so bleiben.
Daher schreibe ich Programmteile an denen mal ein normaler Instandhalter Fehlersuche betreiben muß eben in KOP/FUP oder Graph.
Wenn mal die meisten Instandhalter SCL beherrschen, dann siehts vielleicht anders aus ...

Gruß
Blockmove
 
Daher schreibe ich Programmteile an denen mal ein normaler Instandhalter Fehlersuche betreiben muß eben in KOP/FUP oder Graph.
Wenn mal die meisten Instandhalter SCL beherrschen, dann siehts vielleicht anders aus ...
Ich bin kein Instandhalter, aber ich würde es auch als Zumutung betrachen, irgendwelche Fehler in Schrittabläufen einer SCL Kette zu suchen, wenn diese Kette einigermaßen komplexe Maschinenbewegungen steuern muss. Und wenn die IBN dann auch noch der Endkunde nach Aufwand bezahlen muss, müsste man das im Besten Fall unter Arbeitsbeschaffungsmaßnahmen, im Worst Case unter unlauterer Leistungserbringung, zusammenfassen.

Wenn ich als Handwerker Steinbearbeitung anbiete, dann erwartet man doch auch, daß ich mit zeitgemäßen und sachgemäßen Mitteln dadran gehe, und nicht etwa mit Kupferkeilen und Holzhämmern.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe früher sehr viel mit B+R programmiert. Da konnte man mit ST oder "Automation Basic" programmieren.
Die Schrittketten konnte man da mit SELECT abbilden. Das war im Grunde vergleichbar mit CASE.
Damals kam ich da sehr gut mit zurecht. Da war es für mich eine Umstellung wieder mit Schrittketten in KOP/FUP zu arbeiten.
Genauso bin ich KOP-Mensch geworden, weil ich seinerzeit auch mit FANUC-Steuerungen gearbeitet habe. Da gab es nur KOP.
Wenn ich FUP sehe muss ich 3x hinschauen. Ich denke da ist auch ganz viel Gewohnheit dabei.
Unabhängig von der Programmiersprache muss das Gerüst des Programms vernünftig strukturiert sein.
Sicher gibt es in jeder Sprache Vorzüge für bestimmte Aufgaben. Diskussionen dazu gibt es in diesem Forum genug.
Aber gerade wenn man über den eigenen Tellerrand blickt, und nicht immer das "Gewohnte" machen darf/muss stellt man fest, dass es auch andere Wege gibt die für einen selbst elegant erscheinen, weil das zur täglichen Praxis wird. Und ja das ist dann für andere Programmierer auf den ersten Blick unübersichtlich oder schlecht nachvollziehbar.
Und damit meine ich jetzt nicht die Programme, die ein Programmierer kurz vor dem Burnout unter Zeitdruck zusammengebastelt hat.
 
Ich habe früher sehr viel mit B+R programmiert. Da konnte man mit ST oder "Automation Basic" programmieren.
Die Schrittketten konnte man da mit SELECT abbilden. Das war im Grunde vergleichbar mit CASE.
Damals kam ich da sehr gut mit zurecht. Da war es für mich eine Umstellung wieder mit Schrittketten in KOP/FUP zu arbeiten.
Genauso bin ich KOP-Mensch geworden, weil ich seinerzeit auch mit FANUC-Steuerungen gearbeitet habe. Da gab es nur KOP.
Wenn ich FUP sehe muss ich 3x hinschauen. Ich denke da ist auch ganz viel Gewohnheit dabei.
Unabhängig von der Programmiersprache muss das Gerüst des Programms vernünftig strukturiert sein.
Sicher gibt es in jeder Sprache Vorzüge für bestimmte Aufgaben. Diskussionen dazu gibt es in diesem Forum genug.
Aber gerade wenn man über den eigenen Tellerrand blickt, und nicht immer das "Gewohnte" machen darf/muss stellt man fest, dass es auch andere Wege gibt die für einen selbst elegant erscheinen, weil das zur täglichen Praxis wird. Und ja das ist dann für andere Programmierer auf den ersten Blick unübersichtlich oder schlecht nachvollziehbar.
Und damit meine ich jetzt nicht die Programme, die ein Programmierer kurz vor dem Burnout unter Zeitdruck zusammengebastelt hat.

Ganz ernsthaft, das ist jetzt einfach sinnloses Geschwafel. Das was du jetzt schreibst, nihiliert eine sachgerechte Vorgegehnsweise in der Programmierung per de. So nach dem Motto „geht ja alles und mit allem und Kop und Fup und bla blupp“

Und das lasse ich so nicht stehen! Wie willst du komplexe Ketten mit mehreren 100 Schritten mit ProDiag Übwerwachungen, Verrigelungs- und Supervisionsbedingungen, mit Parallel- und Alternativzweigen in KOP FUP oder ST abbilden ? Solche Vorstellungen gehen an jeglicher Realität im Feld vorbei. Oder es werden eben 10 000h Projekte wo jede kleine Änderung mit unglaublichem Aufwand implementiert werden muss. Maschinenabläufe kannst du wartungsfähig sowie erweiterungsfähig bei Berücksichtigung von Programmieraufwand nur in Graph wirtschaftlich abbilden, und alles andere ist sachfremd und surreales Wunschdenken.
 
Genau dorthin wollte ich diesen thread nicht lenken. Es geht nicht darum eine Theorie aufzustellen welche Sprache man auf jeden Fall immer benutzen sollte.
Es war vielmehr der Blick über den Tellerrand. Nicht jeder programmiert Anlagen mit mehr als 100 Schritten. Nicht jeder hat immer die Möglichkeit die Sprache seiner Wahl einzusetzen, z.B. weil man eben nicht mit Siemens programmiert. So kann man auch durchaus daran gewöhnt sein, Abläufe in SCL zu packen. So wie der TE. Darauf wollte ich in diesem Zusammenhang hinweisen.
 
Zurück
Oben