TIA Direkte Symbolische Bausteinaufrufe Multiinstanzen und Typisierung.

Aksels

Level-2
Beiträge
257
Reaktionspunkte
9
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute,

ich habe da ein Sinn-Problem.
In der Vergangenheit musste ich immer wieder viele FBs des gleichen Typs in meine Projekte kopieren.
Beispiel 30 Analogwerte (Scale Ober- und Untergrenze per Display einstellbar....), 10 Pumpen, 6 Spülkippen.
Der Arbeitsaufwand ist imens. 40 Analogwerte-Bausteine verdrahten und 40 Bilder im Display anlegen. 40-fache Variablen....

Ich bin deswegen dazu übergegangen keine FBs mit Multiinstanzen zu nutzen, sondern machte es folgendermassen:
  1. Ein Datenbaustein, der folgendes enthält: Array mit der benötigten Anzahl z.B. Analogwerte, darin alle Inputs Outputs, statische Variablen...
    Weiterhin einmalig alles was alle Instanzen gemeinsam benötigen (Bei Pumpen z.B. SekundenimpulsFlankenMerker zum Zählen...)
  2. Ein FC, der sich die Bausteinlänge holt, daraus die darin enthaltenen Instanzen errechnet und damit eine For-Schleife durchläuft, die für alle Antriebe oder Analogwerte etc. die Aufgaben abarbeitet.
  3. Noch ein FC, der die bequeme Zuordnung der Ein- und Ausgänge vornimmt (mit Eingang "Antriebsnummer")
  4. Ein weiterer FC übernimmt die Verwaltung der Anzeige auf dem Display. Im HMI habe ich nur ein Bild für alle 40 Analogeingänge. Mit Buttons für rechts links kann man den Analogeingang wählen (Daten werden von Array in ein AnzeigeDaten-Fach kopiert) und die zugehörigen Daten sehen und bearbeiten. Ein Speichern Button übernimmt die Werte in den Array.
Vorteil: Bei der Beschaltung der Eingänge hätte ich mit 40 Mutliinstanz-FBs z.B den Sekundenimpuls 40 Mal anlegen müssen. Bei meiner Methode nur einmal an den FC unter 2.
Ich kann nochmal 40 Antriebe hinzufügen, indem ich den Array im DB von 1. einfach vergrößere. Ich muss sonst nichts beachten.
Selbst das Display muss ich bei dieser Vergrößerungaktion nicht beachten. Der Baustein unter 4. lässt nun einfach 40mal öfter den RechtsButton zu.

Nun kommt das Problem.Ich habe immer wieder Verbesserungen zu den Bausteinen oder Fehlerbehebungen, bei denen mir die Bibliotheken echt helfen würden, Stichpunkt Typisierung.
Aber: TIA mosert wegen meiner zwar Symbolischen, aber direkten Zugriffe auf Globale DBs unter 1.
Da hat es ja recht. Hübsch ist mein Programmierstil nicht.
Also habe ich die DB und die FCs alle zusammen in einen FB kopiert. Dann klappt die Typisierung sehr schön.
Allerdings verliere ich einen Vorteil:
Ich kann den Array nicht vergrößern oder verkleinern, ohne dass er mir eine neue Version draus macht.
Aber mein Archivbaustein, der es ermöglicht z.B. kWh oder m³ Impulse zu Archivieren (ein Jahr Tagesgenau, zwei Jahre monatlich und 10 Jahre jahressumme) muss sowieso sehr klein gehalten werden, denn er passt nur mit Müh und Not in den Speicher.
Neue Version heisst aber, wenn ich das nächste mal bei der Anlage bin muss ich beim Aktualisieren des Bausteins aufpassen, dass ich nicht vergesse ihn zu vergrößern oder zu verkleinern.
Meine Überlegung:
  1. In einem FB habe ich es aufgegeben mittels Konstanten oder ähnlichem Dynamisch zu werden. Es wird immer eine neue Version, wenn er typisiert ist.
  2. Ich kann einen Struct typisieren, der den Array in dem Globalen DB dynamisch verändert.
  3. Dem typisierten Bearbeitungsbaustein gebe ich dann die DB-Nummer als Int-Eingang.
  4. Aber wenn ich dann auf den DB zugreife wird es ja noch schlimmer. Da man erst zur Laufzeit weiss welcher DB da wirklich anliegt, zeigt mir TIA keine Vorschläge mehr an wärend ich die Variablen tippe. Mies.
  5. Ich habe mir schon überlegt, ob ich einen DB-Zugriffsbaustein erstelle. Dem gebe ich an den Eingängen mit, wieviele Instanzen und wieviele Daten darin ich brauche. Dann kann er den DB beim ersten Start sogar selber erzeugen. Zugriffe sind dann eben sehr unkomfortabel, nur über Zahlen. Das ginge noch. Aber für jeden benötigten Typ ein eigener Anzahl-Eingang? Wie baue ich den DB dann blind zusammen, ohne Struct, Datentyp oder sonstiges....

Es dreht sich im Kreise.
Hat jemand was ähnliches schon gemacht und kann mir eine Richtung geben?

Aksels
 
In der Vergangenheit musste ich immer wieder viele FBs des gleichen Typs in meine Projekte kopieren.
Beispiel 30 Analogwerte (Scale Ober- und Untergrenze per Display einstellbar....), 10 Pumpen, 6 Spülkippen.
Der Arbeitsaufwand ist imens. 40 Analogwerte-Bausteine verdrahten und 40 Bilder im Display anlegen. 40-fache Variablen....

Ich finde es genial um für jede Analog wert, Antrieb und so weiter eine FB mit Instanz zu haben. Ja man muss 1 mal durchbeißen um es zu projektieren. Das ist aber auch nicht die Welt.
Es ist sehr übersichtlich und jede kann es nachvollziehen und auswerten. (wir sind mit mehre Inbetriebsetzers)

Ist es bei dir dann wirklich so schlimm?

Bram
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Naja,.... was heisst nicht die Welt....

@de vliegende hollande

Was heisst nicht die Welt.... ein Beispiel: 20 Analogwerte beim Kunden. Ich habe jeden Analogwert auf dem HMI, damit auch ein Techniker ohne PG mal schnell einen Wert umskalieren kann, wenn er z.B. eine andere Messung installiert.
So wie Du es machst: 20 mal FB kopieren und 20 mal verdrahten. 20 mal HMI Bild kopieren und 20mal mit Variablen verbinden.
Bei mir: 1 mal FC kopieren und allgemeine Eingängeverdrahten (Sekundenimpuls, Quittierung....) 1 Mal DB kopieren, Anzahl Messwerte eingeben. 1 Mal HMI Bild kopieren und mit Variablen verbinden. 20 Mal Analogwert auf DB-Variablen legen(vernachlässigbar!).

Wenn ich richtig rechne ist bei Dir der Aufwand 20 Mal höher. Wenn man also (mal sehr sehr günstig gerechnet bei der Menge allein an HMI Variablen) 10 Minuten für einen Analogwert braucht, brauchst Du 200 Minuten, also 3 Stunden und 20 Minuten. Ich brauche tatsächlich nur 10 Minuten.
Ich fände das schon schlimm, wenn das Projekt nur 10 Stunden zur Verrechnung hat.

Gruß,
Aksels
 
Die Typisierung umgehst du am besten, in dem du dein Array als Variant übergibts. Innerhalb der Funktion kannst du dann mit CountOfElements() die Länge des Array bestimmen. Mit MOVE_BLK_VARIANT() greifst du dann auf einzelne Element die Elemente zu. Du musst dann natürlich sicher sein, dass die richtigen Daten als Variant übergeben werden.

Durch dies lose Bindung kannst du also deinen DB beliebig verändern, ohne das die Typsierung des FCs eine neue Version erforderlich macht. Den DB würde ich dann nicht typisieren.
 
Hallo Aksels

die Lösung von hacker mit der Verwendung von VARIANT ist schon mal nicht schlecht. Statt MOVE_BLK_VARIANT, kann man auch VariantPut bzw. VariantGet verwenden um auf von außen herein gereichte Array-Elemente zuzugreifen. Hacker schiebt das ganze Array rein, ich nur das einzelne Element. Zwei Varianten des Umgangs mit VARIANT ;-)

Was man bei 1200 und 1500 auch verwenden kann sind die ArrayDB. Zuerst legt man sich einen Datentyp an, z.B. einen für Pumpen, einen für Spülkippen eine für was immer du so hast.
Dann kannst du dir dafür eine beliebige Anzahl von ArrayDB von beliebiger Größe anlegen. New DB -- als Datentyp ArrayDB -- dann den Datentyp des ArrayElementes und schließlich noch die Zahl der Elemente.
Jetzt legst du dir eine Verwaltungsstruktur für die ArrayDB an. Also einen DB der pro ArrayDB einmal die DB.Nummer (Datentyp DB_ANY) und die Zahl der Elemente im DB enthält.
Also sowas
DATA_BLOCK Verwaltung : STRUCT
PumpenDB : DB_ANY := "Pumpen"
AnzahlPumpen : DINT := 100
SpueltischDB : DB_ANY := "Spueltische"
AnzahlSpültische : DINT := 100

In einem FC oder FB legst du dir dann lokale Variablen an. Mit denen kannst du ganz normal hantieren

TEMP
meinePumpenWerte : PumpenUDT
...

#meinePumpenWerte.An := True;
#meinePumpenWerte.Drehzal := 50;

Um jetzt auf dies ArrayDB zuzugreifen, gibt es vier Funktionen (nagelt mich jetzt nicht wegen der Parameternamen fest, ich zitier gerade aus dem Kopf)

WriteToArrayDB( DB := "Verwaltung".PumpenDB, Index := #i, Value := #meinePumpenWerte ); // schreibt in das Array an index i
ReadFromArrayDB( DB := "Verwaltung".PumpenDB, Index := #i, Value => #meinePumpenWerte );// liest aus den Array von index i

Der Vorteil ist, dass man hier richtig schön mit Strukturen arbeiten kann und diese DB eben so groß sein dürfen, wie Speicherplatz (Working-Memory) da ist ;-)
Der Baustein, den du schreibst um eine Pumpe oder das Feld von Pumpen zu bearbeiten, ist damit völlig unabhängig von der Zahl der Pumpen. In der einen Anlage 10, in der Anderen 1000. Wieviel drin sind steht ja im DB "Verwaltung"

WriteToArrayDBL() und ReadFromArrayDBL funktionieren ähnlich, jedoch asynchron mit ArrayDB die nur im Ladespeicher liegen. Das dauert zwar viel länger, dafür wird die Größe der ArrayDB eben nicht durch den Arbeitsspeicher, sondern durch den Ladespeicher begrenzt. Es soll Leute geben, die sich GB-Kärtchen leisten können. :ROFLMAO:

Ich finde das viel einsichtiger wie diesen mysteriösen VARIANT. In beiden Fällen musst du lokale Kopien deiner Daten anlegen um damit zu arbeiten. D.h beides ist gleich schnell.


'n schön' Tach auch
HB
 
Ich finde da gerade nichts: Funktionieren ArraDBs auch auf 1200er CPUs?
Da bietet mir TIA beim anlegen eines Bausteins keinen ArrayDB in der Drop-Down-Liste an...

Gruß,
Aksels
 
Oh, das hatte ich komplett überlesen. Sorry, mein Fehler. Bei der 1200er kannst du das vergessen. Das geht nur bei der 1500er.

Vielleicht weiß ja jemand aus dem Forum, warum das bei der 1200er nicht möglich ist:confused:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@HelleBarde: Das bringt aber die Meldung: "...enthält globale Bausteinzugriffe..."
Allerdings lässt er mich weitermachen. Seither war das doch gesperrt? Nur hab ich da was von Hellebarde missverstanden?
Wenn ich auf globale Bausteine jetzt zugreifen darf, dann kann ich doch auch direkt auf den Array-DB zugreifen, oder?

Aksels
 
Hallo Leute,

ich war heute auf dem TIA Vortrag. Und ratet mal: Arrays dürfen nun seit TIA V13 SP1 in den Grenzen Konstanten enthalten:
Array[0.."m_Ausgang_Bytes"] of "UDT_Ausgang_Auto_Man"
m_Ausgang_Bytes ist eine Anwenderkonstante. Die Deklaration steht im Static eines Typisierten FBs. Wenn das wirklich klappen sollte hat die ganze Rumfroscherei ein ENDE!

Wow!

Aksels
 
Zurück
Oben