TIA SCL Fußgesteuerte Schleife

Zombieanfuehrer

Level-1
Beiträge
65
Reaktionspunkte
4
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Morgen,


ich habe mal eine Frage zu einer Do While (bzw in TIA While DO ) Schleife.

Hier der Code:

Code:
        WHILE NOT #ERROR_GET_10 AND NOT #ERROR_GET_9 AND NOT #ERROR_GET_8 AND NOT #ERROR_GET_7 AND NOT #ERROR_GET_6 AND NOT #ERROR_GET_5 AND            NOT #ERROR_GET_4 AND NOT #ERROR_GET_3 AND NOT #ERROR_GET_2 AND NOT #ERROR_GET_1 AND NOT #ERROR_PUT_10 AND NOT #ERROR_PUT_9 AND NOT #ERROR_PUT_8 AND NOT #ERROR_PUT_7 AND NOT #ERROR_PUT_6 AND NOT #ERROR_PUT_5 AND
            NOT #ERROR_PUT_4 AND NOT #ERROR_PUT_3 AND NOT #ERROR_PUT_2 AND NOT #ERROR_PUT_1 DO 
            
                 #"Status#Telegramm":=#STATUS_PUT_1;
        END_WHILE;


Da ich so gut wie keine Erfahrung mit schleifen in TIA habe aber es gerne lernen würde lautet meine Frage:

Ich jetzt möchte, wenn die Schleifen Bedienung nicht erfüllt ist,(sprich einer von den ganzen PUT o. GET Errors anliegt) dass dann der Status des entsprechenden Bausteins in den #"Status#Telegramm" geladen wird.

Ich würde das jetzt dann mit IF-Verzweigungen machen, und diese unter END_WHILE; : Bsp. IF Error_GET_8 THEN #"Status#Telegramm":=#STATUS_GET_8 usw.
Somit wäre je die While Do Schleife nicht mehr erfüllt, und dem Status kann verändert werden, oder?


Mit freundlichen Grüßen.
 
Zuletzt bearbeitet:
Moin,
alles was innerhalb deiner While-Schleife steht wird solange ausgeführt, bis die Schleifenbedingung nicht mehr erfüllt ist. In deinem Code findet aber überhaupt keine Manipulation deiner Variablen die den Schleifenkopf bilden statt. Deine Schleife läuft also ewig und deine CPU geht in Stop.
Wichtig bei der Verwendung einer While-Schleife ist zu wissen, dass keinerlei anderer Code (mal abgesehen von Interrupt-OBs) mehr abgearbeitet wird! Du musst also immer die Variablen deines Schleifenkopfes innerhalb deiner While manipulieren.
Und dann noch ein persönlicher Rat: Die meisten guten SPS-Programme kommen auch ohne While-Schleifen aus ;)
Wenn du also das Thema Schleifen beackern möchtest, dann schaue dir lieber die For-Schleife an.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die While-Schleife wird deine SPS in STOP versetzen, wenn kein Fehler anliegt, weil die Zykluszeit der SPS überschritten wird.
Ein SPS-Programm läuft als Endlosschleife, ist es am Ende angelangt, beginnt es wieder von vorn. Dabei wird die Zykluszeit überwacht (Einstellbar in der Hardwarekonfiguration der SPS).

Es hängt ein wenig davon ab, was genau du vorhast.

EIN Fehler der PUT-GET-Bausteine soll gemeldet werden, es wird nichts geändert, solange EIN Fehler ansteht

Aus allen veroderten Put-Get-Error wird eine Flanke gebildet, mit dieser Flanke lädst du den entsprechenden Status (IF...then für jeden Error) in das Telegramm.
Treten zufällig zwei Fehler exakt gleichzeitig auf auf, wird nur einer angezeigt und geladen.
Die nächste Flanke kann erst feuern, wenn alle Fehler mind. einen Zyklus lang gleichzeitig False sind.
Kommt zu einem Fehler ein weiterer hinzu, wird dessen Status nicht in das Telegram geladen.
 
Moin,
alles was innerhalb deiner While-Schleife steht wird solange ausgeführt, bis die Schleifenbedingung nicht mehr erfüllt ist. Deine Schleife läuft also ewig und deine CPU geht in Stop.
Wichtig bei der Verwendung einer While-Schleife ist zu wissen, dass keinerlei anderer Code (mal abgesehen von Interrupt-OBs) mehr abgearbeitet wird! Du musst also immer die Variablen deines Schleifenkopfes innerhalb deiner While manipulieren.
Und dann noch ein persönlicher Rat: Die meisten guten SPS-Programme kommen auch ohne While-Schleifen aus ;)

OK, vielen Dank dafür, ich hatte mich schon gefragt wie die Schleife im TIA läuft, der Hilfe nach dachte ich sie läuft dann parallel zum Zyklus.

Die While-Schleife wird deine SPS in STOP versetzen, wenn kein Fehler anliegt, weil die Zykluszeit der SPS überschritten wird.
Ein SPS-Programm läuft als Endlosschleife, ist es am Ende angelangt, beginnt es wieder von vorn. Dabei wird die Zykluszeit überwacht (Einstellbar in der Hardwarekonfiguration der SPS).

Es hängt ein wenig davon ab, was genau du vorhast.

EIN Fehler der PUT-GET-Bausteine soll gemeldet werden, es wird nichts geändert, solange EIN Fehler ansteht

Aus allen veroderten Put-Get-Error wird eine Flanke gebildet, mit dieser Flanke lädst du den entsprechenden Status (IF...then für jeden Error) in das Telegramm.
Treten zufällig zwei Fehler exakt gleichzeitig auf auf, wird nur einer angezeigt und geladen.
Die nächste Flanke kann erst feuern, wenn alle Fehler mind. einen Zyklus lang gleichzeitig False sind.
Kommt zu einem Fehler ein weiterer hinzu, wird dessen Status nicht in das Telegram geladen.

Ich bin jetzt dann doch weg von der Schleife und hab es so ähnlich gemacht, und Speichere den letzten Fehler noch zwischen. Alles mit IF Verzweigung :)

Vielen Dank !
 
Noch eine Frage, ich wollte dazu kein extra Thema aufmachen. Und zwar geht es um case of (bei C programmierung mit switch case bearbeitet er ja ab dem Fall jeden bis break; kkommt.)
Bei SCL nicht?

Bsp.
Code:
 CASE #"Anzahl_Bytes_*1^100" OF                
            10:
                #GET_Instance(REQ := #FP_Start,
                              ID := #"ID#CPU",
                              NDR => #DONE_GET_10,
                              ERROR => #ERROR_GET_10,
                              STATUS => #STATUS_GET_10,
                              ADDR_1 := #"GET_Byte_900..999_Array_slave",
                              RD_1 := #"Ziel_GET_Byte_900..999_Array_master");
                
                #Auswertung_GET_ERROR := FALSE;
                
            9:
                #GET_Instance_1(REQ := #"Start#Get_9",
                                ID := #"ID#CPU",
                                NDR => #DONE_GET_9,
                                ERROR => #ERROR_GET_9,
                                STATUS => #STATUS_GET_9,
                                ADDR_1 := #"GET_Byte_800..899_Array_slave",
                                RD_1 := #"Ziel_GET_Byte_800..899_Array_master");
                
                #Auswertung_GET_ERROR := FALSE;
                
            8:
                #GET_Instance_2(REQ := #"Start#Get_8",
                                ID := #"ID#CPU",
                                NDR => #DONE_GET_8,
                                ERROR => #ERROR_GET_8,
                                STATUS => #STATUS_GET_8,
                                ADDR_1 := #"GET_Byte_700..799_Array_slave",
                                RD_1 := #"Ziel_GET_Byte_700..799_Array_master");
                
                #Auswertung_GET_ERROR := FALSE;
                
                
            7:
                #GET_Instance_3(REQ := #"Start#Get_7",
                                ID := #"ID#CPU",
                                NDR => #DONE_GET_7,
                                ERROR => #ERROR_GET_7,
                                STATUS => #STATUS_GET_7,
                                ADDR_1 := #"GET_Byte_600..699_Array_slave",
                                RD_1 := #"Ziel_GET_Byte_600..699_Array_master");

Was passieren soll wird klar, wenn jetzt case 8 ausgeführt wird soll dann auch 7 , 6 usw. ausgeführt werden...
Aber er führt wirklich nur 8 aus. Gibts eine Lösung ohne GOTO ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Noch eine Frage, ich wollte dazu kein extra Thema aufmachen. Und zwar geht es um case of (bei C programmierung mit switch case bearbeitet er ja ab dem Fall jeden bis break; kkommt.)
Bei SCL nicht?
...
Was passieren soll wird klar, wenn jetzt case 8 ausgeführt wird soll dann auch 7 , 6 usw. ausgeführt werden...
Aber er führt wirklich nur 8 aus. Gibts eine Lösung ohne GOTO ?
nein, das Case in SCL ist quasi nur ein hübsches if...elsif...elsif...elsif...else :-(
das zunächst das erste Case und einen Zyklus später das zweite bearbeitet wird, müsstest du selbst bspw. mit der Manipulation deiner Case-Variable lösen.
so zum Beispiel:
Code:
Case n Of
    1:  // mache das erste
        ;
        n += 1;
    2:  // mache das zweite
        ;
        n += 1;
    3:  // mache das dritte
        ;
        n := 1;    // nächsten Zyklus wieder von vorne anfangen
    Else  // falls mal was mit n schiefgelaufen ist
        n := 1;    // n wieder initialisieren
End_Case;
oder mal in Richtung Schrittkette hier im Forum suchen.

Wofür ist der ganze Zauber überhaupt? Möchtest du lediglich vermeiden, dass alle Gets parallel laufen?
 
Case arbeitet nur bis zur nächsten Case-Bedingung, also in deinem Fall z.B. bei 9 bis vor 8:

PS: Abwärts zählend hab ich das noch nie gemacht ;-)

Wozu soll dene Vorgehensweise gut sein, was willst du erreichen mit dem case?
 
Was passieren soll, ist mir nicht wirklich klar.
Das scheint weder ein Fall für Case noch für If - Elseif - Else zu sein!
Beschreib Deine Aufgabe bitte so, dass sie nicht nur Dir klar ist!

PS:
Meinst Du so etwas?
Code:
If x>=9 then
    . . .
    endif
If x>=8 then
    . . .
    endif
If x>=7 then
    . . .
    endif
If x>=6 then
    . . .
    endif
u.s.w.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
wenn jetzt case 8 ausgeführt wird soll dann auch 7 , 6 usw. ausgeführt werden...
Aber er führt wirklich nur 8 aus. Gibts eine Lösung ohne GOTO ?
mit REPEAT- oder WHILE-Schleife um das CASE-Konstrukt und CONTINUE und EXIT. Oder so wie hier gezeigt: https://www.sps-forum.de/simatic/90599-v15-scl-goto-befehl-verwenden-3.html#post681007

PS: es ist mir schleierhaft wie man als professioneller Programmierer sich solche Variablennamen ausdenken kann (und Siemens das auch noch zulässt): #"Anzahl_Bytes_*1^100"
PPS: Warum Unterstriche? Leerzeichen sind doch auch erlaubt... ;)

Harald
 
mit REPEAT- oder WHILE-Schleife um das CASE-Konstrukt und CONTINUE und EXIT. Oder so wie hier gezeigt: https://www.sps-forum.de/simatic/90599-v15-scl-goto-befehl-verwenden-3.html#post681007

PS: es ist mir schleierhaft wie man als professioneller Programmierer sich solche Variablennamen ausdenken kann (und Siemens das auch noch zulässt): #"Anzahl_Bytes_*1^100"
PPS: Warum Unterstriche? Leerzeichen sind doch auch erlaubt... ;)

Harald

GOTO ist weiterhin böse, wie schon zu BASIC-Zeiten. :ROFLMAO:

1. PS YEP
2. PS Unterstriche sorgen im "Normalfall" dafür, dass man keine Anführungszeichen beim Eingeben benötigt. Bei so einem Varaiblennamen mit Sonderzeichen bruacht man die dann aber doch wieder.
 
Was passieren soll, ist mir nicht wirklich klar.
Das scheint weder ein Fall für Case noch für If - Elseif - Else zu sein!
Beschreib Deine Aufgabe bitte so, dass sie nicht nur Dir klar ist!

Ich möchte einen Telegrammbaustein (FB) erstellen, ich will von Außen die Adressen vorgeben, die max Anzahl an Bytes die zu senden/empfangen sind. Das ganze soll Stück für Stück ablaufen (immer 100 Byte Schritte, erst Get dann PUT) und natürlich soll der nächste durchlauf erst statt finden können wenn der vorige beendet ist.

nein, das Case in SCL ist quasi nur ein hübsches if...elsif...elsif...elsif...else :-(
Wofür ist der ganze Zauber überhaupt? Möchtest du lediglich vermeiden, dass alle Gets parallel laufen?

Genau.

Case arbeitet nur bis zur nächsten Case-Bedingung, also in deinem Fall z.B. bei 9 bis vor 8:
PS: Abwärts zählend hab ich das noch nie gemacht ;-)
Wozu soll dene Vorgehensweise gut sein, was willst du erreichen mit dem case?

Das ist in einem FB, ich will von außen sagen können wie viele Daten ich versenden möchte, daher auch dieser name #"Anzahl_Bytes_*1^100.
Da ich dachte dass die Case of Anweisung so arbeitet, dass jeder "case" bearbeitet wird bis Exit (break;) kommt, wollte ich von Oben anfangen und somit mindestens der letzte "case" bearbeitet wird.

mit REPEAT- oder WHILE-Schleife um das CASE-Konstrukt und CONTINUE und EXIT. Oder so wie hier gezeigt: https://www.sps-forum.de/simatic/90599-v15-scl-goto-befehl-verwenden-3.html#post681007
PS: es ist mir schleierhaft wie man als professioneller Programmierer sich solche Variablennamen ausdenken kann (und Siemens das auch noch zulässt): #"Anzahl_Bytes_*1^100"
PPS: Warum Unterstriche? Leerzeichen sind doch auch erlaubt... ;)
Harald

Ich glaube ich werde das ganze einfach mit IF n>=7 ect. lösen. Wird wohl das einfachste sein, dachte die Case of Anweisung wäre eine saubere und schöne möglichkeit dafür.
Den Variablen Namen werde ich nochmal ändern ;) Danke sehr an alle die geantwortet haben :)
 
Zurück
Oben