TIA Array OF FB für S7-300: Geht das?

JSEngineering

Level-3
Beiträge
2.268
Reaktionspunkte
812
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich versuche gerade, ein Array OF FBs anzulegen:
Ich habe einen Ventil-FB, den ich mehrfach über eine Schleife aufrufen möchte.

Habe es im DB probiert, in einem neuen FB... TIA sagt mir immer, daß es "an dieser Stelle" nicht geht.

Kann ich kein Array anlegen? Muß ich jede Instanz einzeln deklarieren? Oder sehe ich gerade nicht das Offensichtliche?

Anzuwenden in einer S7-315 mit TIA V14.

Gruß
Jens
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke!

Warum zum Glück???????? :confused:

In CoDeSys funktioniert das wunderbar und macht den Code schön übersichtlich....


Code:
Valve_1(...);
Valve_2(...);
Valve_3(...);
Valve_4(...);
Valve_5(...);
Valve_6(...);
Valve_7(...);
Valve_8(...);
Valve_9(...);
...
Valve_100(...);

oder

Code:
For x:=1 to 100 Do
    Valve[x](...);
End_For;

mir ist die zweite Variante lieber... habe weniger Schwielen an den Fingern und übersichtlicher ist es allemal....
 
Warum zum Glück???????? :confused:

In CoDeSys funktioniert das wunderbar und macht den Code schön übersichtlich....
Na, unter übersichtlich (ok besser: verständlich) verstehe ich was anderes als zig Ventile die nur eine Nummer und keinen Name haben. Werden bei Dir alle FB-Instanzen mit der selben Aktual-Parameter-Beschaltung aufgerufen? Damit der Array-Aufruf funktioniert müssten alle Übergabeparameter ebenfalls aus Arrays kommen. Zum Schluß hat man nur noch eine Schleife mit "anonymen" nummerierten Variablen und Instanzen, und man kann keinen einzigen Bausteinaufruf beobachten.

Harald
 
Na, unter übersichtlich (ok besser: verständlich) verstehe ich was anderes als zig Ventile die nur eine Nummer und keinen Name haben. Werden bei Dir alle FB-Instanzen mit der selben Aktual-Parameter-Beschaltung aufgerufen? Damit der Array-Aufruf funktioniert müssten alle Übergabeparameter ebenfalls aus Arrays kommen. Zum Schluß hat man nur noch eine Schleife mit "anonymen" nummerierten Variablen und Instanzen, und man kann keinen einzigen Bausteinaufruf beobachten.

Harald


Richtig, alle Parameter kommen auch aus Arrays.
Richtig, alle Ventile sind nach außen "anonym".
Richtig, vernünftig debuggen kann man nicht mehr.

Aber:

Den Baustein erstelle ich, der ist durchgetestet. Dann kein Bedarf mehr für Debugging. Und zur Not bei fiesen Fehlern setze ich den Index des Arrays auf einen festen Wert und rufe nur noch diesen Baustein auf.

Vor allem: Dieses Programm ist ein "Serien"-Programm für eine Ventilsteuerung auf Schiffen... die Ventile heißen bei jedem Kunden anders.
Denen also im Programm Namen zu geben macht wenig Sinn. Die hießen dann sowieso maximal "Ventil1", "Ventil2", ...
Und es sind immer mal unterschiedliche viele. Auch ggf. Bedarf für Erweiterung.
Mit Arrays brauche ich nur meine Konstante MaxValves erhöhen, neu übersetzen und es ist fertig.
Bei einzeln aufgerufenen Instanzen muß ich Hand anlegen: Instanzen anlegen, aufrufen, Indizes vergeben... alles fehlerträchtig und braucht Zeit.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin,

ich kann im DB ein Array[0..xy] of FB anlegen:

Konkret:
Array[0.."SSM_MAX"] of Program_Alarm

Wann meckert TIA?

Edit: Bei mir geht es NICHT in einem globalen DB, aber in den Static-Variablendeklaration eines FB.

VG

MFreiberger
 
Zuletzt bearbeitet:
Moin,

ich habe es sowohl im Global DB probiert als auch im Static eines FB.
Sobald ich Enter drücke erkennt er alle Variablen/Konstanten-Namen in der Deklaration, setzt sie in Anführungszeichen und macht die Deklaration rot: An dieser Stelle nicht möglich.

Gruß
Jens
 
Hallo,

das hat mit der CPU zu tun.
Bei mir (TIA v15.1) geht es bei einer S7-1500 aber NICHT bei einer S7-300.

315:
2021-02-09 14_04_21-Window.png

1516:
2021-02-09 14_04_38-Window.png
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin Jens,

im Global-DB klappt es bei mir auch nicht. Aber im Static-Bereich eines FB.
Da schreibe ich ein FB-Symbol als Datentyp rein und er schlägt mir sogar schon den FB vor. Funktioniert einwandfrei.
Da wir das seit TIA14 (bis jetzt zu TIA 16) so handhaben, glaube ich nicht, dass es an der Version liegt.

Aber wieso "Variable/Konstanten-Namen"? Es muss doch eine Datentypbezeichnung sein (elementar, UDT, FB)?

VG

Mario


Edit: ups, gerade erst gecheckt (Überschrift gelesen): geht nicht bei 300/400.
 
Zuletzt bearbeitet:
Richtig, vernünftig debuggen kann man nicht mehr.
Sprich: Meine Programme sind immer Perfekt. Kein Fehler sind möglich und kein Verbesserung wird nötig.

Mit Arrays brauche ich nur meine Konstante MaxValves erhöhen, neu übersetzen und es ist fertig.
Sprich: Mein Zeit ist so viel Wert das es lohnt sich die 10 Sekunden zu sparen pro Instanz es wurde kosten einzelne Symbole zu definieren.

Schreibtischprogrammierer !
 
Moin Mario,

ich deklariere

Code:
Valves : ARRAY[1.."MaxValves"] OF "Valve_FB"

MaxValves ist eine Konstante.

Aber: Testet Ihr das mit einer 315!?
Bei Windoze #8 sehe ich eine 1500er stehen: Da mag das ja wieder funktionieren.

Ich danke Euch erst einmal.
Da das momentan sowieso nur ein Testaufbau ist, mache ich das eben zu Fuß....

Gruß
Jens
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Sprich: Meine Programme sind immer Perfekt. Kein Fehler sind möglich und kein Verbesserung wird nötig.

Sprich: Mein Zeit ist so viel Wert das es lohnt sich die 10 Sekunden zu sparen pro Instanz es wurde kosten einzelne Symbole zu definieren.

Schreibtischprogrammierer !

mmmmh.... soll ich mich angefaßt fühlen.... nein, einfach ignorieren....

Ich spreche nicht von Sondermaschinen oder irgend etwas einmalig Programmiertem...

Ich spreche hier von Anlagen, an denen extrem viele gleichartige Aggregate hängen. Jedes Aggregat ist an einer Testanlage auf Herz und Nieren geprüft.
Wenn das da raus geht, ist das: Ja, es ist perfekt!

Verbesserungen werden wiederum getestet, aber nicht in einer laufenden Anlage, sondern: In der Testanlage!

Und wir arbeiten viel mit Code-Generierung: Ja, da sind Arrays wunderbar - ich liebe sie!

Und hier bin ich gerade bei einem Testaufbau: Ja, da versuche ich Fehler durch Tipparbeit zu ersparen und ich versuche auch Tipparbeit selber zu sparen.

Also bitte nicht vorschnell urteilen, Jesper!
 
Hallo Jens,

hast du schon einmal daran gedacht, ein Array of "MEIN_UDT" in einem globalen DB abzulegen und dieses Array in einem Baustein abzuarbeiten? So ähnlich verfahre ich seit vielen Jahren mit meinen Routinen.

Auf Grundsatzdiskussionen würde ich mich hier nicht einlassen.
 
War hier im Forum schon mal Thema, wie man z.B. die CONT_C Reglerinstanzen in einem Array abarbeiten kann. Ich finde den Thread nicht wieder, aber war ungefähr so, eine UDT mit der CONT_C Struktur zu erstellen, davon entsprechende Anzahl in einem Array anzulegen. Und dann in einer Schleife erst die UDT am aktuellen Index in die einzige CONT_C Instanz schreiben, und nach Aufruf wieder von Instanz in das Array. In SCL sieht das im Grunde auch gar nicht mal so schlecht aus.

Ich habe eine Anlage übernommen in der der ursprüngliche Programmierer alle Antriebe, Schieber usw. im Array verarbeitet, aber in AWL mit Adresstrickserei. Hinzu kommt, dass jeder Antrieb mit einem Regler "verheiratet" ist. Und ich sollte jetzt an einem Antrieb eine Sonderfunktion zwischen Regler und Antrieb bauen. Das ist bei so einer Konstruktion dann mehr oder weniger unmöglich.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@Jens

Ich habe mich arrogant ausgedrückt. Das tut mir leid.
Ich sehe immer noch nicht den Vorteil, eine Maschine oder einen Prozess als Array von Objekten anzuordnen. Egal, dass die Anzahl der Objekte groß ist.
Das heißt aber nicht, dass es für andere auch kein Vorteil sein kann.
 
.. Ich habe eine Anlage übernommen in der der ursprüngliche Programmierer alle Antriebe, Schieber usw. im Array verarbeitet, aber in AWL mit Adresstrickserei. Hinzu kommt, dass jeder Antrieb mit einem Regler "verheiratet" ist. Und ich sollte jetzt an einem Antrieb eine Sonderfunktion zwischen Regler und Antrieb bauen. Das ist bei so einer Konstruktion dann mehr oder weniger unmöglich.
Wenn man ein "System" benutzt, dann besteht natürlich die Gefahr, dass man sich bestimmte Dinge verbaut. Man muss sich sehr gut überlegen, welche Routineaufgaben man sinnvoll als Routinen abarbeiten kann und welche nicht. Das Verheiraten von Antrieb und Regler klingt allerdings recht interessant. Wie hast du deine Aufgabe gelöst?
 
Wenn man ein "System" benutzt, dann besteht natürlich die Gefahr, dass man sich bestimmte Dinge verbaut. Man muss sich sehr gut überlegen, welche Routineaufgaben man sinnvoll als Routinen abarbeiten kann und welche nicht. Das Verheiraten von Antrieb und Regler klingt allerdings recht interessant. Wie hast du deine Aufgabe gelöst?

Ich habe den internen Regler auf Manuell gestellt, und dann meinen eigenen Regler drumherum gebaut und die Stellgröße auf den Handsollwert geschrieben. Das ist eben der Nachteil an so einer Lösung die bei der Programmierung weniger Aufwand benötigt, im Nachhinein aber schwierig wart- und erweiterbar ist. Das ist eine Kolonne gewesen, insofern hat das mit dem Array meiner Meinung nach auch nicht viel Sinn ergeben, außer die Programmierung zu vereinfachen. Wobei es nicht schlecht programmiert war.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe den internen Regler auf Manuell gestellt, und dann meinen eigenen Regler drumherum gebaut und die Stellgröße auf den Handsollwert geschrieben. ..
Das ist eine gute Lösung. Man kann, so fern es denn Sinn macht, den frei gewordenen Regler generell auch zur Handbedienung des Antriebs nutzen, indem man die Verstärkung auf 1 setzt und die restlichen Parameter und den Istwert auf Null.
 
Mit CODESYS kann man ja auch beides machen: konkret benamte Instanzen für jeden Funktionsblock anlegen, und diese über Interface oder Pointer in einem Array verwalten:
Valve1 : Valve;
Valve2 : Valve;
arr : Array [0..1] OF IValve := [Valve1, Valve2];

Dort wo einen die spezielle Instanz nicht interessiert, sondern einfach für alle Instanzen etwas erledigt werden muss, kann man über das Array laufen. An den anderen Stellen kann man die konkrete Instanz verwenden, ohne dass man eine Magic Number kennen muss. Beim Debuggen sollte das alles mit neueren CODESYS-Versionen kein Problem mehr sein, weil überall wo ein IValve verwendet wird, CODESYS beim Monitoring automatisch die konkrete Instanz anzeigt.

Es ist ja nicht nur so dass man sich Schreibarbeit spart, wenn man Arrays von Instanzen verwendet, sondern der Code ist auch einfacher erweiterbar: wenn eine Instanz hinzukommt, muss man nur das Array um eins vergrössern. Wenn man ordentlich mit definierten Konstanten arbeitet, dann ändert man seinen Code an einer Stelle, und überall wo mit einer Schleife über das Array gegangen wird, kann man nichts mehr falsch machen. Je weniger Codestellen man für eine Änderung anpassen muss, desto besser.

Ein solches Array kann ich auch in einer Bibliotheksfunktion bearbeiten, der es völlig egal ist, welche konkreten Instanzen von dem Typ angelegt worden sind. Also es gibt viele gute Gründe das so zu machen.
 
Zurück
Oben