TIA indirekter Zugriff auf symbolische Variablen

HWH

Level-1
Beiträge
2
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo TIA Experten

Ich habe hoffentlich nur ein Verständnisproblem mit der TIA Programmierung.
Wir setzen mittlerweile immer mehr die 1500er Steuerungen ein. Daher bin ich dabei, langsam die altbekannten Bausteine aus der 300/400 anzupassen. Als Programmiersprache nutze ich AWL oder SCL. In der 1500 soll man ja nur noch Symbolisch programmieren, was ich an und für sich gar nicht so schlecht finde, bei CoDeSys geht es ja auch. Aber jetzt kommt das Problem, Ich habe bei der 300/400 oft mit indirekter Adressierung sowie ANY-Pointern usw. gearbeitet. Das beißt sich aber mit der symbolischen Programmierung. Zumindest habe ich nichts Passendes darüber gefunden.
z.B. habe ich bisher oft den SFC20 (BLKMOV) benutzt. In der 1500 mit den optimierten Bausteinen geht das natürlich nicht mehr, da ja keine Adressen mehr bekannt sind. Habe jetzt mit MOVE und MOVE_BLK_VARIANT experimentiert, es scheitert aber daran, dass ich einen VARIANT-Zeiger anscheinend nicht manipulieren kann. Erst dachte ich eine CASE-Anweisung und VARIANT_PUT wären die Lösung, allerdings erhalte ich immer dann eine Meldung „Zugriff durch nicht initialisierten Pointer“. Auch mein Versuch über den Umweg aus der CONCAT Anweisung und String-Zeichenketten etwas zu basteln ist kläglich gescheitert.
Meine Frage(n):
Wie kann ich einen VARIANT-Zeiger zur Laufzeit manipulieren,
Wie kann ich indirekt auf eine symbolische Variable zugreifen? z.B. statt U „Motor01“. Betrieb -> U Motor[DB_Index]. Betrieb

Natürlich kann man die Optimierung ausschalten und auch weiterhin mit absoluten Adressen arbeiten, aber das soll man ja nicht mehr, schon aus Performancegründen und vor allem wo ist dann die Verbesserung, wenn so grundlegende Sachen nicht mehr gehen?

Danke für eure Infos
 
Moin HWH

Wie kann ich indirekt auf eine symbolische Variable zugreifen? z.B. statt U „Motor01“. Betrieb -> U Motor[DB_Index]. Betrieb

Hast Du für jeden Motor einen eigenen DB?
Besser wären alle Motoren mit gleicher Struktur in einem DB.

Dann kannst Du im DB als Datentyp angeben:

MOTOR Array[0..9] of Motordatentyp

==>
Motor[0].Motordatentyp
Motor[1].Motordatentyp
.
.
Motor[9].Motordatentyp

Motordatentyp:
Ein BOOL
Aus BOOL
Solldrehzahl INT
Istdrehzahl INT
.
.

Beispiele:
Motor[3].Ein := true;
Motor[3].Solldrehzahl := 1200;

Ich würde sogar auf AWL verzichten.
Meine favborisierten Programmiersprachen sind:
- SCL (AWL war von S eigentlich gar nicht vorgesehen und ist nur nachträglich noch implementiert worden)
- KOP (ist aus meiner Sicht für Fehlersuche besser geeignet als FUP)
- Graph (schön flexibel bei großen Schrittketten)

In SCL kannst Du gleiche Strukturen komplett statt mit BLK_MOVE mit einer Zeile übergeben:

Tag.Struct1 := Tag23.Struct1;


Insgesamt schätze ich, dass dieses Thema wieder sehr aufgebläht wird mit allen möglichen Meinungen ;).


Den Variant-Zeiger kannst Du nicht manipulieren. Um zur Laufzeit variabel auf Daten zuzugreifen gibt es MOVE_BLK_VARIANT. Das hattest Du ja auch schon gefunden. Noch ein Hinweis:
Damit kannst Du nur gleiche Strukturen übertragen. Um von einer Struktur auf eine andere zu wechseln beötigst Du Serialize und Deserialize. Mit Serialize wird ein Datentyp in ein Array[0..n] of <Datentyp> übertragen (ich bin mir nicht sicher, ob als Datentyp auch was anderes als Byte geht. Ich benutze jedenfalls Byte). Mit Deserialize wird ein Array[0..n] of <Datentyp> in einen Datentyp (z.B. eine Struktur) übertragen.
Wenn Du bei hintereinanderschaltest, kannst Du eine Struktur von Daten in eine andere Structur überführen.

Ich benutze das bei Schnittstellentelegrammen. Erst gucke ich mir den Telegrammkopf an und die Daten sind ein Array[0..n] of Byte. Wenn ich die Telegrammart kenne (Lebenstelegramm, Auftrag, Status, Befehl, etc.) überführe ich das Roh-Telegramm in die entsprechende Struktur.


VG

MFreiberger
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie kann ich einen VARIANT-Zeiger zur Laufzeit manipulieren
Gar nicht, Variant hat nicht wirklich was mit einem klassischen Pointer gemein.
Den Variant selber kann man weder kopieren noch sonst irgendwie bearbeiten.
Wie kann ich indirekt auf eine symbolische Variable zugreifen? z.B. statt U „Motor01“. Betrieb -> U Motor[DB_Index]. Betrieb
Variabler Zugriff über zusammengebauten Variablennamen ist nicht möglich.

Das letztere Könntest du über sogenannte Array-Dbs lösen.
Datenbaustein mit Namen "Motor" als Array-DB abgeleitet von einem UDT-Datentyp erzeugen. Zugriff ala U "Motor".THIS[Indexvariable].Statuswort
Oder das Array einfach in nem Global-DB erzeugen.

Indirekte Adressierung ist bei optimierten Datenbausteinen eigentlich nur möglich unter Basis einer vorliegenden Array-Struktur.
Sonst wird auch noch Case als "indirekte Adressierung" gezeigt - https://support.industry.siemens.com/cs/ch/de/view/97552147

Freien Zugriff auf nicht zur Compile-Zeit bekannte Datenbereiche, ähnlich POINTER/ANY wie bei 300/400, gibt es nicht.
 
Zuletzt bearbeitet:
Danke erstmal für eure raschen Antworten.

Ich glaube über Programmiersprachen brauchen wir hier nicht zu philosophieren, da gibt es 1000 Argumente dafür und dagegen. Ich persönlich mag halt mal kein KOP/FUP und Graph, anderen gefallen sie, aber das ist ja auch egal.;)

Konkret habe ich für jeden Motor einen FB (und damit natürlich eine Instanz). Wenn man auf der Visu auf das Motorensymbol klickt, wird ein Popup-Fenster geöffnet mit der Bedienung, Zustand, Betriebsstunden, Wartungszyklus, Strom, Frequenz usw.
Für die Verwaltung des Popup-Fensters gibt es einen FC, der die Daten vom Motorsteuerungsbaustein hin- und her schubst. Dazu muss ich Teile des Instanz-DB’s in den „PopUp*-DB kopieren und umgekehrt. Das gleiche gibt es auch für Prozessventile. Ich mach das seit Jahren so, mit direkten Adressen klappt das auch sehr gut und unseren Kunden gefällt’s.
Diese Beispiele lassen sich noch endlos fortsetzen.

Es ist anscheinend wirklich so, wie ich befürchtet habe. Ich werde mich damit abfinden, dass ich bei vielen Anwendungen auf den optimierten DB verzichten muss. Vielleicht gibt’s ja bald eine V15, die das kann.

Danke für eure Mühe, Gruß
 
@TE:
Es gibt für dein Vorhaben bestimmt einen Ansatz, es umzusetzen ohne herum-zu-pointern. Der Vorschlag von MFreiberger ging da für mich schon in die aus meiner Sicht richtige Richtung. Für uns ist es an so einer Stelle immer schwierig, Vorschläge zu machen da man mitunter schon sehr gut verstehen muss, was der andere macht, um sinnvoll helfen zu können ... Das war jetzt bei dir möglicherweise eher nicht der Fall ...

In jedem Fall : ob das mit dem "optimierten Bausteinzugriff" von Siemens her wirklich so der Bringer war mag ich nicht entscheiden wollen - dazu gehen hier im Forum aber auch die Meinungen (mittlerweile) ganz schön auseinander ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich glaube die Idee von Siemens fuer das Problem vom TE sind diese ARRAY of FB oder wie das heisst. Also die Motor-FBs alle in einem FB als Multiinstanz aufrufen, dann sollten alle Instanz-DBs des Motor-FB als Array verfuegbar sein. Hab ich aber noch nicht ausprobiert...
Die 2. Variante: Die im Panel benoetigten Daten in nen UDT zusammenfuehren und vom Motor-FB als IN OUT oder INOUT in nen GlobalDB (der hat dann die Arrays von diesem UDT) uebergeben.
Oder halt wie oben schon angesprochen, fuer den Motor nen FC verwenden und alle Daten in nem GlobalDB mit Arrays zu halten...

Gruss

PS : die Variante mit den Multiinstanzen wuerd ich so nicht nutzen, Stichwort Reinitialisieren bei Aenderungen im laufenden Betrieb. Wir nutzen schon seit Jahren die Variante 3 mit den Motor-FCs auch unter 300/400. Im TIA sind dann aber diese FCs nicht Bibliotheksfaehig. Bleibt also eigentlich nurnoch Variante 2. Alles was nen anderer braucht, ueber die Bausteinschnittstelle zu uebergeben...

PPS: ich programmiere im TIA zwar auch gern sybolisch mit Arrays, aber nutze ausschliesslich nichtoptimierte DB FC FB! Somit kann man auch problemlos absolut Adressieren...
 
Zuletzt bearbeitet:
Hallo ducati,

wir haben die selbe Philosophi, würde jede einzelne deiner Aussagen unterschreiben, einschliesslich PS und PPS.

Im speziellem Falle des TE sollte allerdings unter Verwendung eines GlobalDB auch ein bibliotheksfähiger Baustein möglich sein, an dem das ARRAY, der Datensatz des HMI und der angewählte Index parametrierbar sein sollten. Soweit könnte das vielleicht auch mit optimierten Bausteinen funktionieren. Wenn es bei der eingangs erwähnten Funktion bleibt, genügt in SCL eigentlich auch schon eine einfache Zuweisung des ARRAY-Elementes auf den HMI-Datensatz, bzw. in FUP/KOP/AWL ein BLOCK_MOVE_VARIANT.

Gruß, Onkel
 
Zuletzt bearbeitet:
Zurück
Oben