# Wartebefehl in ST Schrittkette / wait time



## domiup (29 September 2022)

Hallo zusammen, 

zu meinem Programm: ich möchte 4 Verschiedene Spannungen über eine Schrittkette anfahren. Die Spannung soll dabei langsam erhöht werden und beim Erreichen der jeweiligen Punkte soll die Spannung 2min anstehen. Die Schrittkette habe ich soweit fertig. Allerdings benötige ich Hilfe bei den Zeiten bzw. beim Erhöhen der Spannung. Hat da jemand eine Lösung für mich? 


```
PROGRAM PLC_PRG
VAR
    rTestspannung:INT;
    iSchrittkette:INT:=0;
    rPunkt1:INT:=19552;
    rPunkt2:INT:=19968;
    rPunkt3:INT:=21631;
    rPunkt4:INT:=22048;
END_VAR


CASE iSchrittkette OF
    
    1:    rTestspannung:=rPunkt1;
        iSchrittkette:=2;
            
    2:    WHILE rPunkt1 < rPunkt2 DO
        rTestspannung:=rPunkt1;
        rPunkt1:=rPunkt1+1;
        END_WHILE;
        iSchrittkette:=3;
        
    3:    WHILE rPunkt1 < rPunkt3 DO
        rTestspannung:=rPunkt1;
        rPunkt1:=rPunkt1+100;
        END_WHILE;
        iSchrittkette:=4;
        
    4:    WHILE rPunkt1 < rPunkt4 DO
        rTestspannung:=rPunkt1;
        rPunkt1:=rPunkt1+100;
        END_WHILE;
        iSchrittkette:=0;
    
END_CASE
```


----------



## oliver.tonn (29 September 2022)

Nimm doch einen TON den Du außerhalb der Schrittkette aufrufst und innerhalb der Schrittkette die Eingänge beschaltest und den Ausgang abfragst und dann entsprechend zum nächsten Schritt schaltest. Du musst nur darauf achten, dass der TON zum Start eine steigende Flanke bekommt.


----------



## KLM (29 September 2022)

Moin, ein TON außerhalb der Schrittkette ist, wie @oliver.tonn schon sagt, was Du suchst. Allerdings koppelst Du durch Deine Schrittkette die Addition an die Taskzykluszeit und Timer mittels Task sind immer ungünstig. Ich würde daher einen zweiten Time dafür einbauen. Und Deine Schrittkette ist recht unflexibel was mögliche weitere Zwischenpunkte anbelangt. Mein Vorschlag wäre folgender.


```
VAR CONSTANT
    c_usiMAX_POINTS    : USINT := 3; (* base 0 *)
END_VAR

VAR
    rVoltageOut            : REAL;
    aiPoints                : ARRAY[0..c_usiMAX_POINTS] OF INT := 19552, 19968, 21631, 22048;
    aiOffsets                : ARRAY[0..c_usiMAX_POINTS] OF INT := 0, 1, 100, 100;
    usiPoint                : USINT;
    fbDelaySmall            : TON;
    fbDelayLarge            : TON;
    xRun                    : BOOL := TRUE;
    fbRtRun                : R_TRIG;
    usiSate                : USINT;
END_VAR
```


```
fbRtRun(CLK:= xRun);
IF fbRtRun.Q THEN
    usiSate := 1;
    rVoltageOut := aiPoints[ 0 ];
    usiPoint := 1;
ELSIF NOT xRun THEN
    usiSate := 0;
    rVoltageOut := 0;
END_IF

fbDelaySmall(
    IN:= NOT fbDelaySmall.Q AND (usiSate = 1),
    PT:= t#100ms);
fbDelayLarge(
    IN:= NOT fbDelaySmall.Q AND (usiSate = 2),
    PT:= t#2m);

CASE usiSate OF
    0: (* idle *)
        ;

    1: (* add offset *)
        IF fbDelaySmall.Q THEN
            rVoltageOut := rVoltageOut + aiOffsets[ usiPoint ];
        END_IF
        IF rVoltageOut >= aiPoints[ usiPoint ] THEN
            usiSate := 2;
        END_IF

    2: (* wait for large delay *)
        IF fbDelayLarge.Q THEN
            IF usiPoint >= c_usiMAX_POINTS THEN
                usiSate := 0;
            ELSE
                usiPoint := usiPoint + 1;
                usiSate := 1;
            END_IF
        END_IF
END_CASE
```


----------



## oliver.tonn (29 September 2022)

Ich habe mir Deinen Code gar nicht richtig angesehen.Was willst Du denn mit den While Schleifen erreichen?
Ich habe da einen Verdacht was Du vorhast und falls meine Vermutung stimmt, wird das allerdings so nicht gehen.


----------



## domiup (30 September 2022)

Vielen Dank für die Hilfe! Ich werde mich mal dran setzen. @oliver.tonn mit WHILE - Schleife hatte  ich vor gehabt die Spannung an Punkt1 zb. solange zu erhöhen bis sie den Wert von Punkt2 erreicht. Das hatte auch so funktioniert wie ich es wollte allerdings wollte ich sekündlich erhöhen, was dann nicht funktionierte.


----------



## oliver.tonn (30 September 2022)

domiup schrieb:


> Vielen Dank für die Hilfe! Ich werde mich mal dran setzen. @oliver.tonn mit WHILE - Schleife hatte  ich vor gehabt die Spannung an Punkt1 zb. solange zu erhöhen bis sie den Wert von Punkt2 erreicht. Das hatte auch so funktioniert wie ich es wollte allerdings wollte ich sekündlich erhöhen, was dann nicht funktionierte.


Nachtigall ick hör Dir trapsen. Ich sehe eine Katastrophe aufziehen. Du bist mit den Besonderheiten einer SPS vertraut? Komm bitte nicht auf die Idee in der While-Schleife einen Timer zu nutzen die den Ablauf verzögert und schmeiß diese am Besten gleich ganz raus. Ein SPS Programm wird meist zyklisch abgearbeitet und dies muss innerhalb einer definierten Zeit erfolgen. Bei Codesys basierten Steuerungen gibt die Zykluszeit vor, wie lange nach dem vorhergehenden Start das SPS-Programm erneut gestartet wird und alles muss vor dieser Zeit beendet sein. Ein SPS-Programm kann nicht, wie ein PC-Programm, an einer Stelle auf ein Ereignis warten, sondern muss stetig weiterlaufen.


----------



## Ralle (30 September 2022)

Du nimmst einen Timer (SE oder Impuls) und baust dir damit einen Sekundentakt. Wiele SPS (Wago evtl. auch) heben auch Standardbits für soetwas wie Takte.
Den AUsgang des Timeras schaltest du auf eine Flanke, so dass du danach jede Sekunde eine Flanke hast.
Mit dieser Flanke kannst du dann deine Werte hochzählen.

`If #SekundenFlanke Then
   #MeinWert  := MeinWert + 1;
End_IF;`

In der Schrittkette dann:

`If #MeinWert > rPunkt1 then
   usiState := ...
End_IF`

So in dieser Art.
Willst du schneller hochzählen, dann den Timer kleiner machen (Auchtung, er darf nicht zu klein werden) oder du zählst nicht 1 hoch sondern z.Bsp. 10.


----------



## domiup (30 September 2022)

@oliver.tonn bin ein SPS Neuling und habe es durch Try and Error probiert 😂Habe alle Probleme lösen können. Danke für die Hilfe!


----------



## hucki (30 September 2022)

domiup schrieb:


> @oliver.tonn bin ein SPS Neuling und habe es durch Try and Error probiert 😂Habe alle Probleme lösen können. Danke für die Hilfe!


Im Interesse anderer Suchender mit einem gleichen oder ähnlichen Problem wäre es gut, wenn Du hier auch erklären/zeigen würdest, wie genau Du Dein Problem gelöst hast.


----------



## domiup (30 September 2022)

Habe die Lösung von @KLM übernommen und ein wenig auf mein Projekt angepasst. Sprich Variablen geändert und die Arrays weggelassen da es so für mich einfacher  zu Verstehen war und ich kein Raum für Erweiterungen brauche.  Somit ist ist die professionellere Lösung schon im Chat


----------

