Step 7 IEC-Timer und andere Ärgernisse

Lord Helmchen

Level-2
Beiträge
19
Reaktionspunkte
6
Zuviel Werbung?
-> Hier kostenlos registrieren
Seid Gegrüßt,

Ihr Programmierer und Leidensgenossen. Nach meinem ersten Beitrag zur neuen „Firmen-Norm“ hat sich einiges getan.
Auch wenn es sehr schleppend ging, sind mehrere Projekte ohne S5-Timer und fast ohne Merker abgewickelt worden. Ganz auf Merker zu verzichten, scheint Siemens nicht vorgesehen zu haben. Das Taktmerkerbyte kann z. B. nicht direkt in einen DB geschrieben werden!

Den ganz großen Mehrwert der neuen Strategie hab ich noch nicht erkennen können.
Es gibt dadurch mehrere Probleme, für die es scheinbar keine Lösung gibt:
  • IEC-Timer scheinen Probleme zu bekommen, wenn die Instanz recht groß wird. Gibt es eine maximale Größe, die nicht überschritten werden darf? Ist das auch noch CPU-abhängig?
  • IEC-Timer in Instanzen können nicht global gefunden werden. „Gehe zur Verwendungsstelle“ greift nicht.
  • Wenn während der Inbetriebnahme nur eine Variable in der Instanz ergänzt wird, gehen bei der Übertragung vom IDB automatisch dessen Aktualdaten verloren! Das war schon immer so, nur war es bei Verwendung von Merkern und S5-Timer nicht notwendig, die Instanz so oft zu übertragen. Wie geht Ihr damit um?

Da es bis zu meinem planmäßigen Ruhestand noch ein Weilchen ist, würde ich das noch gerne in Griff bekommen.
Für konstruktive Lösungsvorschläge bin ich Euch sehr dankbar.

Eure Lordschaft
 
"Gehe zur Verwendungsstelle" bzw. vernünftige Referenzdaten sind für mich ein Muss.
Daher arbeite ich überwiegend mit Global-DBs als "Merkerersatz"
Das Thema Aktualwerte bei Instanz-DBs ist leider nervig. Ich lege mir für die Inbetriebnahmephase entsprechende Reservebereiche mit ein paar Timern, Ints und Bools an.
Die werden am Ende bereinigt. Wenn's gar nicht anders geht, dann wird halt doch in prov. S5-Timer eingefügt und in einer ruhigen Minute gegen IEC getauscht.

Gruß
Dieter
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich geh mal deine Punkte nacheinander durch:

1. Gehts detaillierter? Was für Probleme hast Du?
2. Naja mit IDBs verhält es sich wie mit dem Fightclub. Und dort besagt Regel 1: Was im Fightclub passiert bleibt im Fightclub.
Zugriffe von außen auf IDBs wird als "schmutzig" und "schlechter Stil" angesehen - es gibt ein paar Ausnahmen wie z.B. Instanzierung von Aggregaten wo die Visu über die IDB Nummer indirekt IDB Werte verändert, aber im Programm sollte ein FB immer über die Schnittstelle (IN/OUT) bedient werden. Somit fällt dein Querverweisthema weg. Verwende globale DBs für globale Timer - Der Vorschlag von Blockmove einen GDB mit Reserve zu nutzen ist hier gut.
3. Wenn es hilft. Online gehen -> DB nach offline kopieren -> Änderung machen -> einspielen. Wenn natürlich die Anlage dabei weiterläuft (was aber bei manchen Änderungen eh nicht sinnvoll ist hilft das nur bedingt.

Grüße

Marcel
 
  • IEC-Timer scheinen Probleme zu bekommen, wenn die Instanz recht groß wird. Gibt es eine maximale Größe, die nicht überschritten werden darf? Ist das auch noch CPU-abhängig?
1. Gehts detaillierter? Was für Probleme hast Du?

Der IEC-Timer läuft nicht, obwohl ich sehe, dass am „In“ eine „1“ anliegt. Ebenso konnte ich beobachten, dass er nach langem hin und her dann am „Q“ eine „1“ ausgegeben hat, die spätere Abfrage 3 Zeilen weiter unten „U TonInstanzYX.Q“ war aber wieder auf „0“.
Das war eine Konstellation mit 2 Timer (Unterschiedliche Instanzen!), die ich leider wieder verworfen habe und vermutlich nicht mehr nachgestellt bekomme. Nächstes mal mach ich ein Bildchen, wenn ich der Meinung bin, dass kann oder darf nicht sein. Vielleicht wird das dann peinlich für mich, aber sonst komme ich ja nicht weiter.

Ursprünglich wollte ich folgendes Beispiel umsetzen. Ein Pulsgeber für die Inbetriebnahme, der alle x Sekunden für einen Zyklus „1“ wird:

Code:
UN   #TonInstanzYX.Q
=    #TonInstanzYX.In

CALL  #TonInstanzYX
      IN:=
      PT:=#tPeriodeYX          // x = 30ms bis 1000ms
      Q :=
      ET:=

3 Zeilen weiter wird ein INT hochgezählt, an dem ich sehen kann, ob der Timer klackert.
Das lief nicht – dann hab ich angefangen den „Q“ mit Merker zu beschaltet um oben wieder einzulesen – ging auch nicht.
Aus Verzweiflung habe ich die Instanz eingekürzt, neu übersetzt und siehe da – der Timer klackert!

Kann das mit der Größe der Instanz zu tun haben? Laut Handbuch hat die CPU IM151-8F 64kB maximale Baustein-Größe, die ich bestimmt nicht überschritten habe!

Ähnliches Verhalten hatte ich schon mehrfach. Leider kann ich im Nachhinein nicht mehr genau nachvollziehen, an was es denn gescheitert ist.
 
Nicht laufende IEC-Timer kommen vor, wenn die Instanz nicht zum FB passt.
Also wenn du z.B. Definitionen aus dem Schnittstellenbereich des FB löscht und so der Datenbereich für den IEC-Timer nach oben rutscht und du dann den FB OHNE neue erzeugten Instanz-DB überträgst. Für den IEC-Timer passen dann die internen Zustände nicht mehr und du bekommst ihn nicht mehr zum laufen.
Erst das Übertragen des passenden Instanz-DBs hilft dann.
Es gibt genügend Anwendungen, bei denen klassische Merker, Timer und Zähler den IEC-Varianten überlegen sind.

Gruß
Dieter
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Lord Helmchen.
Sprechen wir hier von TIA mit der 1200/1500? Weil dann wären dein Probleme zu erklären, siehe unten.
Wenn es Classic mit der 300/400 ist, dann kannst du meine Antworten unten vergessen. Könnte aber trotzdem nützlich sein es zu wissen bevor ihr (falls ihr) wechselt.

DER TEIL GILT FÜR TIA UND 1200/1500------------------------------------------------------------------------------------------------------------------------------------------------------------

Code:
UN   #TonInstanzYX.Q
Das erklärt eigentlich schon deine Probleme. Diese Zugriffe (wie sie auf der 300/400 kein Problem waren) solltest du dir abgewöhnen.

Die Instanzdaten eines Timers und damit auch die Ausgaenge werden bei der 1200/1500 NUR aktualisiert ,in Momenten in denen entweder .Q oder .ET abgefragt wird.
Der IEC-Timer läuft nicht, obwohl ich sehe, dass am „In“ eine „1“ anliegt.
Ebenso konnte ich beobachten, dass er nach langem hin und her dann am „Q“ eine „1“ ausgegeben hat, die spätere Abfrage 3 Zeilen weiter unten „U TonInstanzYX.Q“ war aber wieder auf „0“.
Genau das war gemeint.
1. Wenn du einen Timer-Baustein (z.B. TON) einfügst ohne die Ausgänge zu beschalten oder zumindest wo anders zyklisch .Q oder .ET abfragst, dann werden die Instanzdaten des Timers nicht aktualisiert.

IEC-Timer auf der 1200/1500 arbeiten nicht mehr wie die klassischen SFBs in der 300/400.
Die Timer und vor allem der Zeitablauf (also die Berechnung "aktuelle Zeit minus Startzeit") passiert möglicherweise durch das Betriebssystem und nicht durch den TON-Baustein.

Könnte auch sein dass der Compiler bei der Abfrage von .Q einen entsprechenden Codeteil an die Stelle im SPS-Programm schreibt welcher die Berechnung macht und die Instanzdaten aktualisiert.
Vielleicht kompiliert er auch einen vollen TON-Aufruf an die Stelle und die Zeitberechnung steckt nach wie vor im TON-Baustein.
Das halte ich aber für unwahrscheinlich da ein TON-Aufruf ohne Zuweisung von Q auf eine Variable ebenfalls keine Aktualisierung vornimmt.
Die genaue Mechanik kennt glaub ich keiner.

Man kann jedoch definitiv sagen dass die Zeitberechnung und Instanzaktualisierung nicht mehr ausschließlich dort passiert wo man den TON-Baustein selber aufruft.
Die Aktualisierung passiert an jedem Ort wo ein Lesezugriff auf .ET oder .Q stattfindet.
Die 1500er IEC Timer sind wie Schrödingers Katze, wenn du den .Q nicht abfragst, kann er entweder 0 oder 1 sein.... :ROFLMAO:


2. Dass das mehrmalige Abfragen des .Q im Zyklus dass du schilderst führt dann eben genau zu mehreren Aktualisierungen
Damit wird es auch möglich dass .Q bei der zweiten Abfrage einen anderen Zustand annimmt als bei der Ersten.​
Das hast du, so wie du oben schreibst, ja auch schon beobachtet.​

Ursprünglich wollte ich folgendes Beispiel umsetzen. Ein Pulsgeber für die Inbetriebnahme, der alle x Sekunden für einen Zyklus „1“ wird:
Code:
UN   #TonInstanzYX.Q
=    #TonInstanzYX.In     

CALL  #TonInstanzYX
      IN:=
      PT:=#tPeriodeYX          // x = 30ms bis 1000ms
      Q :=
      ET:=
Genau dass ist die Programmierweise die du dringendst verwerfen musst.
Erstens funktioniert die direkte Verknüpfung von .Q und .IN nicht. Warum auch immer, muss wohl wieder eine Eigenheit sein.
Zweitens handelst du dir alle möglich Probleme ein wenn es, bei mehreren .Q abfragen, zu unterschiedlichen Ergebnissen kommt.
Die einzig sichere Variante ist folgende.
Code:
UN   Ton1_Signal
=    #TonInstanzYX.In          // Bin mir nicht mal sicher wie sich das verhält., kann sein dass der Timer schon in dem Moment startet...

CALL  #TonInstanzYX
      IN:=
      PT:=#tPeriodeYX          // x = 30ms bis 1000ms
      Q :=Ton1_Signal
      ET:=

//SOME CODE
U Ton1_Signal

//SOME CODE
U Ton1_Signal

//SOME CODE
U Ton1_Signal
Du darfst die IEC_TIMER keinesfalls mehr als einfache Bausteine betrachten.
Warum dies von BigS so gestaltet wurde ist unklar. Vermutung ist dass die "etwas weniger erfahrenen" Programmierer den TON-Baustein endlich in eine IF-Abfrage packen können.
Vielleicht auch um das Verhalten an die S5-Timer (Aktualisierung im Zyklus) anzugleichen.

Das Timer-Verhalten (und andere Unterschiede) wurden hier schon vielfach diskutiert.
http://www.sps-forum.de/simatic/79662-umstieg-auf-s7-1500-a-post601632.html#post601632


_
 
Zuletzt bearbeitet:
DIE ANTWORT BEZIEHT SICH EBENSO AUF TIA UND 1200/1500 -----------------------------------------------------------------------------------------------------------------------
  • IEC-Timer scheinen Probleme zu bekommen, wenn die Instanz recht groß wird. Gibt es eine maximale Größe, die nicht überschritten werden darf? Ist das auch noch CPU-abhängig?
  • IEC-Timer in Instanzen können nicht global gefunden werden. „Gehe zur Verwendungsstelle“ greift nicht.
  • Wenn während der Inbetriebnahme nur eine Variable in der Instanz ergänzt wird, gehen bei der Übertragung vom IDB automatisch dessen Aktualdaten verloren! Das war schon immer so, nur war es bei Verwendung von Merkern und S5-Timer nicht notwendig, die Instanz so oft zu übertragen. Wie geht Ihr damit um?

Zu 1:
Glaube nicht dass es da einen Zusammenhang gibt. Die Probleme kamen wohl vom geänderten Timerverhalten. Siehe vorigen Beitrag​
Zu 2:
Das solltest du sowieso nicht müssen. Warum sollte man auch von außen einen Querverweis auf das .Q eines Timers suchen der sich in einem Baustein-Inneren befindet.
Greift ihr von außen direkt auf die Ergebnisse (.Q bzw. ET) eines Timers zu der sich in einem anderen FB befindet?

Bei solchen Abfragen von Außerhalb enstehen sicher ganz "interessante" Konstellation wenn solche Zugriffe die Instanzdaten des IEC-Timers innerhalb des Bausteins aktualisieren...
Wenn ihr global auf Timer-Ergebnisse zugreifen wollt, dann legt das Timerergebnis bitte dort wo die Instanz bzw. der TON-Aufruf liegt auf eine Schnittstelle nach außen (OUT) oder auf eine Globalvariable.
Zu 3:
Ja das ist ein Problem, wie auch schon früher. Allerdings ist es insofern besser geworden dass man zumindest folgendes machen kann.


  1. [*=1]Momentanwerte des IDB als Startwerte übernehmen
    [*=1]Instanzdaten verändern
    [*=1]Einspielen
Beim Übersetzen behalten die Instanzen welche schon vorher da waren die Startwerte. Beim Überspielen und Reinitialisieren bekommen die "alten" Instanzen dann die Startwerte.
Wenn sich die Daten der Instanz nicht zu schnell bewegen ist dass zumindest eine Option.

Allerdings musste ich, wegen der Reinitialisierungswut von TIA, mir angewöhnen einige kritische Instanzen als Global-IDBs abzulegen. Was auch nicht schön ist.

Bevor man irgendwelche Hardware-S5-Timer (mit diesem grausigen S5T-Format) verwendet, kann man die 1500er-IEC-Timer auch ohne Ablage in einem IDB verwenden
Einfach irgendwo in einem Global-Datenbaustein ein "Array[1..x] of IEC_TIMER" anlegen und dieses verwenden.
Damit kann man jetzt die IEC_TIMER genauso wie einen S5T-Timer verwenden.
Siehe Beispiel: http://www.sps-forum.de/simatic/50733-sfb4-ton-sfb5-tof-usw-post533813.html#post533813

Nebenbei:
Noch ein weitere Unteschied zwischen 300/400 und 12/1500 ist dass ein Aufruf eines IEC-TIMER mit PT=T#0ms nicht mehr zum Reset führt, sondern wirklich eine Timer mit 0ms Verzögerung bringt.
Reset geht nur mehr über eine separate Funktion. Bei den ganzen Unterschieden werden Migrationen von 300/400er-Programmen sehr schwierig.
 
Zuletzt bearbeitet:
@Lord Helmchen.
Sprechen wir hier von TIA mit der 1200/1500? Weil dann wären dein Probleme zu erklären, siehe unten.
Wenn es Classic mit der 300/400 ist, dann kannst du meine Antworten unten vergessen. Könnte aber trotzdem nützlich sein es zu wissen bevor ihr (falls ihr) wechselt.

Nein, hier ist noch S7 Klassik im Einsatz. Schön wenn es in TIA dann wieder anders ist. Würde ja langweilig werden, wenn eine genormte Funktion überall gleich funktionieren würde.
Oh ich vergaß – nicht genormt, sondern an die Norm angelehnt! grrr.jpg

Zu den Ursprungsfragen:
  • Die Länge der Baustein-Instanz darf keine Auswirkung auf die Funktion vom IEC-Timer haben?
  • Für eine globale Verwendung und Nachverfolgbarkeit muss ich den Ausgang vom Timer auf eine Globale Variable legen?
  • Damit ich keinen Aktualdatenverlust erleide, deklariere ich einfach in jeder Instanz entsprechend viele unbenutzte Reserve-Timer?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zu den Ursprungsfragen:
  • Die Länge der Baustein-Instanz darf keine Auswirkung auf die Funktion vom IEC-Timer haben?
  • Für eine globale Verwendung und Nachverfolgbarkeit muss ich den Ausgang vom Timer auf eine Globale Variable legen?
  • Damit ich keinen Aktualdatenverlust erleide, deklariere ich einfach in jeder Instanz entsprechend viele unbenutzte Reserve-Timer?

Lord Helmchen,

zu deinen Ursprungsfragen:
- Ja
- Ja
- Ja, oder jedes Mal umständlich die Aktualdaten retten (siehe oben) :rolleyes:

LG Cassandra
 
Lord Helmchen,
- Ja, oder jedes Mal umständlich die Aktualdaten retten (siehe oben) :rolleyes:

Kannst du mir das Vorgehen schildern?
Ich habe gerade gestern wieder geflucht. Ich generiere einen globalen DB per Quelle (DB für HMI, SCADA etc). Da habe ich viele meiner Sollwerte/Betriebsstunden etc drin. Jetzt habe ich ihn verlängert weil ich mehr daten Brauche. Da er verlängert wurde und die Quelle also wieder übersetzt werden muss. Ist der Baustein nun unterschiedlich. Ich kann keinen Aktualdatenabzug mehr machen, ich kann ihn ja nichtmal vom Laden ausnehmen weil er nur noch konsistentes Laden anbietet und dann verliere ich alle meine Betriebsstunden, sollwerte etc.

Ich bin mitlerweile dazu übergegangen das ein Baustein für Sollwerte und Betriebsstunden diese in ein Merker sichert und wenn die Daten im DB 0 werten (durch Laden des DBs) dann werden die Werte aus dem Merker wieder in den DB zurückgeschrieben.
Zum heulen solcher Murks. Der DB kann auch nicht optimiert sein da HMI drauf zugreifen soll. Also lässt sich Laden ohne Reinit nicht einstellen.

mfG René
 
Wir hatten mal als Konzept angedacht, ein externes Tool zur DB-Quellengenerierung schreiben, welches einen S7-Treiber beinhalltet. Dieses Tool verbindet sich mit der S7, liest die Aktualwerte aus und übernimmt diese in die (Excel-)Liste... dann Liste erweitern und Quelle wieder generieren, incl. alter Aktualwerte...

Falls sich die bestehenden Bereiche im DB nicht ändern, könnte das Tool auch vor dem Generieren der erweiterten AWL-Quelle die Aktualwerte der bestehenden Datenbereiche auslesen und in die Quelle mit einarbeiten...

Aber mehr als ein Konzept ist es noch nicht.

Du kannst natürlich den DB rücklesen und dann ne Quelle exportieren... Aber die Quelle krigst Du vermutlich nicht in Deine (Excel-)Liste. Dafür könnte mal aber evtl. auch nen Tool schreiben, oder das gibt's irgendwo.

Programmierst Du mit TIA oder Step7? Welche Steuerung?

Gruß.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich programmiere beides. Das Problem hab ich aber natürlich nur mit TIA, denn in Step7 hab ich den HMI/SCADA DB einfach richtig gross definiert und lade den nie wieder in die CPU. TIA will aber halt sobald die Quelle neu übersetzt wurde (auch wenn sich nur Symbole oder Texte geändert haben) den DB neu laden und natürlich auch reinitialisieren.
Mir würds ja reichen wenn der DB sich aus der Konsistenzprüfung ausnehmen liesse und nicht automatisch mit in den Download genommen würde.

mfG René
 
Ich bin kein Freund der Übernahme der Aktualwerte vom Arbeitsspeicher in den Ladespeicher, weil dann diese Werte die Anfangswerte bei Urlöschen sind. Ich will kontrolliert vorgeben können, mit welchen Werten das SPS-Programm nach Urlöschen beginnt. Es können ja z.B. Schrittketten oder Fehlermeldungen oder von der HMI parametrierbare Grenzwerte in den DB sein, die nach einem Urlöschen eben nicht die Werte von einer laufenden Anlage sein sollen, sondern es sollen vernünftige/getestete Anfangswerte sein, die auch oft absichtlich 0 sein sollen.


Wenn ich in Step7 classic DB oder FB/IDB erweitert habe und ich mußte die vorhandenen Aktualdaten (zyklusgenau) beibehalten, dann habe ich zuerst am Ende des OB1 ein BLKMOV des vorhandenen DB in einen anderen (zusätzlichen temporären) DB eingefügt, danach am Anfang des OB1 einen BLKMOV aus dem zusätzlichen DB zurück in den Arbeits-DB. Danach konnte ich problemlos den neuen erweiterten DB einspielen ohne die Aktualwerte zu verlieren. Ich vermute mal, daß dieses simple Vorgehen unter TIA wohl nicht mehr möglich ist (TIA mit dem unbedingten Willen zum konsistenten Laden mit Initialisieren, vom vermutlich nicht mehr möglichen BLKMOV ganz abgesehen).

Harald
 
Ich bin kein Freund der Übernahme der Aktualwerte vom Arbeitsspeicher in den Ladespeicher, weil dann diese Werte die Anfangswerte bei Urlöschen sind. Ich will kontrolliert vorgeben können, mit welchen Werten das SPS-Programm nach Urlöschen beginnt. Es können ja z.B. Schrittketten oder Fehlermeldungen oder von der HMI parametrierbare Grenzwerte in den DB sein, die nach einem Urlöschen eben nicht die Werte von einer laufenden Anlage sein sollen, sondern es sollen vernünftige/getestete Anfangswerte sein, die auch oft absichtlich 0 sein sollen.

Sehe ich genauso...

Aber, unter Step7 mit CFC gab es dafür eine schöne Lösung. Man konnte pro Baustein (für den IBD) das System-Bausteinattribut S7_read_back setzen und für jede einzelne Variable auch nochmal das Parameterattribut S7_read_back. Im CFC konnte man dann selektiv "rücklesen". Zumindest für einen CPU-Tausch, Urlöschen etc. hatte man die Werte im Projekt. Bei Änderungen/Erweiterungen von IDBs half das aber auch nicht, kommt im CFC aber auch seltener vor.

Im TIA hätte man ja sicherlich dafür eine intelligente Rücklesefunktion implementieren können, aber es ist so wies ist...

Fürs DB-Quelleneinlesen würde dazu auch eine intelligente Auswahlmöglichkeit ("vorhandene Daten beibehalten ja/nein") dazugehören...

Da die Informationen ja alle symbolisch in ner Datenbank liegen, sollte das theoretisch sogar funktionieren...

Wie immer, die "Innovationen" vom TIA sind mehr Schein als Sein und beseitigen bei weitem nicht die allgemein seit Jahren bekannten wichtigen Sorgen im Step7.

Gruß.
 
Zurück
Oben