TIA Rückwärts FOR Schleife in SCL steht still

jackoherra

Level-1
Beiträge
7
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Würde bereits gelöst. Vielen Dank an alle.

------------
Hallo zusammen.
Ich bin neu hier und freue mich auf neue Eindrücke und Erfahrungen.

Nun zu meinem Problem.

Ich habe in SCL eine Rückwärts FOR Schleife programmiert die aber leider einfach nicht rückwärts zählen möchte.

Code:
IF #MOVE_DATABLOCK_M1_P THEN    #Blockschmierer_1 := TRUE;
END_IF;


IF #MOVE_DATABLOCK_M2_P THEN
    #Blockschmierer_2 := TRUE;
END_IF;


IF #Blockschmierer_1 THEN
    FOR #i1 := 199 TO 1 BY -1  DO
        #i1_Schmier := #i1 - 1;
        "DB_Mengenmessung".Archiv_Daten[#i1] := "DB_Mengenmessung".Archiv_Daten[#i1_Schmier];
        "DB_Mengenmessung".Archiv_Daten_M1[#i1] := "DB_Mengenmessung".Archiv_Daten[#i1_Schmier];
    END_FOR;
END_IF;


IF #i1 = 1 THEN
    "DB_Mengenmessung".Archiv_Daten[0] := "DB_Mengenmessung".Aktuelles_Rohr_M1;
    "DB_Mengenmessung".Archiv_Daten_M1[0] := "DB_Mengenmessung".Aktuelles_Rohr_M1;
    #Blockschmierer_1 := FALSE;
END_IF;


IF #Blockschmierer_2 THEN
    
    FOR #i2 := 199 TO 1 BY - 1 DO
        #i2_schmier := #i2 - 1;
        "DB_Mengenmessung".Archiv_Daten[#i2] := "DB_Mengenmessung".Archiv_Daten[#i2_schmier];
        "DB_Mengenmessung".Archiv_Daten_M2[#i2] := "DB_Mengenmessung".Archiv_Daten[#i2_schmier];
    END_FOR;
END_IF;


IF #i2 = 1 THEN
    "DB_Mengenmessung".Archiv_Daten[0] := "DB_Mengenmessung".Aktuelles_Rohr_M2;
    "DB_Mengenmessung".Archiv_Daten_M1[0] := "DB_Mengenmessung".Aktuelles_Rohr_M2;
    #Blockschmierer_2 := FALSE;
END_IF;

Die Anweisung stellt eine Kombination dreier Schieberegister dar welches je 200 Datensätze beinhaltet. Eins für alle Daten und jeweils eins für Maschine 1 und Maschine 2.

Kann hier jemand irgend einen schwerwiegenden Fehler entdecken warum diese Schleifen nicht laufen?

Status wurde life beobachtet. Alle schleifen stehen beim Anfangswert von 199. Was ich noch feststellen konnte ist, dass die erste Zeile der Schleife bearbeitet wird.
ov4uigMqCAAiAAAiAAAiAAAiAQERgEqEc2cQhCIAACIAACIAACIAACFw8AQjli 9CNAAEQAAEQAAEQAAEQOAQBCCUD0EVNkEABEAABEAABEAABC6eAITyxXchGgACIAACIAACIAACIHAIAv8PqkKxY8iGdssAAAAASUVORK5CYII=

In diesem #i1_Schmier stehen schon die 198.

Ich hoffe jemandem fällt hier was ein.

Vielen Dank im Voraus.

Mit freundlichen Grüßen

Markus
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich denke, die Abfrage
Code:
[COLOR=#333333]IF #i1 = 1 THEN ...[/COLOR]
funktioniert nicht, weil bei den Rückwärtsschleife bis 1 #i von der FOR-Schleife noch auf 0 dekrementiert wird, bevor die Schleife komplett beendet wird.

Warum nimmst Du den Neueintrag nicht auch mit in die IF-Bedingung des #Blockschmierers?
Dann wäre diese IF-Abfrage eh' überflüssig.



PS:
Benutz' für Deinen Code bitte die [code]...[/code]-Tags, die Du auch mit dem letzten Button # der 2. Icon-Leiste erzeugen kannst.
Dadurch wird der Code deutlich lesbarer und auch Einrückungen sind möglich. [Edit:] Seh' grad, Du wolltest die Code-Tags verwenden, hast aber beim Abschluss versehentlich die [-Klammer gelöscht. [/Edit]
Und bei eingefügtem Code wird von der Forumssoftware oft in der ersten Zeile das Return gelöscht, so dass sich dann die 2. Zeile dort direkt anschließt.
Keine Ahnung, warum das so ist, aber ich muss dass auch dauernd wieder korrigieren und bei Deinem Code ist es auch der Fall.
Wär schön, wenn Du das oben noch alles korrigierst.
;)
 
Zuletzt bearbeitet:
Ich habe mir das Programm jetzt nicht genau angesehen, aber das die For-Schleifen in jedem Zyklus komplett durchlaufen werden und nicht nur schrittweise ist Dir bekannt?
Außerdem steht der Zähler der For-Schleife wie hucki schon schrieb am Ende der For-Schleife auf 0.
 
Zuletzt bearbeitet:
Ich habe mir das Programm jetzt nicht genau angesehen, aber das die For-Schleifen in jedem Zyklus komplett durchlaufen werden und nicht nur schrittweise ist Dir bekannt?

Genau hier liegt mein Denkfehler :D

Die Schleife wird ja mit einem Zyklus komplett durchlaufen somit kann ich sie später nicht abfragen.

Vielen Dank dafür

Hier die Änderung.

Code:
IF #MOVE_DATABLOCK_M1_P THEN    #Blockschmierer_1 := TRUE;
END_IF;


IF #MOVE_DATABLOCK_M2_P THEN
    #Blockschmierer_2 := TRUE;
END_IF;


IF #Blockschmierer_1 THEN
    FOR #i1 := 199 TO 1 BY -1  DO
        #i1_Schmier := #i1 - 1;
        "DB_Mengenmessung".Archiv_Daten[#i1] := "DB_Mengenmessung".Archiv_Daten[#i1_Schmier];
        "DB_Mengenmessung".Archiv_Daten_M1[#i1] := "DB_Mengenmessung".Archiv_Daten[#i1_Schmier];
    END_FOR;
    "DB_Mengenmessung".Archiv_Daten[0] := "DB_Mengenmessung".Aktuelles_Rohr_M1;
    "DB_Mengenmessung".Archiv_Daten_M1[0] := "DB_Mengenmessung".Aktuelles_Rohr_M1;
    #Blockschmierer_1 := FALSE;
END_IF;


IF #Blockschmierer_2 THEN
    
    FOR #i2 := 199 TO 1 BY - 1 DO
        #i2_schmier := #i2 - 1;
        "DB_Mengenmessung".Archiv_Daten[#i2] := "DB_Mengenmessung".Archiv_Daten[#i2_schmier];
        "DB_Mengenmessung".Archiv_Daten_M2[#i2] := "DB_Mengenmessung".Archiv_Daten[#i2_schmier];
    END_FOR;
    "DB_Mengenmessung".Archiv_Daten[0] := "DB_Mengenmessung".Aktuelles_Rohr_M2;
    "DB_Mengenmessung".Archiv_Daten_M1[0] := "DB_Mengenmessung".Aktuelles_Rohr_M2;
    #Blockschmierer_2 := FALSE;
END_IF;
 
Zuletzt bearbeitet:
Servus,

du müsstest bei deiner IF Bedingung die Laufvariable #i auf gleich 0 Vergleichen.

Code:
IF #i = 0 THEN
;
END_IF;

Das liegt daran, dass die FOR-Schleife eine Kopfgesteuerte Schleife ist und bei jedem Durchlauf prüft, ob die Laufvariable sich noch innerhalb den angegebenen Grenzen befindet.

Edit: Zu spät.


Gesendet von iPhone mit Tapatalk
 
Status wurde life beobachtet. Alle schleifen stehen beim Anfangswert von 199. Was ich noch feststellen konnte ist, dass die erste Zeile der Schleife bearbeitet wird.
ov4uigMqCAAiAAAiAAAiAAAiAQERgEqEc2cQhCIAACIAACIAACIAACFw8AQjli 9CNAAEQAAEQAAEQAAEQOAQBCCUD0EVNkEABEAABEAABEAABC6eAITyxXchGgACIAACIAACIAACIHAIAv8PqkKxY8iGdssAAAAASUVORK5CYII=

In diesem #i1_Schmier stehen schon die 198.
Live beobachtet? Kannst Du denn sooo schnell gucken? Und kann Dein Bildschirm sooo schnell die Änderungen wiedergeben?
199 SchleifenDurchläufe innerhalb eines Bruchteils einer PLC-Zyklus-Zeit von x ms ... damit wäre selbst eine Fliege total überfordert.
Oder kannst Du die FOR-Schleife im Einzelschritt durchtackern?
Wenn Du den Inhalt des Arrays vor und nach dem Durchlaufen der Schleife kennst und beide vergleichst, dann hast Du eine Chance, zu sehen, ob die Schleife funktioniert hat. ;)
 
Was mir hier noch aufgefallen ist (ich weiß aber nicht ob es Relevanz hat) :
Der Hilfsmerker "Blockschmierer_1" (bzw. 2) ist ja von der Variablen "MoveDataBlock" abhängig. Steht diese Variable wirklich nur für einen Zyklus an ? Also ist hier ein Flankenmerker mit im Spiel ? Ansonsten würde die ganze Schiebe-Geschichte mit großer Wahrscheinlichkeit so einige Male aufgerufen werden ... Ich denke aber mal, dass hier immer nur einfach verschoben werden soll ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was mir hier noch aufgefallen ist (ich weiß aber nicht ob es Relevanz hat) :
Doch, doch, grosse Relevanz, Larry!
Jedenfalls, wenn es darum geht, ob die Schleifen in mehreren aufeinander folgenden Zyklen durchlaufen werden sollen oder nicht.
Keine Relevanz aber bezüglich der vermutlich falschen Beobachtung, dass die Schleifen angeblich gar nicht durchlaufen werden.
Überflüssig sind aber die Hilfsmerker allemal. Ihr Gesetztwerden durch die If-Abfragen und ihr Rückgesetztwerden nach dem Eintragen des neuen Wertes in das erste (eigentlich nullte) ArrayElement bewirkt rein gar nichts, was sich von einer direkten Abhängigkeit der SchleifenDurchläufe von den If-Abfragen unterscheiden würde.
Diese Hilfsmerker suggerieren lediglich beim Überfliegen des Codes, dass hiermit eine FlankenAuswertung stattfindet ... was aber nicht der Fall ist.
 
Zuletzt bearbeitet:
Naja ... ich hätte das auch eher als Flanken-Geschichte aufgezogen ...
Möglicherweise ist es ja auch so, dass diese Schleifen so oft durchlaufen werden das dadurch das erwartete Ergebnis auch nicht erzielt wird.
Vielleicht zur Vollständigkeit : ich hätte das Ganze so aufgezogen :
Code:
IF MoveDataBlock and not FM_MoveDataBlock then
   // jetzt die Schleife und dann die Zuweisung am Ende ausführen
END_IF ;
FM_MoveDataBlock := MoveDataBlock ;   // dieser Flankenmerker muss natürlich eine statische Variable sein (also kein TEMP)

Gruß
Larry
 
Zurück
Oben