# While Schleife in ST



## Snooky (24 November 2010)

moin zusammen,

hab da ma ne Frage...
Villt ne dumme aber ich weiß es nicht besser.
Programmiere für nen Projekt grad eine Ofensteuerung.
Hab eine While schleife gebaut wo ich auf eine Temperature abfrage.

IF isttempA < SolltempA THEN    
SolltempB:=SolltempA - 0.1;     
   WHILE isttempA < SolltempB DO  (*solange isttemp < solltemp*)
       isttempA:=Umwandlung(isttemp);(Funktion Strom0..20mA->°C*)      
       SolltempmA := Solltemp_Strom(SolltempA); 
   IF AbtastA <> -1 THEN      
       NotSolltemp:=TRUE;     
      TIME3:=mult_sec(AbtastA); (*Funktion von ms nach s *)
      z:=abtasten(AbtastA,NotSolltemp);  
   END_IF
   END_WHILE
  END_IF

Kompilieren lässt sich alles wunderbar. 
Wenn ich das Programm starte, schmiert sofort alles ab.

Ich kenne die While schleife aus C und in C wiederholt die schleife das ganze bis die Bedingung eintritt.

Ne SPS arbeitet ja über nen Zyklus und ich hab das Gefühl das ich mit der Schleife nen Loop baue.

Komme irgendwie nicht weiter... 

Danke für eure Hilfe

Gruß Martin


----------



## MSB (24 November 2010)

Dein Problem ist definitiv das "WHILE".

Die SPS ist sowieso eine ständige Endlos-Schleife, also entspräche dein WHILE in dem Fall eindeutig einem zusätzlichen "IF THEN".


```
IF isttempA < SolltempA THEN
    SolltempB:=SolltempA - 0.1;
    IF isttempA < SolltempB DO (*solange isttemp < solltemp*) THEN
        isttempA:=Umwandlung(isttemp);(Funktion Strom0..20mA->°C*)
        SolltempmA := Solltemp_Strom(SolltempA);
        IF AbtastA <> -1 THEN
            NotSolltemp:=TRUE;
            TIME3:=mult_sec(AbtastA); (*Funktion von ms nach s *)
            z:=abtasten(AbtastA,NotSolltemp);
        END_IF
     END_IF
END_IF
```

Die WHILE Schleife ist bei einer SPS nur in den seltensten Fällen sinnvoll zu gebrauchen.
Warum hast du jetzt ja kennengelernt ...

Mfg
Manuel


----------



## CoDeSysCoDer (26 November 2010)

Snooky schrieb:


> Ich kenne die While schleife aus C und in C wiederholt die schleife das ganze bis die Bedingung eintritt.



While wiederholt { ... } solange while( ... ) wahr ist!!! 
Es gibt in C auch noch eine Until und die wiederholt { .. }bis until( ... ) wahr ist!!!



> Ne SPS arbeitet ja über nen Zyklus und ich hab das Gefühl das ich mit der Schleife nen Loop baue.


Genau das passiert auch. Du musst die bedingung in der While ändern


> Komme irgendwie nicht weiter...



Du musst die bedingung in der While ändern


----------



## Snooky (30 November 2010)

Hallo danke für eure Hilfe.
Es scheint allerdings so als hätte ich nen hänger. Ich komme einfach nicht drauf wie ich das machen soll.

Das Programm soll so funktionieren das alles abgearbeitet wird und bei einer Negativen Flanke von bool_verweil i um 1 hochgezählt wird.
Wenn im Feld Ende steht wird das Programm beendet ansonsten die nächste Temperatur angefahren.
Das Problem ist, wie kann ich erreichen das das Programm nicht beim Start direkt alle Felder abfragt. erst wenn bool_verweil eine negative flanke bringt darf die nächste Temperatur angefahren werden.
Oder kann ich dies noch anders z.B. ohne eine Schleife programmieren?

Hier der Code:


```
IF Programm_start = TRUE THEN                 (*Programm start *)
verweilStart:=FALSE;
    WHILE  eingabe[i] <> 'Ende' DO                     (* Programm Schleife zur Abfrage der in der Tabelle stehenden Werte*)

        IF eingabe[i] ='Temperatur' THEN                 (* Abfrage ob im Feld eingabe von i der String Temperatur steht *)
            SolltempA:=eingabe_wert[i];                     (*Temperaturwert nach Variable SolltempA schreiben ( Sichern ) *)
        END_IF
        IF SolltempA >= -20 AND SolltempA <= 90 THEN     (* Abfrage ob SolltempA > -20°C und < 90°C ist*)
            i:=i+1;                                         (* Die Varible i wird um 1 hochgezählt um ins nächste Feld der Arrays zu springen*)
        END_IF
        IF SolltempA > 90 THEN                         (*Abfrage ob Solltemp A > 90 ist*)
            SolltempA := 90;                                 (*Die Variable SolltempA mit 90 überschreiben*)
            eingabe_wert[i]:=90;                             (* 90 ins Arrayfeld schreiben ( nur zur Anzeige ; keine Funktion) *)
            Fehlermeldung[i]:='Temp > 90°C ; Temp=90°C !';     (* Fehlermeldung ob die Temperatur > 90°C ist*)
            i:=i+1;                                          (* Die Varible i wird um 1 hochgezählt um ins nächste Feld der Arrays zu springen*)
        END_IF
        IF SolltempA < -20 THEN                         (*Abfrage ob Solltemp A < 20 ist*)
            SolltempA:= -20;                                 (*Die Variable SolltempA mit -20 überschreiben*)
            eingabe_wert[i]:= -20;                             (* -20 ins Arrayfeld schreiben ( nur zur Anzeige ; keine Funktion) *)
            Fehlermeldung[i]:='Temp< -20°C ; Temp= -20°C !';     (* Fehlermeldung ob die Temperatur < -20°C ist*)
            i:=i+1;                                          (* Die Varible i wird um 1 hochgezählt um ins nächste Feld der Arrays zu springen*)
        END_IF
        IF eingabe[i]='Abtastrate' THEN                  (* Abfrage ob im Feld eingabe von i der String Abtastrate steht *)
            AbtastA:=eingabe_wert[i];                         (* Wert nach AbtastA schreiben*)
            i:=i+1;                                          (* Die Varible i wird um 1 hochgezählt um ins nächste Feld der Arrays zu springen*)
        END_IF



            IF isttempA <> SolltempA THEN            (*Schleife für Steigung positiv *)

            isttempA:=Umwandlung(isttemp);            (*Abfrage auf Isttemperatur des Ofens*)

            SolltempmA := Solltemp_Strom(SolltempA);    (*Übergabe der Solltemperatur auf den Eingang der Stromklemme*)

            IF AbtastA <> -1 AND NOT bool_verweil THEN                        (*Abfrage ob AbtastA ungleich -1*)
                NotSolltemp:=TRUE;
                TIME3:=mult_sec(AbtastA);
                z:=abtasten(AbtastA,NotSolltemp);        (*Übergabe der Funktion WerteSchreiben den Abtastintervall sowie die positive BOOL*)
            END_IF
            END_IF
            IF eingabe[i]='' THEN                             (* Wenn EingabeFeld leer Ende reinschreiben! Wichtig sollte der Anwender Ende vergessen würde die CPU abstürzen (LOOP) *)
            eingabe[i]:='Ende';
            END_IF
            IF isttempA > SolltempA - 0.1 THEN
            istgroesser:=TRUE;
            ELSE
            istgroesser:=FALSE;
            END_IF
            IF isttempA < SolltempA +0.1 THEN
            istkleiner:=TRUE;
            ELSE
            istkleiner:=FALSE;
            END_IF

(* Isttemp größer Solltemp*)

(*ENDE Veränderung*)

(*START Timer*)
        IF eingabe[i] ='Timer' THEN                      (* Abfrage ob im Feld eingabe von i der String Timer steht *)
        TimerA:=eingabe_wert[i];
        i:=i+1;
        time4:=mult_min(TimerA);                                         (* Die Varible i wird um 1 hochgezählt um ins nächste Feld der Arrays zu springen*)
        END_IF
            FF2(CLK:=istgroesser , Q=>nflanke );
            Timer(IN:=nflanke , PT:=time4 , Q=>bool_verweil );

            FF3(CLK:=istkleiner , Q=>nflanke2 );
            Timer(IN:=nflanke2 , PT:=time4 , Q=>bool_verweil );


            IF bool_verweil = TRUE THEN
            IF eingabe[i]='Abtastrate' THEN                  (* Abfrage ob im Feld eingabe von i der String Abtastrate steht *)
            AbtastA:=eingabe_wert[i];                         (* Wert nach AbtastA schreiben*)                                                (* Die Varible i wird um 1 hochgezählt um ins nächste Feld der Arrays zu springen*)
            END_IF
            SolltempmA := Solltemp_Strom(SolltempA);    (*Übergabe der Solltemperatur auf den Eingang der Stromklemme*)

            NotSolltemp:=FALSE;                    (*Umwandlung von TimerA nach minuten*)

            (*start_time_verweil:=FALSE;*)
            IF AbtastA <> -1 THEN                        (*Abfrage ob AbtastA ungleich -1*)
            TIME3:=mult_sec(AbtastA);
            z:=abtasten(AbtastA,bool_verweil);        (*Übergabe der Funktion WerteSchreiben den Abtastintervall sowie die positive BOOL*)
            END_IF
            END_IF

        END_WHILE

END_IF                                         (*ENDE Programm_start*)
```


----------



## Bitmanipulator (30 November 2010)

Wie oben schon erwähnt, wird jedes Programm in einer SPS zyklisch abgearbeitet.
Also immer und immer wieder. Dazu gehört eine Zykluszeit und die kann man mit einer Schleife ungewollt überschreiten.


----------



## Snooky (30 November 2010)

Hey,

ja das habe ich verstanden! Nur wie kann ich erreichen das die große(eingabe_<> 'Ende') von mir aus auch ne IF Schleife, immer bei einer negativen Flanke von bool_verweil ausgeführt wird? Das Problem ist ja das der Eingang der IF Abfrage solange TRUE sein muss bis die SPS zeit hatte alle anderen IF Abfragen abzuarbeiten. Ne Flanke reicht da wahrscheinlich nicht aus.

Gruß Martin_


----------



## Ghosty (30 November 2010)

Hi,

zuerst mal IF ist keine Schleife, sondern eine Abfrage.

Setz doch einfach bei der negativen Flanke von bool_verweil ein Bit das die IF-Anweisung aktiviert und nachdem du alle gewünschten Anweisungen abgearbeitet hast nimmst du es wieder weg. 

Gruß


----------

