TwinCAT2: Überschreiben einer Variablen einer FB-Instanz

LMDaniel999

Level-1
Beiträge
57
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo!

Ich habe eine Frage zu TwinCat2:
In meinem Programm möchte ich eine FB-Instanz zyklisch aufrufen und von verschiedenen Stellen im Programm einzelne Variablen ändern.
Beim Siemens TIA Portal V13 geht das, deshalb würde ich das gerne hier auch so machen... Dabei habe ich allerdings Probleme.
Ich hab noch nicht viel mit TwinCat gemacht, deshalb komm ich nicht auf die Lösung.

So sieht meine Programmstruktur aus:
Ich habe einen FB erstellt, der eine Baugruppe einer Maschine steuert. Da diese Baugruppe mehrmals vorhanden ist, hab ich einen Array von FBs erstellt und rufe diese zyklisch ohne Werteübergabe auf. Ich habe also ein Array von gleichen Baugruppen, die ich über deren Index ansprechen kann.

Bsp:
Code:
fbScale : ARRAY[1..3] OF ScaleSystem;
Hier werden 3 Scales erstellt, die im Programm entsprechend ohne Variablenübergabe aufgerufen werden. Das habe ich hier aber nicht gepostet.

Das möchte ich machen:
Nun möchte ich an verschiedenen Stellen im Programm einzelne dieser Baugruppen steuern. Teilweise auch mehrere gleichzeitig.
Daher dachte ich, dass ich einfach die Inputs über die Programmstruktur im ST steuern kann.

Bsp:
Code:
MAIN.fbScale[iCounter].bSetNewMaterial := TRUE ;
bSetNewMaterial ist dabei eine Boolsche Eingangsvariable im FB. Ich möchte so die verschiedenen Maschinenteile ansprechen, indem ich nur "iCounter" ändere.

Das Problem hab ich:
TwinCat meldet beim Kompilieren die Fehlermeldung 4020, was wohl daran liegt, dass ich so nicht auf die Variable zugreifen darf und kann.
Soweit ich das nun verstanden habe, muss ich hier den FB neu aufrufen und ihm den Wert dann übergeben.

Ich dachte mir das aber so, dass ich im Programm an verschiedenen Stellen einzelne Variablen ändern kann und die Bausteine zyklich aufgerufen werden.
Mein Kopf sagt mir nun, dass wenn ich die Bausteine nun jedesmal beim Schreiben aufrufen muss, dann wird der auch jedesmal ausgeführt.
Aber das möchte ich eigentlich nur einmal pro Zyklus.

Hab ich irgendwo ein Denkfehler?
Muss ich eine Variablentabelle erstellen und diese dann direkt in der Main mit den Eingängen verknüpfen? Diese könnte ich dann ja genau so beschreiben.
Dann geht mir aber der Vorteil des "Kopierens" des FBs verloren.
Ich habe an einer anderen Stelle einen FB 20 mal, weil ich 20 gleiche Maschinenteile habe. Für diese kann ich das gleiche Programm und die gleiche Visu nutzen, wenn ich nur jedesmal den Index ändere. Das macht das ganze einfach skalierbar.

Wie setze ich sowas nun um?
Vielen Dank für die Hilfe!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

Ja, ich habe erst ein Array angelegt und die einzelnen FBs danach ohne Variablenübergabe geladen.
Diese werden auch geladen.

Ich kann auch über die Visu auf deren Ausgangsvariablen zugreifen und die Berechnung darin funktioniert auch.
Aber zum Setzen der Eingänge hab ich im ST nun auch die entsprechenden Instanzen aufgerufen und diese mit Variablen geladen. Geht auch soweit.

Mein Problem ist nur, dass ich nun der Meinung bin, dass der Baustein mehrmals pro Zyklus abgearbeitet wird.
Und ich denke, dass mir das Probleme bereiten könnte.
Wenn ich beispielsweise was inkrementiere und der Baustein unterschiedlich oft aufgerufen wird, dann würde ich ja auch immer unterschiedlich oft inkrementieren.

Also anstelle von
Code:
Instanz.Inputvariable := Wert ;
muss ich jedesmal beim Schreiben folgendes machen:
Code:
Instanz (Inputvariable := Wert) ;
So geht es auch. Zumindest mit den Tests aktuell. Ich bin nicht sicher, ob das richtig ist.
Und laut dem TwinCat InfoSys ist das direkte Zuweisen nicht ok, sondern man soll Folgendes machen:
Code:
Variable := Wert ; Instanz (Inputvariable := Variable ) ;

Irgendwie blick ich da nicht so ganz durch....

Danke
 
Ich denke, wenn du von überall in deinem Programm auf das Array mit den FB-Instanzen zugreifen willst, musst du das Array bei den Globalen Variablen deklarieren.
Auf lokal deklarierte Instanzen kann auch nur lokal zugegriffen werden.

Ansonsten wünsche ich dir noch viel Glück, dass du dich mit deinen programmweiten Zugriffen nicht verhaspelst und dann Wochen mit der Fehlersuche verbringen darfst.
 
Verstehe ich das richtig, dass Du ausserhalb von MAIN auf das FB-Array schreiben willst? Dazu musst Du das FB-Array als VAR_INPUT von MAIN deklarieren.
Für empfehlenswert halte ich so etwas allerdings nicht, ich kann mich deshalb den guten Wünschen von MasterOhh nur anschliessen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Verstehe ich das richtig, dass Du ausserhalb von MAIN auf das FB-Array schreiben willst? Dazu musst Du das FB-Array als VAR_INPUT von MAIN deklarieren.
Für empfehlenswert halte ich so etwas allerdings nicht, ich kann mich deshalb den guten Wünschen von MasterOhh nur anschliessen.
Ja, genau. Ich habe das so in der Form mal gelernt, wobei das bei einem anderen Programmmiersystem so war. Da ging es darum, mehrere Motoren parallel zu betreiben, die alle zentral initialisiert wurden und dann im laufenden Programm immer nur neue Drehzahlen und "Execute" - Bools vorgesetzt bekamen. Das ging soweit problemlos.

Wie würdet ihr so eine "Skalierbarkeit" machen? Ich habe den Vorschlag, mehrere gleiche FBs bei gleichen Maschinenteilen zu nutzen, hier auch im Forum gelesen. Da stand aber nur was über die Verbindung zu den I/Os der Hardware, nicht über dessen Ansteuerung.

Vielleicht genauer zur Maschine:
Es geht um eine Mischanlage mit vielen Silos und 3 Waagen. Jede Waage hat bestimmte Silos, die ihnen zugeordnet sind. Die Silos stehen noch nicht alle, werden aber noch ergänzt.
Daher die Skalierbarkeit. Die Silos und Waagen sind aber alle gleich aufgebaut. Und während dem Ablauf, soll ein Rezept durchlaufen werden, und Material in der Waage abgemessen werden. Dazu möchte ich das Rezept dann im Code nach Waagen/Silos aufteilen und 3 parallele Wägevorgänge durchführen.

Wenn ich nun meine Visu erstelle kann ich immer das gleiche Bild verwenden, indem ich alle Variablen der Viso mit einem Index auf das Array zugreifen lasse. Den Index kann ich einfach erweitern und ich brauch keine neue Viso erstellen, wenn noch 3 Silos dazukommen.
Im Programm ist es ähnlich. Über eine Zuordnungsliste schau ich das Rezept einmal durch und teile es nach Waage auf. Dann wird dieses Teilrezept einfach durchgearbeitet und nacheinander die Silos angesprochen. Ich kann auch hier den gleichen Schritt mehrmals durchführen, wenn ich einen Verweis vom Material auf den Index vom Silo habe. Und den hab ich in der Zuordnungsliste.
Das bedeutet, dass ich einfach nur die Arrays und Grenzen verändern muss, wenn sich die Anzahl der Silos ändert.

Wie würdet ihr sowas lösen? Ich dachte, dass das eine gute Möglichkeit ist.... :-(
 
Hallo,
natürlich läßt sich das ganz bestimmt irgenwie so in der Art umsetzen - die Frage ist : sollte man es so machen ...?

Je mehr Funktionen dieser Art du in einen Baustein hineinpackst umso unübersichtlicher und schwerer zu debuggen wird er am Ende.
Du solltest m.E. die Struktur kleiner (objekt-orientierter) angehen und dann hinterher zusammengehörige Dinge zusammen fassen.
Wenn ein FB (oder seine Instanz) je nach Aufruf unterschiedliche Dinge tun soll so könnte man ihm das auch mitgeben in dem man es über die Schnittstelle tut (im Prinzip so als wollte man unterschiedliche Methoden einer Klasse ansprechen).

Gruß
Larry
 
Ich habe nichts dagegen, ein Array of FB zu deklarieren, auch nicht, die Input-Variablen der FB's nicht direkt bei ihrem Aufruf zu beschreiben. Aber Zugriffe auf die FB-Variablen sollten nur aus der POU heraus erfolgen, in der die FB's instanziiert sind.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
dass man es so nicht machen sollte, hab ich rausgehört.... :)

Der FB soll keine unterschiedlichen Sachen machen. Prinzipiell gibt der FB nur sein gelagertes Material und seinen Füllstand aus und zwei Aktoren werden angesteuert.
Bei der Waage ist es so, dass diese das aktuelle Gewicht ausgibt und einen Tara eingang hat.
Also eigentlich nicht viel.

Wenn jetzt das Ablaufprogramm einfach nur einen Aktor anschalten soll, dann wollte ich dementsprechend einfach den Eingang setzen.
Da ich das aber wohl so nicht kann, müsste ich jedesmal den Baustein aufrufen.

Nochmal zwei Verständnisfragen:

1. Wenn ich einen FB mehrmals im Programm aufrufe, wird der dann auch mehrmals abgearbeitet?
2. Wie mach ich das bei TC2 objektorientiert? Aus Java kenn ich Methoden, die ich aufrufen kann. Also Aktor an oder Aktor aus. Und da das wohl erst ab TC3 geht, wollte ich das hier über einen Eingang machen.... Selbst wenn ich eine Funktion schreibe, der ich eine Aktion und eine Nummer übergebe, dann schreibt auch diese Funktion "von außen" auf das FB. Wie würdet ihr die Ein-Ausgänge verwalten und ansprechen?

Ich denke, dass ich vermutlich nur grad den Wald vor lauter Bäumen nicht sehe. Vielleicht hat ja einer ein Beispiel oder einen Link zum InfoSys für mich... :)
 
Hallo,
wenn du den FB mehrmals aufrufst dann wird er auch mehrmals abgearbeitet ...
Es sei denn du änderst sein Verhalten durch eine entsprechende Beschaltung auf die du im FB-Code reagierst.
Auf diese Weise könntest du so eine Art Methoden-Verhalten erzeugen. Deine "Methoden" des FB's sind boolsche IN-Parameter von denen abhängig du Dinge im FB ausführst oder auch nicht. Du kannst aber immer auf den gesamten Datenhaushalt des FB's zugreifen ... Konntest du mir folgen ?

Gruß
Larry
 
Hi.
Danke für die Antwort.
Das sind ja genau solche Sachen, die machen möchte.
Ich habe einen FB, der auf verschiedene INs reagiert.
Bsp.: Ich habe ein IN für eine Real Variable und ein IN mit einer BOOL. Wenn ich die BOOL von außen setze, möchte ich den Real Wert übernehmen im FB.
Soweit eine "Art" Methode. Wenn ich aber von "irgendwoher" eine IN Variable setzen möchte, dann kommt immer der Schreibzugriff Error.
Aber weiter oben wurde ja schon gesagt, dass ich den FB Array nicht als VAR in einer Funktion anlegen soll. Ich denke das löst das Problem, hab ich aber noch nicht getestet.

Ich möchte halt nur alle Operationen zu einer Baugruppe im selben FB machen und diesen sauber intern trennen. Jede "Methode" hat dort seine eigenen Eingangsvariablen und schreibt auf bestimmte Variablen im FB. Die Outs frage ich halt andauernd ab.

Also denke ich schon, dass ich auf dem richtigen Weg bin, oder?
Es geht mir ja aktuell um das Problem, dass ich selbst IN Variablen nicht einfach ohne Bausteinaufruf beschreiben kann....
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich denke (nach deinem letzten Beitrag) auch, dass du auf dem richtigen Weg bist.
Wenn du allerdings dazu etwas Konkreteres brauchst (z.B. Hilfestellung) dann wäre es nützlich, wenn du den Code, an dem es augenblicklich hängt, mal postest ...

Gruß
Larry
 
Ich möchte halt nur alle Operationen zu einer Baugruppe im selben FB machen und diesen sauber intern trennen. Jede "Methode" hat dort seine eigenen Eingangsvariablen und schreibt auf bestimmte Variablen im FB. Die Outs frage ich halt andauernd ab.
Dann beschäftige Dich mal mit Aktionen. Die kommen OOP-Methoden recht nahe, können allerdings keine eigenen Variablen haben, sondern nur auf die FB-Datenstruktur zugreifen. Du musst also auch Daten, die eigentlich nur zu einer Aktion gehören, in der FB-Datenstruktur deklarieren. Damit werden sie natürlich auch für andere Aktionen und den FB-Hauotcode sichtbar, da ist dann Disziplin gefragt.
Es geht mir ja aktuell um das Problem, dass ich selbst IN Variablen nicht einfach ohne Bausteinaufruf beschreiben kann....
Doch, das kannst Du, aber nur in der POU, in der der FB instanziiert ist, in Deinem Fall also im Programm MAIN. Wenn Du von ausserhalb zugreifen willst, verwehrt der Compiler Dir nicht den Zugriff auf FB.Input, sondern auf MAIN.FB. Um doch von aussen zugreifen zu können, musst Du den FB in MAIN ebenfalls als VAR_INPUT deklarieren, wie ich schon geschrieben hatte.
 
Hi!

Vielen Dank für die guten Antworten.
Damit sollte mein Problem gelöst sein. Die Aktionen schau ich mir nun nochmal an.
Vielleicht sind die ja auch interessant für mich.

Danke nochmal!
 
Zurück
Oben