TIA Anfängerfragen über Timer, Fehlerauswertung, Code mehrfach verwenden

ex0dus

Level-1
Beiträge
11
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo liebes Forum,

mein Name ist Ahmed, bin 18 Jahre alt. Zur SPS-Programmierung bin ich durch meine Schule gekommen und habe nun bei einer freiwilligen SPS-Projekt mitgemacht.
Da ich noch ein blutiger Anfänger in der SPS-Programmierung bin, würde ich mich sehr über eure Hilfe freuen.

Problem #1:

Mein Projekt besitzt ein Auslaufband, welches 2x starten muss:
1.Fall: Schieber fährt los, Auslaufband startet und schaltet sich nach einer gewissen Zeit ab.
2. Fall: Der Sensor am Ende erkennt das entfernen eines Objektes und fährt für eine gewisse Zeit nach.

Dazu habe ich auch einen Code geschrieben:
Code:
// Hauptfunktion
"timer_auslaufband_fahrzeit".TOF(IN := "Daten_DB".schieber2_belegt,
                                 PT := "Zeiten_DB".zeit_auslaufband_fahrzeit,
                                 Q => #auslaufband);
// Objekt angekommen und abholbereit
"pos_flankenerkennung_objekte_abholbereit"(CLK := "timer_auslaufband_fahrzeit".Q);
IF "pos_flankenerkennung_objekte_abholbereit".Q THEN
    "Daten_DB".objekte_abholbereit_anzahl := "Daten_DB".objekte_abholbereit_anzahl + 1;
END_IF;




// Objekt wurde entfernt und Station fährt nach
"neg_flankenerkennung_objekte_abholbereit"(CLK := #auslaufband_belegt);
"timer_auslaufband_nachfahren".TOF(IN :="neg_flankenerkennung_objekte_abholbereit".Q AND"Daten_DB".objekte_abholbereit_anzahl > 0,
                                   PT := T#500ms,
                                   Q => #auslaufband);


IF "neg_flankenerkennung_objekte_abholbereit".Q AND "Daten_DB".objekte_abholbereit_anzahl > 0 THEN
    "Daten_DB".objekte_abholbereit_anzahl := "Daten_DB".objekte_abholbereit_anzahl - 1;
END_IF;

Mein Problem nun: Je nachdem welcher der beiden Timer weiter unten im Code ist, funktioniert nur dieser. Abhilfe?

Problem #2:

In meinem Projekt sind mehrere Fehlererkennungen, die je eine Fehlervariable in meinem Fehler_DB setzt. Nun möchte ich, wenn einer dieser Variablen gesetzt wird, dass alle meine Outputs auf 0 gesetzt werden.
Könnte mir jemand erklären, wie man das am Besten macht?

Problem #3:

In meinem Projekt besitze ich 2 FB's die zu 90% gleich sind und viele andere Stellen wo der Code auch schonmal vorgekommen ist. Mein Lehrer meinte, man könnte diesen Code öfter verwenden und man bräuchte das Programm nicht öfter schreiben. Da ich aber immer andere Variablen habe und so auch keine Idee wie das funktioniert, würde ich mehr sehr freuen, wenn auch das mir jemand erklären könnte.

Danke im Vorraus.

Lg
 
zu #1

Beide Timer haben die selbe Outputvariable.
Der letzte gewinnt immer, denn sein Ergebnis überschreibt das des vorhergehenden (ist ja der selbe Ausgang).

2 Möglichkeiten:

1. Je eine Temp- oder Star-Var an den Ausgang des Timers. Dann nach beiden Timern im Code

#Auslaufband := TimerOut1 OR TimerOut2

2. Timer-Output nicht beschalten und nach den beiden Timern im Code

#Auslaufband := "timer_auslaufband_fahrzeit".Q OR "timer_auslaufband_nachfahren".Q

zu #2

1. Ganz am Ende des Bausteins:

If #FEHLER Then

#Auslaufband := False;
...

END_IF;

Alle Ausgangsvariablen werden dann mit False überschrieben.

oder

2. schon in der Zuweisung

#Auslaufband := (TimerOut1 OR TimerOut2) AND NOT #FEHLER

zu #3

Als Variablen verwendest du Input, Output, INOUT, TEMP und STAT, keine externen Variablen aus DB, Merker oder Timer.
Das heißt, du mußt die Timer im FB in den Stat-Var deklarieren und dann diese Timer im Baustein verwenden. Alle Variablen von "Außen"
mußt du ja nach Verwendung als Input, Output oder INOUT deklarieren, keine Direkt-Zugriffe in DB.

"Daten_DB".objekte_abholbereit_anzahl z.B.

wäre ein IN_OUT, denn du
merkst dir darin die Anzahl der Abholbereiten Objekte, holst also die Daten in den FB, veränderst sie und gibst sie wieder aus. Wenn diese Variable nur in deinem FB verwendet wird, dann kannst du sie auch im STAT-Bereich deklarieren, der Stat-Bereich ist ein Variablenbereich, der Werte enthält, die sich der FB "merken" kann. Der Temp-Bereich enthält Variablen, die immer nur genau einen Zyklus lang gültig sind. Darin kann man Zwischenergebnisse ablegen, die im Baustein im gleichen Zyklus wiederverwendet werden. Sie müssen immr zuerst mit einem Wert beschrieben werden, ehe man sie liest, sonst sind sie zufällig und undefiniert!

Suche mal in der Step7-Hilfe und im Forum unter dem Stichwort "Multiinstanz".
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo erstmal,

danke für deine ausführliche Beschreibung. Hat mir wirklich sehr geholfen.

Zu #1: gelöst durch folgende Methode: #Auslaufband := "timer_auslaufband_fahrzeit".Q OR "timer_auslaufband_nachfahren".Q.

Zu #2: habe es im ersten Post sehr schlecht ausgedrückt aber hier erneut: Ich habe ca. 15 Fehlercodes. Wenn 1 Fehlercode aktiv ist, sollen alle Outputs auf 0 gesetzt werden. Da ich aber 7 FB's habe und diesen Code überall reinzuschreiben wäre sehr unschön. Kann man dies nicht irgendwie übergeordnet ins OB1 oder als FB machen, so das die Fehlercodes nur 1x immer abgefragt werden und nicht immer im dazugehörigen FB?

Zu #3: Danke für diese tolle Erklärung. Ich habe hier 2 Bearbeitungsstationen, wo ich den Code weiterverwenden will. Beide werden gleich angesteuert doch 3 Zeilen Code sind zwischen den beiden Stationen anders. Was mach ich mit diesen extra Code? Außerdem haben beide Stationen verschiedene Bearbeitungszeiten, aber keine Ahnung wie ich das mit nur einem FB machen soll. Außerdem hab ich mich jetzt etwas durch die Hilfe gelesen, wegen den Multiinstanzen, aber verstehe dies leider überhaupt nicht.. Wäre schon wenn einer erklären könnte warum man diesen braucht und wie man so einen erstellt.

Noch eine Frage zum Schluss: Die Station wird später mit einer HMI bedient. Da aber nicht ich die Visualisierung mache und davon auch keine Ahnung habe, wäre noch wichtig zu wissen, welche Variablen man im HMI auslesen und verändern kann.

Danke und Lg

Edit: habe nun einen FB erstellt der alle Fehlercodes durchcheckt und wenn einer gesetzt ist schaltet er alles aus, den FB hab ich ganz am Ende meines OBs und wird nur abgearbeitet wenn eine Fehler auftritt. Wäre dies so ok oder gibt es eine schnellere und sichere Möglichkeit?
 
Zuletzt bearbeitet:
zu #2

Ja, das kannst du machen.
es macht ohnehin Sinn, die Fehler aus den FB nach außen zu führen, um sie dann später z.B. mit einem Oanel oder ener roten Meldeleuchte anzuzeigen.
Die Ausgänge werden von dir zwar mitten im Programm gesetzt oder rückgesetzt, aber immer am Ende bzw. am Anfang eines SPS-Zyklus werden sie erst tatsächlich an die Peripherie übertragen. Wenn du also innerhalb eines Zyklus 10 mal einen Ausgang setzt und rücksetzt, wirst du physikalisch am Ausgang immer nur das Letzte sehen, das du gemacht hast!

Dein Edit hört sich gut an.

zu #3

Ok, Multiinstanzen war ein wenig zu weit gegriffen, brauchst du nicht unbedingt, wenn man mal von den Timern absieht, die du im Stau-Bereich des FB definierst, das sind im grunde genommen, dann auch welche. Hast du diesen Teil der Ausführungen, mit den Timern denn verstanden?

Wenn Code wirklich unterschiedlich ist, dann muß man ihn entweder auslagern, also aus dem FB herausnehmen und dann eben nach oder vor dem FB bearbeiten oder, man baut als Input quasi einen Schalter ein, der dem FB dann sagt, "Du verhältst dich wie Fall1 oder Fall2". Im FB dann mit einer IF ... Then - Abfrage diesen "Schalter" abfragen und den jeweiligen Code ausführen..
Das ist aber in gewissem Maße eine wenig geschummelt, denn die FB lassen sich dann nicht einfach für einen dritten Fall wiederverwenden, es sei denn, das entspricht einem der beiden brereits programmierten Fälle. MAn muß dann noch enen Schalter einbauen oder eine Integer zur Fallunterscheidung nutzen.
 
Also erstmal danke für dein großartige Hilfe.

Zu #2: Die Fehler habe ich alle in eine eigene DB gepackt, damit man später bei der Visualisierung die Fehler schneller anfindet und nicht jeden FB durchsuchen muss.

Zu #3: Ich habe es inzwischen geschafft einen FB mehrfach zu verwenden, zwar ohne Multiinstanz-DB aber es hat funktioniert. Problem nun: Dieser Code wird ja bei 2 Stationen ausgeführt. Diese Stationen haben aber andere PT bei den Timern und andere Fehlermeldungen, wie schaffe ich es nun, dies so umzuändern, dass es ersichtlich ist für welche der beiden Stationen dies ist.

Zu meinem Edit: Ein Screenshot von meinem OB1 ist angehängt (derzeit nur rot markiert, da ich den Namen einer lokalen Variable geändert habe und noch nicht im OB1 geändert hab, falls nicht ersichtlich, der ENO meines Fehlerfalls geht zu jedem meiner Programmbausteine, die nichts mit dem Fehler zu tun haben) und der Code in meinem Fehlerfall sieht so aus:
Code:
#zufuehrband := 0;#schieber1_vor := 0;
#schieber1_zurueck := 0;
#fraesband := 0;
#fraeser := 0;
#bohrband := 0;
#bohrer := 0;
#schieber2_vor := 0;
#schieber2_zurueck := 0;
#auslaufband := 0;
Hier setzte ich einfach all meine Outputs auf 0.
Ist diese Lösung so ok? Oder gibt es vielleicht doch eine bessere Lösung?
Und wenn ich den Fehler wieder zurücksetze, starten dann die ganzen Bausteine von neu, oder dort wo sie aufgehört haben, als der Fehler kam?

Danke und LG

Edit: Hab nun bisschen mit Multiinstanzen herumgespielt und ich habs geschafft! Meine #3 Frage kann man nun vergessen, da ich verstanden habe, wie ich das mit Multiinstanz hinbekomme. Danke dafür.
 

Anhänge

  • Unbenannt.jpg
    Unbenannt.jpg
    124,5 KB · Aufrufe: 29
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Du mußt für Unterschiede, dem FB jeweils einen Engang spendieren.
Wenn z.B. Timerwerte unterschiedlich sind, dann also einen Eingang definieren der den Datentyp der Variablen hat, die am Timer zu stehen hat.
Dann kannst du beim jeweiligen Aufruf des FB an diesen Eingang den Entsprechenden Zeitwert ertragen. Im FB schreibst du die Eingangsvariable an den Input PT des Timers.
Gleiches machst du mit boolschen Variablen oder Integer etc. Außen an den FB dann die Wert oder auch die exteren Variable, z.Bsp. einen Wert aus dem HMI-DB, falls du da variable Werte übergeben willst, im FB mit der Input-Variablen arbeiten.

Generell ist die Frage, ob du die Outputs im Fehlerfall auf 0 bringen mußt. Der Rest deinens Programmes kann ja durchaus normal weiterarbeiten, obwohl ein Fehler auftritt.
Bsp. Du hast 2 Bänder, die nicht vonenander abhängen. Dann kann Band 1 in Fehler gehen, Band 2 aber normal weiterarbeiten und an einer LS stoppen etc. ja nachdem, wie das Programm arbeiten soll.
Hängen die Bänder hintereinander, macht es Sinn, das vordere zu stoppen, wenn das darauffolgende Band einen Fehler hat, umgekehrt könnte man das hintere Band weiterlaufen lassen, wenn das vordere in einen Fehler geht.

Es hängt also immer von Anwendungsfall ab, wie man auf Fehler reagiert.

Ich persönlich versuche, Ausgänge nur an einer Stelle zu beschreiben. Das passiert dann durchaus mit mehreren Varaiblen, wie du das ja auch schon machst, bei den Timer-Outputs.
Dazu habe ich teilweise Bausteine, z.B. für Ventile oder Motore, die haben dann Freigabe-Eingänge oder auch Sperr-Eingänge, über die ich dann bei Bedarf auch die Reaktion der Ausgänge beeinflusse.
 
Zuletzt bearbeitet:
Du mußt für Unterschiede, dem FB jeweils einen Engang spendieren.
Wenn z.B. Timerwerte unterschiedlich sind, dann also einen Eingang definieren der den Datentyp der Variablen hat, die am Timer zu stehen hat.
Dann kannst du beim jeweiligen Aufruf des FB an diesen Eingang den Entsprechenden Zeitwert ertragen. Im FB schreibst du die Eingangsvariable an den Input PT des Timers.
Gleiches machst du mit boolschen Variablen oder Integer etc. Außen an den FB dann die Wert oder auch die exteren Variable, z.Bsp. einen Wert aus dem HMI-DB, falls du da variable Werte übergeben willst, im FB mit der Input-Variablen arbeiten.

Dies hab ich bereits mit Multiinstanzen wunderbar hinbekommen. Mit etwas googlen und deinen Tipps im Hintergedanken hab ich es problemlos geschafft.
Wäre da nur noch die Frage ob das mit dem Fehlerfall so ok ist oder ob es eine bessere Möglichkeit gibt.

lg
 
Siehe nochmal oben, hatte gerade nacheditiert. :)

Geht schon so, wird aber immer schwieriger zu überblicken, falls dein Programm viel größer wird.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Siehe nochmal oben, hatte gerade nacheditiert. :)

Geht schon so, wird aber immer schwieriger zu überblicken, falls dein Programm viel größer wird.

Ja hab ich gesehen.
Was wäre den die elegantere und übersichtlichere Variante?

Und bei einem Fehlerfall bin ich mir noch nicht 100%ig sicher wie ich auf einen Fehlerfall reagiere. Falls man es noch nicht aus meinem Posts rausfinden konnte, folgende Station wird derzeit programmiert: http://www.ikhds.com/media/catalog/...6e5fb8d27136e95/f/t/ft_orig_taktstr_72dpi.jpg. Was wäre eure Empfehlung bei dieser Station auf Fehler zu reagieren. Alles abschalten bei einem Fehlerfall oder nur die Stationen davor?

LG

Edit: Noch eine Frage. Da ich erst durch Ralles Posts erfahren habe, dass man Timer und Flankenerkennungen auch im STAT-Bereich machen kann, sollte man dies immer tun, wenn sie nur in dem FB gebraucht wird? Habe nämlich zurzeit alle Timer und Flankenerkennungen in einem eigenen DB, obwohl die nur in einem FB gebraucht werden. Ich denke es ist besser wenn ich diese Timer und Flankenerkennungen im STAT bereich mache. Was ist eure Meinung dazu?
 
Zuletzt bearbeitet:
Mach es erstmal so, wie du es vorhattest.
Das "Nacheinander Abschalten" würde ich mir aufheben, falls man noch etwas "schöner2 machen will.

Variablen, die nur im FB benötigt werden (auch Timer und Flanken) immer im FB. Dessen IDB ist ja sozusagen, sein Gedächtnis und genau dafür da.
Sollte man dann noch etwas in Richtung HMI und umgekehrt benötigen, dann über die INPUT/OUTPUT/IN_OUT gehen. Das kann man auch mit kompletten Strukturen machen, wenn nötig, aber nutze erst einmal die normalen vorhandene Datentypen für die Schnittstelle des FB zum übrigen Programm.
 
Mach es erstmal so, wie du es vorhattest.
Das "Nacheinander Abschalten" würde ich mir aufheben, falls man noch etwas "schöner2 machen will.

Variablen, die nur im FB benötigt werden (auch Timer und Flanken) immer im FB. Dessen IDB ist ja sozusagen, sein Gedächtnis und genau dafür da.
Sollte man dann noch etwas in Richtung HMI und umgekehrt benötigen, dann über die INPUT/OUTPUT/IN_OUT gehen. Das kann man auch mit kompletten Strukturen machen, wenn nötig, aber nutze erst einmal die normalen vorhandene Datentypen für die Schnittstelle des FB zum übrigen Programm.

Ok danke.

Ich entschuldige mich schon mal für die ganze Fragerei aber eine finale Frage hätte ich da noch. Kann ich mit dem HMI auch STAT-Variablen aus normalen (keine Multiinstanz) FBs auslesen und verändern? Wäre interessant zu wissen welche Variablen man mit dem HMI auslesen/verändern kann.

LG
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was für eine HMI nutzt du?

Falls WinCCFlex:
Du kannst auf alle Variablen eines DB, auf Merker, Eingänge, Ausgänge Zeiten etc. zugreifen.
Am einfachsten geht das, indem du diese Variablen symolisch adressierst. Sie dir mal die Variablentabelle in deiner HMI an.

In TIA geht es sogar noch einfacher du kannst die gewünschte Variable einfach von DB in das HMI-Bild ziehen, dann wird sie im HMI automatisch angelegt.

PS: Man kann auch auf die Variablen eines Instanz-DB zugreifen, ich rate aber in den meisten Fällen davon ab, da ich persönlich das für einen unsauberen Stil halte. Besser ist es hier klare Schnittstellen zu haben, also einen z.Bsp. HMI-DB anzulegen und zu nutzen. Variablen, die man im HMI anzeigen, editieren will, kann man hier definieren und dann aus dem SPS-Programm heraus auch aus diesem DB lesen oder diese Variablen als Input an einen FB/FC übergeben.
Aber darüber gibt es hier im Forum zahlreiche Kontroversen, jeder hat da seinen Meinung und sucht sich dann das, was er für richitg und passend hält.

PS: Für Fragen ist dieses Forum da, da gibt es nichts zu entschuldigen.
 
Komm gute ins neue Jahr, das wünsche ich auch allen anderen hier im Forum!

Ich werde jetzt zum Feiern aufbrechen. :)
 
Komm gute ins neue Jahr, das wünsche ich auch allen anderen hier im Forum!

Ich werde jetzt zum Feiern aufbrechen. :)

Danke für alles. Rechtzeitig noch alle Fragen geklärt :).

Ich wünsche dir noch einen schönen Abend und einen guten Rutsch ins neue Jahr.
Vielleicht hört man ja wieder im nächsten Jahr :)

Lg
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Eine letzte Frage wäre da noch :)

Wenn ich in meinem Programm z.B. folgenden Code habe: "Hilfsvariablen_DB".variable := 1;
Ist das dann so ok, wenn man es so programmiert, oder sollte man diese Variablen in IN, OUT IN/OUT deklarieren und im Programm auch so verwenden und erst im OB1 zuteilen?
Was ist den die Variante die man üblicherweise macht und eleganter ist?

Jetzt sollte ich aber alles haben :)

lg
 
Wenn das in dem FB ist, der mehrfach verwendet werden soll, dann solche Variablen über die IN/OUT/IN_OUT - Schnittstelle in den FB holen. Im Programmcode selbst, außerhalb dieser FB kannst du solche Zugriffe natürlcih machen.
 
Zurück
Oben