# TP Baustein hält Variable auf False



## marsmännchen (19 März 2022)

Hallo zusammen.
Ich würde einen kleinen Lehrkurs für Anfänger benötigen.
Ich versuche auf meiner PFC200 immer wieder mal in ST zu programmieren. Jetzt habe ich folgende Frage:
Ich benutze einen TP um meinen Rollläden den Impuls für Öffnen/Schließen und den Input für die Position zu übermitteln.
Einen Impuls deshalb, weil ich ja von anderer Stelle im Programm die Globalen Variablen für Öffnen/Schließen und Positionierung  auch nochmal beschreiben will. Durch z.B.: Taster, Dämmerung,...
Also denke ich mir als Laie " OK, der Impuls von TP setzt das ganze mal für 2 sek. auf true-> Wert wird übermittelt -> Trigger für Positionierung wird gesetzt und dann ist Schluss Globaler Variable beschreiben"
Aber mir kommt es so vor als würde der TP die Variable auf FALSE halten und ich kann nichts mehr daran ändern. 

```
TON_RollUg_TrigPos1(IN:=xStateRollUg=1,PT:=T#2S);
TON_RollUg_TrigPos2(IN:=xStateRollUg=2,PT:=T#2S);


R_Trig_SavePos(CLK:=xStateRollUg=1);
    
    
// Hier wird die Position gespeichert bei Abwesenheit der Personen
IF R_Trig_SavePos.Q THEN
    bySavedPosRollWZR:= PersistentVars.byRollActualPosWZR;
    bySavedPosRollWZL:= PersistentVars.byRollActualPosWZL;
    bySavedPosRollWasch:= PersistentVars.byRollActualPosWasch;
    bySavedPosRollTerr:= PersistentVars.byRollActualPosTerr;
    bySavedPosRollFranz:=PersistentVars.byRollActualPosFranz;
    
END_IF

//Ab hier wird die Anwesenheit verarbeitet
IF MB_Gen.xPresenceDetectionON THEN
CASE xStateRollUg OF
    1:    //Case1 Keine Anwesenheit erkannt
        //Zuerst werden die Positionswerte von Konstanten übernommen
        GVL_Main_Control.byUGRollWZRSetPos:= Control_RollUG.byUgPosClosed;
        GVL_Main_Control.byUGRollWZLSetPos:= Control_RollUG.byPosWZLCAT;
        GVL_Main_Control.byUGRollWaschSetPos:= Control_RollUG.byUgPosClosed;
        GVL_Main_Control.byUGRollTerrSetPos:= Control_RollUG.byUgPosClosed;
        GVL_Main_Control.byUGRollFranzSetPos:= Control_RollUG.byUgPosClosed;
        TP_RollUg_Pulse1(IN:=TON_RollUg_TrigPos1.Q,PT:=T#2S);
        
        IF TON_RollUg_TrigPos1.Q THEN
        //Jetzt werden die Trigger gesetzt für den OscatBlindInput
        
        GVL_Main_Control.xUGRollWZRTrigPos:= TP_RollUg_Pulse1.Q;
        GVL_Main_Control.xUGRollWZLTrigPos:=TP_RollUg_Pulse1.Q;
        GVL_Main_Control.xUGRollWaschTrigPos:=TP_RollUg_Pulse1.Q;
        GVL_Main_Control.xUGRollTerrTrigPos:=TP_RollUg_Pulse1.Q;
        GVL_Main_Control.xUGRollFranzTrigPos:=TP_RollUg_Pulse1.Q;
        END_IF
        
        
        //Case2 Anwesenheit erkannt
    2:   
        //Hier das selbe wenn jemand anwesend ist
        GVL_Main_Control.byUGRollWZRSetPos:= bySavedPosRollWZR;
        GVL_Main_Control.byUGRollWZLSetPos:= bySavedPosRollWZL;
        GVL_Main_Control.byUGRollWaschSetPos:= bySavedPosRollWasch;
        GVL_Main_Control.byUGRollTerrSetPos:= bySavedPosRollTerr;
        GVL_Main_Control.byUGRollFranzSetPos:= bySavedPosRollFranz;
        TP_RollUg_Pulse2(IN:=TON_RollUg_TrigPos2.Q,PT:=T#2S);
        
        IF TON_RollUg_TrigPos2.Q THEN
        
        GVL_Main_Control.xUGRollWZRTrigPos:=TP_RollUg_Pulse2.Q;
        GVL_Main_Control.xUGRollWZLTrigPos:=TP_RollUg_Pulse2.Q;
        GVL_Main_Control.xUGRollWaschTrigPos:=TP_RollUg_Pulse2.Q;
        GVL_Main_Control.xUGRollTerrTrigPos:=TP_RollUg_Pulse2.Q;
        GVL_Main_Control.xUGRollFranzTrigPos:=TP_RollUg_Pulse2.Q;   
        END_IF
    END_CASE
END_IF
```

Und hier ist ein anderer Programmabschnitt mit dem TP_0 der die Trigger (GVL_Main_Control.xUGRollWZRTrigPos,....) scheinbar auf FALSE zwingt.



Wenn ich den Programmteil nämlich lösche funktioniert mein wunderbares Spiel.
Kann mir jemand sagen wie ihr machen würdet? Es kann doch nicht sinnhaft sein für jede Ansteuerung eine eigene Variable zu erstellen und die dann mit OR an den BlindInput zu klemmen
Danke für die Lehreinheit schonmal.
Gruß Patrick


----------



## winnman (20 März 2022)

Variablen im TP nur setzen, nach Bearbeitung in der SPS von dieser zurücksetz.
Achtung, TP setzt Variablen irgendwann im Zyklus, hier muss man selbst eine art Zykluskontrollpunkt schaffen.


----------



## marsmännchen (20 März 2022)

Hallo, meinst du Variablen werden *vom* TP nur gesetzt? Und nach Ablauf der Pulszeit wieder zurückgesetzt?
So hätte ich dich und die Anleitung verstanden.


----------



## holgermaik (20 März 2022)

Bei mehrfachen beschreiben von Variablen muss man aufpassen. Der letzte Schreibbefehl gewinnt.
Dein ST Programm wird nur bedingt ausgeführt. ist also ok. der TP wird immer ausgeführt. Ist die Zeit angelaufen schreibt er die Variable  zu False.


----------



## marsmännchen (20 März 2022)

Ja, aber warum HÄLT er ihn auf False? Wie kann ich das *verhindern* das der Teil mit TP_0 im Screenshot (CFC) die Variable z.B: GVL_Main_Control.byUGRollWZRSetPos auf False Hält? Die sollte ja doch irgendwie (wie soll ich sagen?) frei sein, unberührt...😬
Fertig um meinen Befehl zu empfangen. Einfach einmal gepulst und aus. Weil wenn ich den TP_0 und die Variablen GVL_Main_Control.byUGRollWZRSetPos, usw.. lösche dann funktioniert mein ST Programm einwandfrei. Wenn ich das CFC so lasse kann mein ST die Variablen nicht schreiben. die bleiben stur auf FALSE.
Gruß Patrick


----------



## holgermaik (20 März 2022)

marsmännchen schrieb:


> Ja, aber warum HÄLT er ihn auf False?


Er hält den Ausgang nicht. Der Ausgang des TP wird jeden Zyklus anhand der Funktion neu beschrieben.


----------



## marsmännchen (20 März 2022)

Mit FALSE beschrieben. Und dadurch kann er an anderer Stelle nicht mit true beschrieben werden. Ich versteh das einfach nicht. Dann muss ich scheinbar etliche hilfsmerker erstellen um den GVL_Main_Control.byUGRollWZRSetPos mehrmals zu beschreiben.


----------



## PN/DP (20 März 2022)

Variablen oder gar Ausgänge an verschiedenen Stellen des Steuerungsprogramms zu beschreiben (womöglich noch in verschiedenen Codeblöcken) ist ganz schlechter Programmierstil. Besser ist, die verschiedenen Schalt-Anforderungen auf mehrere Hilfs-Variablen zu legen und diese bei der Ausgangszuweisung mit einem großen ODER zu verknüpfen. Das läßt sich u.A. viel besser beobachten und es fällt einem auf, daß man auch für Ausschalten sorgen muß.

Harald


----------



## marsmännchen (21 März 2022)

Ja, das ist mal eine Ansage. Das hab ich verstanden. Ich werde das mal so versuchen! Danke sehr. 
Gruß Patrick


----------



## winnman (21 März 2022)

Eine gute Programmierstrategie ist alles was vom TP kommt / zu TP geht in einen eigenen DB (oder mehrere) zu packen.


----------



## oliver.tonn (21 März 2022)

winnman schrieb:


> Variablen im TP nur setzen, nach Bearbeitung in der SPS von dieser zurücksetz.
> Achtung, TP setzt Variablen irgendwann im Zyklus, hier muss man selbst eine art Zykluskontrollpunkt schaffen.


Seit wann soll das im Codesys Universum so sein? Bei Siemens ist das bei den S5-Timern so, meine ich, aber bei Codesys und den Derivaten ist das eigentlich nicht so.
TP ist, wie TON und TOF auch, ein FB und der ändert seine Ausgänge nur wenn er aufgerufen wird, danach bleiben diese gleich bis zum nächsten Aufruf. Einfach so spontan ändern FBs Ihre Ausgänge nicht.
Ich habe gerade Deinen letzten Beitrag gelesen, kann es sein, dass Du gedanklich bei Siemens bist, denn auch DBs gibt es im Codesys Universum nicht.


----------



## winnman (21 März 2022)

Sorry ja war bei Siemens, würde das aber auch auf allen anderen Plattformen der Übersichtlichkeit wegen mit eigenem Speicherbereich machen.

So kann man später auch leicht von der Ferne, . . . gezielt zugreifen ohne sich in die Tiefen des Programms verirren zu müssen.


----------



## marsmännchen (21 März 2022)

Ok, jetzt wirds kompliziert... Ich werd mal die Sache mit den hilfsvariablen durchziehen, das kenne ich aus der Arbeit.


----------



## oliver.tonn (21 März 2022)

marsmännchen schrieb:


> Ok, jetzt wirds kompliziert... Ich werd mal die Sache mit den hilfsvariablen durchziehen, das kenne ich aus der Arbeit.


Eigentlich nicht wirklich. Variablen sollte man nicht an mehreren Stellen schreiben, weil der letzte Schreibzugriff bestimmt den Wert der Variablen.
Dann machst Du meiner Meinung nach noch einen weiteren "Fehler". Du rufst Timer in einer CASE-Anweisung auf, das kann zu Fehlern führen. Damit Deine Timer das nächste mal loslaufen müssen Sie mindestens einmal mit IN := FALSE aufgerufen werden, da sie nur auf eine steigende Flanke reagieren.
Am besten rufst Du Timer außerhalb von bedingten Anweisungen (CASE oder IF) auf und innerhalb der Anweisungen setzt Du nur die Eingänge (z.B. TP_RollUg_Pulse1.IN := TRUE) und wertest die Ausgänge aus.
Übrigens sollte man FBs die mehrere Zyklen laufen nie in bedingten Anweisungen ausführen, sondern immer außerhalb, egal ob Timer oder anderes (z.B. Dateizugriffe).


----------

