Todes-Schleife...

Zuviel Werbung?
-> Hier kostenlos registrieren
Is genauson Befehl wie "INC", "DEC" usw. Befehle wos gibt aber man einfach nicht benutzt :)

Nur dass die Befehle nicht zum Spaß drin sind.
Zeitvergleich (CPU 317):

L 1 // 0,05 µs
+I // 0,2 µs

INC 1 // 0,1 µs

Bei deiner 100er Schleife sind das 25 µs zu 10 µs.

Ansonsten schau ich auch nicht so auf die Ausführungszeit, aber bei Schleifen ist das schon sinnvoll.
 
Code:
      L     0
      T     #LK_Temp.Zaehler
 
LP01: NOP   0
//==> Aktion Start
 
 
//==> Aktion Ende
 
      L     #LK_Temp.Zaehler
      L     1
      +I    
      T     #LK_Temp.Zaehler
 
      U(    
      L     100
      L     #LK_Temp.Zaehler
      <=I   
      )     
      SPB   LE01
      SPA   LP01
 
LE01: NOP   0
//FERTIG :D

In diesem Fall führt ein beim Eintritt in die Schleife gelöschtes VKE dazu, daß der Sprung zu LE01 nie ausgeführt wird.

@Zottel: Mit Verlaub, aber das ist Blödsinn.

@Hawkster: Kannst du mal noch die "Aktion" posten?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich kanns jetzt net testen, aber für dich mach ich morgen mal das U( ) raus. Das erklärt dennoch nicht, warums bei mir geht wenn ichs anschau, und bei anderen net...

Und dies ist nicht der Fehler weil das MW (mit dem wirs schon getestet haben) nie über die 100 kommt :) Und das er die Zusätzlich benötigten 65535 Zyklen durchführt, von denen Zufällig die Restlichen 32668 Zyklen (bei 32768 kommt ja Überschlag) das VKE 0 ist, um nicht rauszuspringen, ist unwahrscheinlich :D

Also ist das Prob wo anders :D
 
Ok... nun mal der Komplette Code (welcher Derzeit nicht drin ist).
Also ich nehm mal das komplette NW

Code:
      NOP   0
//#############################################################
//### Konfigurationen beschreiben
//#############################################################        
      L     100
      T     #LK_Temp.CNF_Schleifen_Anzahl

      L     23                          //0-23 (array)
      T     #LK_Temp.CNF_Leistungsklasse_Max

//#############################################################
//### Ablöschen der aktuellen Werte der Leistungsklassen
//#############################################################        
      L     0
      T     "DB_DH_Speicher_1".Leistungsklasse[1]
      T     "DB_DH_Speicher_1".Leistungsklasse[2]
      T     "DB_DH_Speicher_1".Leistungsklasse[3]
      T     "DB_DH_Speicher_1".Leistungsklasse[4]
      T     "DB_DH_Speicher_1".Leistungsklasse[5]
      T     "DB_DH_Speicher_1".Leistungsklasse[6]
      T     "DB_DH_Speicher_1".Leistungsklasse[7]
      T     "DB_DH_Speicher_1".Leistungsklasse[8]
      T     "DB_DH_Speicher_1".Leistungsklasse[9]
      T     "DB_DH_Speicher_1".Leistungsklasse[10]
      T     "DB_DH_Speicher_1".Leistungsklasse[11]
      T     "DB_DH_Speicher_1".Leistungsklasse[12]
      T     "DB_DH_Speicher_1".Leistungsklasse[13]
      T     "DB_DH_Speicher_1".Leistungsklasse[14]
      T     "DB_DH_Speicher_1".Leistungsklasse[15]
      T     "DB_DH_Speicher_1".Leistungsklasse[16]
      T     "DB_DH_Speicher_1".Leistungsklasse[17]
      T     "DB_DH_Speicher_1".Leistungsklasse[18]
      T     "DB_DH_Speicher_1".Leistungsklasse[19]
      T     "DB_DH_Speicher_1".Leistungsklasse[20]
      T     "DB_DH_Speicher_1".Leistungsklasse[21]
      T     "DB_DH_Speicher_1".Leistungsklasse[22]
      T     "DB_DH_Speicher_1".Leistungsklasse[23]
      T     "DB_DH_Speicher_1".Leistungsklasse[24]
      T     "DB_DH_Speicher_1".Leistungsklasse[25]

//#############################################################
//### Schleife 
//#############################################################        
      L     0
      T     #LK_Temp.Zaehler
      T     #LK_Temp.PTR_SRC_Leistungsklasse
      T     #LK_Temp.PTR_DEST_Leistungsklasse
      T     #LK_Temp.Leistungsklasse


LP01: NOP   0
//#############################################################
//### Aktion Start
//#############################################################        
//==> Pointer der Leistungsklassen-Quelle
      L     #LK_Temp.Zaehler
      L     50                          //<== Sprungweite
      *I    
      L     140                         //<== Start-Wert
      +I    
      L     P#1.0
      *D    
      T     #LK_Temp.PTR_SRC_Leistungsklasse

//==> Kopieren der Leistungsklasse in Temp-Var
      AUF   "DB_DH_Speicher_1"
      L     DBW [#LK_Temp.PTR_SRC_Leistungsklasse]
      T     #LK_Temp.Leistungsklasse

//==> Leistungsklasse im Toleranz-Bereich
      U(    
      L     0
      L     #LK_Temp.Leistungsklasse
      <=I   
      )     
      U(    
      L     #LK_Temp.Leistungsklasse
      L     #LK_Temp.CNF_Leistungsklasse_Max
      <=I   
      )     
      SPB   LVAL                        //Leistungsklasse Gültig (Valid)
      SPA   LINV                        //Leistungsklasse UnGültig (InValid)

LVAL: NOP   0
//==> Pointer der Leistungsklassen-Ziel
      L     #LK_Temp.Leistungsklasse
      L     2                           //<== Sprungweite
      *I    
      L     0                           //<== Start-Wert
      +I    
      L     P#1.0
      *D    
      T     #LK_Temp.PTR_DEST_Leistungsklasse

//==> Entsprechende Leistungsklasse um eins erhöhen
      AUF   "DB_DH_Speicher_1"
      L     DBW [#LK_Temp.PTR_DEST_Leistungsklasse]
      L     1
      +I    
      T     DBW [#LK_Temp.PTR_DEST_Leistungsklasse]

      SPA   LEND

LINV: NOP   0
//==> Unbekannte Leistungsklasse um eins erhöhen
      L     "DB_DH_Speicher_1".Leistungsklasse[25]
      L     1
      +I    
      T     "DB_DH_Speicher_1".Leistungsklasse[25]

      SPA   LEND

LEND: NOP   0

//#############################################################
//### Aktion Ende
//#############################################################        
      L     #LK_Temp.Zaehler
      L     1
      +I    
      T     #LK_Temp.Zaehler

      U(    
      L     #LK_Temp.CNF_Schleifen_Anzahl
      L     #LK_Temp.Zaehler
      <=I   
      )     
      SPB   LE01
      SPA   LP01

LE01: NOP   0

Können wir uns nun einmal von dem VKE0-Prob lösen und zum Thema zurückkehren.
Und ja, der Code funktioniert... solange ich ihn anschau :)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Na ich hoffe mal auf eine genauso spannende Fehlersuche/Disskusion wie heute!
Es macht echt Spaß in diesem Forum mitzulesen.Alle sind respektvoll und man kann was lernen.

Gruß Rene
 
Alle sind respektvoll
Träum weiter.Hier gibt welche die wissen nicht mal,dass es dieses Wort überhaupt gibt.
ist jetzt nicht auf dieses thema bezogen.
Gute nacht
 
ok... jetzt bin ich neugierig

2 Fälle:
Code:
U M0.0  //VKE0
U(
L 100
L #Zaehler
>=I
)
SPB Anfang
SPA ENDE
Code:
U M0.0  //VKE0
L 100
L #Zaehler
>=I
SPB Anfang
SPA ENDE
In meinen Augen geht beides in die Hose. Du jedoch behauptest der 2. Fall wird klappen...

Ok, Höre grade im unteren Fall wird nur der Vergleicher beim Absprung berücksichtigt.... das muss ich gleich ma Testen morgen :) Wenn Ja, Sorry all, dann habt ihr recht. Dennoch isses net das Prob
 
Zuletzt bearbeitet:
@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.
 
Zuletzt bearbeitet:
Also Zottel, Daumen hoch... mich hat das ja schon angefressen, aber dich hats ja jetzt total erwischt...

Bedingt dadurch, das es 4 Uhr nachts ist, komme ich derzeit nur noch bedingt hinterher.

Ich stelle jedenfalls fest, das du bis zum Erbrechen rumgetestet hast.

Zu der Schleife... klar es ist eine Ansichtssache. Ich weiß nur, das ich bedingt durch die Schleife Sinnvoll viel Code ersparen kann, ob die das Nun noch Aufsplitte ist ja alles möglich. Wie man es realisiert ist ja immernoch ein anderes Thema, weil es mir ja eigentlich um den Magischen Stop ging.

Was mir bei dir auffällt, du Spring bedingt zum Schleifen Anfang, ich hingegehn Springe bedingt zum Ende. Soweit klar... deine Methode (muss ich zugeben) ist auch Sauberer. Bloß ich muss mir morgen in Ruhe nochma das mit den VKE's durchlesen, weil ich da gerade nicht mehr durchsteige.

Aber eine Sache fände ich klasse. Wenn Zottel sich jetzt einen derartigen Aufwand gemacht hat zu Testen, schleifen und Ergebnissse gesammelt hat, würde ich sagen

VOTE 4 STICKY!

In diesem Sinne lege ich mich jetzt schlafen und werde morgen mal den VKE's hinterger-schleifen :D

Mit freundliche Grüßen,
Hawkster
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Hawkster,
ohne auf den Schleifeninhalt einzugehen, dass Problem ist mir auch bekannt. Nach meiner Erinnerung war ausschlaggebend, wo sich der Cursor beim "Brille-drücken" befand, innerhalb der Schleife => Zyklusüberschreitung, ausserhalb => ohne Problem. Wenn das Beobachten lief, konnte der Cursor in die Schleife gesetzt werden. Ich hatte damals allerdings innerhalb der Schleife beide Adressregister genutzt.
Aus den damaligen Hot-Line-Kontakten, ist dann ein FAQ entstanden. Evtl. krame ich mal das betreffende Projekt hervor.
mfG. Jo
 
es gibt noch einen weiteren "subtilen" Grund: SPB setzt /ER auf null.
Aber diese Erkenntnis wird dem TE nicht nützen :cry:

Hatten wir das nicht erst. In der Hilfe steht dazu, SPB ist VKE-Begrenzend. D.h. dann, daß nach einer Sprunganweisung, wenn diese ausgeführt wurde oder auch nicht, das VKE True ist und die nächste Abfrage auch eine Erstabfrage ist.
 
genau das hab ich mir beim durchlesen die ganze Zeit auch schon gedacht...

btw. ich hab den gleichen effekt vor ein paar Wochen auch festgestellt. War ne Schleife mit 128 durchgängen. Beim Beobachten ging die 314er in Stopp. Um die zu verhindern wurde die Schleife auf mehrere Runden aufgeteilt.
 
Also :)

Nach erneuten Rumforschen folgende Erkenntnis.

1. Ich musste das Programm um eine weitere Schleife (gleicher Grundaufbau) erweitern. Somit habe ich im oberen Netzwerk eine einfache Schleife und im unteren Netzwerk eine komplexe.
2. Ich kann diese Schleifen mit meinem Rechner problemlos beobachten.
3. Dennis hat seinen Rechner auf "Einzelplatz" gestellt. Leider ohne erfolg.
4. Wir haben das Programm in eine andere Steuerung gespielt. Gleiches Problem, ich kann es anschauen, der Rest der Welt nicht.
5. In der test-Steuerung ist aber aufgefallen: Normale Zykluszeit 12ms (30 bei F-CALL). Die Einfache Schleife konnten die anderen noch gerade so beobachten. Zykluszeit war dann bei 120-140ms. Sobald wir in die komplexe Schleife wechseln Zykluszeitüberschreitung. Nur nicht bei mir, da schwankt die Zykluzszeit immer nur um +/- 1ms.
6. Wir haben alle Schnittstellen ausprobiert. Alles erfolglos...
-> WLAN auf CP343
-> LAN auf CP343
-> Via einen Steckverbinder von Prozessinformatik auf die Profibus-Schnittstelle
-> Via einen Steckverbinder von Prozessinformatik auf die MPI-Schnittstelle

So, also und das mit dem U( ) ist auch draußen :) Geht genausowenig.

Zottel, eine Sache hat mich Stutzig gemacht... du sagtest deine 315 schafft die Schleife nur 50x? Hast du diese zu dem zeitpunkt beobachtet? Wenn ja... mach die Anzahl der schleifen ma auf 100 und Beobachte den Baustein nicht... weil 100 Schleifendurchgänge und dabei Nichtstun ist ein Witz (sogar für ne 315)... Ich mein, ich hab es nochmal mit meiner 317 hier versucht:

Folgende Randbedingungen:
-> Anwenderprogramm drinnen
-> F-Programm drin
-> Maximale Zykluszeit derzeit bei 78MS

Nun hab ich eine Schleife ohne jegliche Aktion integriert folgendes Ergebniss:
100 Zyklen -> 78 MS (Unverändert)
1.000 Zyklen -> 78 MS (Unverändert)
10.000 Zyklen -> 83 MS (Oh, es tut sich was :D)
20.000 Zyklen -> 93 MS (Ok... nun wirds brenzlig)
30.000 Zyklen -> 132 MS (Ja. da hat der F-Call wohl mit reingespuckt)
Aber was ich dir damit sagen will.... ich glaub ja alles... aber nicht das eine 315 bei ner 100 Zyklen-Schleife den Geist aufgibt....

Und wenn man Schleifen sowieso nicht Brauch :) Dann Prog mir mal nen Suchbaustein. Hab das ja schon gemacht... deswegen weiß ich das Schleifen eigentlich Oft gebraucht werden. Kommt auch wieder auf die Anwendung an.

PS: Aber immernoch gehts darum: WIESO GEHT DIE CPU !-B-E-I-M B-E-O-B-A-C-H-T-E-N-! IN STOP!

Mit freundlichen Grüßen,
Hawkster
 
Zuletzt bearbeitet:
Zottel, eine Sache hat mich Stutzig gemacht... du sagtest deine 315 schafft die Schleife nur 50x? Hast du diese zu dem zeitpunkt beobachtet?
Wenn ja... mach die Anzahl der schleifen ma auf 100 und Beobachte den Baustein nicht... weil 100 Schleifendurchgänge und dabei Nichtstun ist ein Witz (sogar für ne 315)... Ich mein, ich hab es nochmal mit meiner 317 hier versucht:
Aber was ich dir damit sagen will.... ich glaub ja alles... aber nicht das eine 315 bei ner 100 Zyklen-Schleife den Geist aufgibt....
Die Schleife hatte ich in einem FC7, der aus dem OB1 aufgerufen wurde. Ansonsten machte das Programm nicht viel.
Der FC7 wurde beobachtet.
Im OB1 prev_cycl_time nach MW kopiert, um es per L MW im FC7 beobachten zu können. FC7 wurde permanent beobachtet.
Zykluszeit 1 bis 4 ms.
Schleife auf 100 Durchläufe.
CPU geht auf Stop.
Auch nach Schalter STOp->RUN ging sie wieder auf Stop.
Im Diagnosepuffer steht dann was von Zyklusüberschreitung. Ein leerer OB80 war vorhanden. Ob die pure Anwesenheit reicht oder Nachtriggern nötig wäre, weiß ich nicht.
Das geschah unabhängig davon, WO das Beobachten anfängt, in der Schleife, oder im Nachfolgenetzwerk.
Es gab keinen signifikanten Unterschied zwischen Beobachten in der Schleife oder hinter der Schleife.
Ich habe nicht versucht, den Baustein nicht zu beobachten.
Ich weiß nicht, welche sonstigen Einstellungen (max.Zykluszeit?) verändert sind, außer maximale Kommunkationslast von 20%->50%.
Ich habe nicht versucht, die Schleife unbeobachtet ausführen zu lassen. Die CPU ist ein älteres Modell.
PS: Aber immernoch gehts darum: WIESO GEHT DIE CPU !-B-E-I-M B-E-O-B-A-C-H-T-E-N-! IN STOP!
Prinzipiell speichert die CPU während der Ausführung die Ergebnisse der einzelnen Schritte, um sie dann gesammelt zum PG zu schicken.
 
Zurück
Oben