@Zottel: Mit Verlaub, aber das ist Blödsinn.
So, das mußte ich jetzt überprüfen, inwieweite es Blödsinn ist...Ergebnis: Es ist TEILWEISE Blödsinn.
Ich habe also beide Schleifen auf einer 315 getestet.
Die Durchläufe mußte ich auf 50 reduzieren, mit 100 bekam ich Zykluszeit-Überschreitungen.
Das wesentliche, was ich Hawkster mitteilen wollte, war eigentlich:
Seine Schleife hat einen bedingten Aussprung und danach einen unbedingten Rücksprung.
Wegen dem U( wird sein bedingter Aussprung ausgeführt, wenn das unmittelbar vor dem Vergleich vorliegende VKE 1 ist UND der Schleifenzähler >= 100.
Ist das VKE davor 0, so wird der Aussprung nie ausgeführt.
Meine geänderte Schleife würde stattdessen in dem Fall die Schleife einmal und den Rücksprung nie ausführen. Das wäre immerhin einfacher zu beobachten.
Meine Schleife, M76.0 bestimmt das VKE beim Eintritt:
Code:
U M 76.0
L 0
T #TEMP0
M001: NOP 0
L #TEMP0
L 1
+I
T #TEMP0
U(
L 50
L #TEMP0
>I //
// <=I
)
SPB M001 //
// SPB M002
// SPA M001
M002: NOP 0
L #TEMP0
T MW 84
Diese Schleife wiederholt nur, wenn M76.0 =1, dann steht 50 im MW84, sonst 1.
Mein Satz über seine Version "In diesem Fall führt ein beim Eintritt in die Schleife gelöschtes VKE dazu, daß der Sprung zu LE01 nie ausgeführt wird."
ist Blödsinn. Der Grund ist aber subtil. Zitat aus der Hilfe zu SPB:
"Wenn VKE = 0, wird der Sprung nicht ausgeführt. Das VKE wird auf "1" gesetzt, und der Programmablauf wird mit der folgenden Anweisung fortgesetzt."
Wenn also Hawksters Schleife den 1. Durchlauf absolviert, stößt sie in jedem Fall auf eine unerfüllte Bedingung. SPB springt nicht, setzt aber das VKE auf 1.
Der nächste und alle weiteren Durchläufe verknüpft diese 1 mit dem Ergebnis des Vergleichs, so daß der Abbruch und die Schleife funktionieren.
Resultat:
1. Ich habe dazugelernt. SPB beeinflußt das VKE.
2. Das hat wahrscheinlich keinen praktischen Wert für Hawkster, weil sich in dem "Aktionsteil" andere Operationen befinden, die das VKE beeinflußen.
3. Ich habe nochmal dazugelernt. Ich hatte Bedenken bei CLR. Funktioniert aber, weil: CLR setzt nicht nur VKE auf 0 (was ALLEINE für Hawkster fatal wäre), sondern auch /ER auf 0, so daß das U(
nicht keine Erstabfrage ist, also zur Erstabfrage wird und damit de facto das VKE aus dem Vergleich GELADEN und nicht VERKNÜPFT wird.
4. Eine möglichst einfache Programmierung ist immer vorzuziehen.
Hier sind überflüssig:
- U( für die "Schönheit"
- der bedingte Aussprung gefolgt vom unbedingten Rücksprung. Ein bedingter Rücksprung reicht.
Etwas anderes wäre es, wenn Hawkster im "Aktionsteil" eine Zusatzbedingung auswertet. Allerdings wäre dann typischerweise ein "ODER" für den Abbruch oder ein "UND" für die Fortsetzung zu erwarten:
Zutreffenden Datensatz gefunden ODER alle Datesätze durchsucht, dann abbrechen.
Zutreffenden Datensatz NICHT gefunden UND nocht nicht alle Datesätze durchsucht, dann nächster Schleifendurchlauf.
@Hawkster:
Ich halte nicht viel von Schleifen in einem SPS-Programm. Insbesondere, wenn die Anzahl der Durchläufe variabel ist, bergen sie die Gefahr, daß ein programm plötzlich nicht mehr die "Echtzeitanforderungen" erfüllt. Halte mich für arrogant, aber zu 95% gehe ich davon aus, das du die nicht brauchst.
Ich habe deinen Code nur "quergelesen". Aber wenn die Mehrzahl der Daten nicht in jedem Zyklus neu sind, ist es häufig vorteilhaft, zu überlegen, in welcher Weise die neuen Daten dem alten Ergebnis hinzugefügt werden können.
Ein Beispiel:
Vor Jahren habe ich hier mal den Bubblesort-Algorithmus in S7-AWL gepostet, weil jemand eine Tabelle für Pumpenlaufzeiten sortieren wollte. Er schaltet eine Pumpe aus, addiert die absolvierte Laufzeit zur Gesamtlaufzeit dieser Pumpe und sortiert, um beim nächsten Mal diejenige Pumpe einzuschalten, die am wenigsten gelaufen hat.
Für seine 5 oder 7 Pumpen ist es belanglos, aber für 100 Pumpen sind es 4950 Durchläufe der inneren Schleife (nimmt mit n^2-n/2 zu).
Der effizientere Weg ist dann:
- Den neuen Platz mittels "binary search" ermitteln.
- Alle alten Vorgänger in eine neue Tabelle kopieren
- Alle neuen Vorgänger kopieren
- Datensatz dahinter einfügen
- alle Nachfolger dahinter kopieren.