TIA TIA - Softwarestruktur

Jochen Kühner

Level-3
Beiträge
4.291
Reaktionspunkte
527
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich will mal Testweise unser Programm auf 1500 umstellen. Dazu versuche Ich nun das ganze auch vollsymbolisch etc zu lösen. Nun, wir Programmieren Fördertechnik, und haben für jeden Stellplatz einen DB! Diese Struktur möchten wir auch gerne beibehalten, da ein DB mit einem Platzarray uns zu unflexibel etc erscheint. Auch sehen wir da Schwierigkeiten beim erweitern, und wollen ja auch die Platznamen und nicht ein Arrayindex im Program verwenden.

Ok, nun zu meinem Problem. Wie gesagt Ich habe einen DB für jeden Platz. Dieser wird als Instanz eines UDTs erzeugt. In den ersten 10 Bytes steht nun der Platzname. Nun habe Ich eine Kopplung welche Telegramme empfängt, welche dann in den entsprechenden Platz DB kopiert werden sollen.

Dies geht unter AWL so: Ich gehe alle DB's von 1000 bis max durch, vergleiche den Platznamen, wenn gleich trage Ich die Daten in den DB ein! Funz ja alles da Ich indirekt adressieren kann! Ist dies auch mit SCL in TIA und vollsymbolischen DBs möglich?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du kannst doch das ganze in SCL mit ner z.B. for-Schleife durchlaufen, in der Schleife dann den Platznamen vergleichen falls richtig die Daten eintragen und die Schleife beenden?!?!
 
So wie ich das sehe, musst Du über alle Platz Instanzen iterieren, dort jeweils eine Get Property aufrufen, die Dir den zugehörigen Datenbaustein liefert und dann kommt der Vergleich und wenn gefunden der Datenupdate.

Die Get Property sollte eine Referenz auf den DB liefern, dann kannst Du direkt auf die Daten zugreifen und schreiben oder Du brauchst auch noch eine Set Property, wenn es "ordentlich" und sicher sein soll.

So würde ich das in Codesys ST angehen. Wie schon öfters angedeutet mit TIA und Siemens kann es weniger elegant sein, aber nach einigen Programmen mit 1200 und TIA 11 abe ich schnell wieder dieses Feld den Siemens Fans überlassen.
 
Du kannst doch das ganze in SCL mit ner z.B. for-Schleife durchlaufen, in der Schleife dann den Platznamen vergleichen falls richtig die Daten eintragen und die Schleife beenden?!?!

Ich will ja die Platznamen nicht in meinem Kopplungsbaustein hinterlegen, sonst muss Ich den Baustein ja bei jeder Analgen anpassen! Im Moment lese Ich diese aus den DBs!
 
Ja aber wie kann Ich über die Platz Instanzen Iterieren? Die sind ja nicht in einem Array...

Du kannst doch in der Schleife einen Index für die DB Nummer inkrementieren......(aber vollsymbolisch ist das halt nicht)

Code:
Platz_DB : INT;

WORD_TO_BLOCK_DB(INT_TO_WORD(Platz_DB)).XXXXX
 
Du kannst doch in der Schleife einen Index für die DB Nummer inkrementieren......(aber vollsymbolisch ist das halt nicht)

Code:
Platz_DB : INT;

WORD_TO_BLOCK_DB(INT_TO_WORD(Platz_DB)).XXXXX

Jetzt sind wir so weit:
Warum auch vollsymbolisch programmieren? :ROFLMAO:

Ich halte meine Belegung, ob oder ob nicht, in einem DB aus dieser Position in diesem Baustein berechne ich den entsprechenden DB.
Das geht symbolisch, da die Symbole so angelegt sind.
Muss mal schauen, ob das noch in TIA geht, habe ich noch nicht.


bike
 
Wenn ich dich richtig verstehe, würde man für so etwas einen Zeiger oder Referenzen verwenden.
Zumindest würde ich mir dann ein Array von Referenzen anlegen, die Adressen (Zeiger) auf die entsprechenden DBs setzen und dann in einer Schleife alle durchgehen.

Leider gibt es für "optimierte" Programmierung im TIA-Portal weder Zeiger noch Referenzen, das heißt man muss sich was anderes überlegen.

Eine Möglichkeit die auch die Hilfe aufzeigt, ist, einen FC zu schreiben der anhand eines übergebenen Index die zugehörige UDT zurückgibt. Das ist sozusagen eine händisch ausprogrammierte Liste.
Code:
FUNCTION "GetTypeDbByIndex" : "dtTest1"
VERSION : 0.1
   VAR_INPUT 
      Index : Int;
   END_VAR
BEGIN
	CASE #Index OF
	    1:
	        #GetTypeDbByIndex := "DBofdtTest1_1";
	    2:
	        #GetTypeDbByIndex := "DBofdtTest1_2";
	    3:
	        #GetTypeDbByIndex := "DBofdtTest1_3";
	END_CASE;
END_FUNCTION

Dem Programmierer der etwas auf Effizienz bedacht ist, stellen sich dabei natürlich die Fußnägel auf. Weil jedes Mal je nach Größe der Struktur mehr oder weniger große Datenmengen durch die Gegend kopiert werden, wo in jeder anderen Sprache ein Zeiger/Referenz gereicht hätte.

Wenn mit der gleichen Denkweise das TIA-Portal programmiert wurde, wundert es einen nicht warum alles so zäh und langsam ist.

Es gibt noch den Datentyp "Variant", der evtl. mal für sowas gedacht ist. Aber dieser Datentyp ist irgendwie nur da, ohne dass er dokumentiert ist was man sinnvolles damit anstellen kann. Bei V13 sind in der Hilfe ein paar Erläuterungen und komische Funktionen wie VariantPut/Get hinzugekommen, aber ich bin noch nicht schlau geworden was man damit anstellen können soll.

Diesen ganzen Zoo von Hilfsfunktionen und komischen Datentypen hätte man weglassen können, indem man ganz einfach einen Zeiger/Referenzdatentyp ermöglichen würde. Vielleicht kommt sowas ja in V19 so gegen 2026...
 
Mir ist ehrlich gesagt nicht ganz klar warum ihr das nicht in einem Array lösen wollt?
Wenn es von der max. DB-Größe passt hab ich das in Classic schon immer als Array of UDT oder Struct gelöst.
TIA müsste bei optimierten DBs beim Erweitern eigentlich besser sein als Classic. Ansonsten geht immer noch der Umweg über AWL-Quellen.
Gruß
Dieter
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn er ein Array verwendet möchte, hätte er das Problem nicht, klar.
Bei Einzel-DBs hat man aber die Möglichkeit ein sprechenderes Symbol mit Kommentar zu vergeben.
Mit einem Array kann man viel machen, nachher läuft es aber auf ein Programm hinaus was ein Array[100] of Messstellen, Array[200] of Ventile und Array[50] of Motoren hat. Das hat auch nicht nur Vorteile.

Bei S7 Classic und selbst bei der S5 konnte man sowas effizient umsetzen, nur beim TIA-Portal scheint es (noch?) nichts dafür zu geben.

Ich weiß nicht wie das z.B. bei den Motion-Control Bausteinen im TIA-Portal gelöst ist. Ob der Parameter zur den Achsdaten eine wie auch immer geartete Referenz ist die einem als Anwender nicht zur Verfügung steht, oder ob dieser "per Value" dem Baustein übergeben wird. Da die Achsdaten nicht gerade klein sind, bläht das wenn "per Value" ungemein auf.
 
Mir ist ehrlich gesagt nicht ganz klar warum ihr das nicht in einem Array lösen wollt?
Wenn es von der max. DB-Größe passt hab ich das in Classic schon immer als Array of UDT oder Struct gelöst.
TIA müsste bei optimierten DBs beim Erweitern eigentlich besser sein als Classic. Ansonsten geht immer noch der Umweg über AWL-Quellen.
Gruß
Dieter

Weil wir das in unserm Standart so seit Jahren Problemlos einsetzen, und noch nie Probleme hatten eine laufende Anlage zu erweitern. Wenn wir neue Plätze hinzufügen, gibts neue DBs und keine Probleme. Man weiss sofort welche DB für jeden Fördertechnikplatz zuständig ist, und muss nicht erst schaun welchem Arrayindex entspricht welcher Platz...

Nur so wie Ich das seh bringt mir Vollsymbolisch damit gar nichts...

@Thomas_V2.1:
Ja, dache an zumindest das mit einer 1500er Zeiger auf einen Bereich möglich wären ohne das Ich diesen vorher umkopieren muss. Gibts sowas nicht?
 
Ja, dache an zumindest das mit einer 1500er Zeiger auf einen Bereich möglich wären ohne das Ich diesen vorher umkopieren muss. Gibts sowas nicht?

Ich habe die Möglichkeit zumindest noch nicht gefunden. Wenn dann ist sie gut versteckt. Aber es gibt mittlerweile ein gutes Dutzend Speicherzugriffsfunktionen, die aber alle entweder nur in "nicht optimierten" Bausteinen funktionieren, oder nicht wirklich nützlich zu verwenden sind.

Ich denke mal ein Zeiger oder Referenzkonzept ist einfach nicht vorgesehen worden. Ich kann mir zwar vorstellen, dass so ein Konzept wegen der Möglichkeit des Austauschs und Erweiterung von Programmteilen im laufenden Betrieb problematisch sein kann (gespeicherte Zeiger werden ungültig), aber andere (z.B. Codesys) bekommen das auch hin.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich weiß nicht wie das z.B. bei den Motion-Control Bausteinen im TIA-Portal gelöst ist. Ob der Parameter zur den Achsdaten eine wie auch immer geartete Referenz ist die einem als Anwender nicht zur Verfügung steht, oder ob dieser "per Value" dem Baustein übergeben wird. Da die Achsdaten nicht gerade klein sind, bläht das wenn "per Value" ungemein auf.

Hi Thomas

das ist ja mal eine spannende Frage.
Ich hatte auf einer 1518 mit den Motion Bausteinen rumgespielt. Mal rein aus Sicht der Zeitmessungen kann die 1500 mit Referenzen umgehen.

Allgemein für 1500 und 1200 gilt:
Wenn eine Struktur im Input eines FB ist, dann wird by-value übergeben, es dauert entsprechend lange.
Wenn eine Struktur im InOut eines FB ist, dann wird by-reference übergeben, es geht entsprechend schneller.
Für den Zugriff auf die Struktur im aufgerufenen FB macht es keinen Unterschied ob by-value oder by-reference übergeben wird.

Für Achsen gelten aber andere Regeln:
Bei der 1518 war es so, dass der MC-Power, obwohl er im Input die Achse übergeben bekommt genaus schnell war wie wenn die Achse an einem selbstgeschriebenen Baustein im InOut übergebe.

Ich bin dem aber letzes Jahr so kurz vor Weihnachten nicht mehr nachgegangen. Aber da werde ich doch nochmal nachbohren ...

'n schön' Tach auch
HB
 
@Thomas

Das fehlt mit auch, mir ist die ganze Zeit immer noch nicht ganz klar geworden, wie man vollsymbolisch wirklich effizient programmieren kann und dann vieleicht noch mit optimierten Bausteinen (was für eine schlimme Idee). Irgendwie fehlt mir genau die Möglichkeit, indiziert in beliebige Datenbausteine zu greifen. Auch das Konzept, alles über Arrays und deren Indizes zu machen, ist, auf Grund der immer noch vorhandenen Datenbausteine, nicht wirklich schön.
 
Im TIA Portal indirekt adressieren, siehe :
https://support.industry.siemens.com/cs/ww/de/view/97552147

Folgendes habe ich noch aus einer Doku rausgezogen:
Datentyp ARRAY und indirekte Feldzugriffe

Der Datentyp ARRAY repräsentiert eine Datenstruktur, die sich aus mehreren

Elementen eines Datentyps zusammensetzt. Der Datentyp ARRAY eignet sich z.B.

für die Ablage von Rezepturen, Materialverfolgung in einer Warteschlange,

zyklische Prozesswerterfassung, Protokolle, usw.



Mit einem Index (

array [„index“]) können Sie auf einzelne Elemente im

ARRAY indirekt zugreifen.


Vorteile
Einfacher Zugriff, da der Datentyp der ARRAY-Elemente irrelevant für den
Zugriff ist.

Keine umständliche Zeigererstellung notwendig


Schnelle Erstellung und Erweiterung möglich


Nutzbar in allen Programmiersprachen

Eigenschaften


Strukturierter Datentyp


Datenstruktur aus fester Anzahl von Elementen des gleichen Datentyps


ARRAYs können auch mehrdimensional angelegt werden


Indirekter Zugriff mit Laufvariable mit dynamischer Indexberechnung zur

Laufzeit möglich

Empfehlung


Benutzen Sie ARRAY für indizierte Zugriffe statt Zeiger (z.B. ANY-Pointer).

Dadurch wird das Programm leichter lesbar, da ein ARRAY mit einem

symbolischen Namen aussagekräftiger ist als ein Zeiger in einen

Speicherbereich.


Nutzen Sie als Laufvariable den Datentyp INT als temporäre Variable

Nutzen Sie die Anweisung „MOVE_BLK“, um Teile eines ARRAYs in ein

anderes zu kopieren.


Nutzen Sie die Anweisung „GET_ERR_ID“, um Zugriffsfehler innerhalb des

Arrays abzufangen.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Allgemein für 1500 und 1200 gilt:
Wenn eine Struktur im Input eines FB ist, dann wird by-value übergeben, es dauert entsprechend lange.
Wenn eine Struktur im InOut eines FB ist, dann wird by-reference übergeben, es geht entsprechend schneller.
Codesys handelt das exakt genau so. Das bringt einen gewaltigen Performance Vorteil, wenn man VAR_IN_OUT auf Structs durchgängig anwendet. Das ist auch der Grund, warum in .NET und C# das sogar die einzige Möglichkeit ist, es gibt nur noch Referenzen auf Objekte.



Für Achsen gelten aber andere Regeln:
Bei der 1518 war es so, dass der MC-Power, obwohl er im Input die Achse übergeben bekommt genaus schnell war wie wenn die Achse an einem selbstgeschriebenen Baustein im InOut übergebe.
HB

Die Softmotion von Codesys verwendet durchgängig dieses Konzept bei den MC_ (CIA 402) Aufrufen. Vielleicht gibt das schon die PLC Open so vor.
 
@zako

Ja, dein Siemens-Beitrag zeigt ja, was Thomas schon gezeigt hat, man muß dann z.Bsp. mit einer Case-Anweisung arbeiten und alle z.Bsp. DB händisch eintragen. Das setzt voraus, man kennt diese schon beim Programmieren mit symbolischem Namen. Will man das erweitern, dann muß man nachtragen. Oder man nutzt Array mit Index, kann dann aber keine so schönen symbolischen Namen mehr nutzen und hat ein Problem, wenn man den DB wechseln will, weil man z.Bsp. Rezeprgruppen in DB verwaltet. Da fehlt mit irgendwie noch ein ganz kleines Stück, aber villeicht fällt uns noch etwas ein. :)
 
Für einen besonderen user schreibe ich l a n g s a m. :ROFLMAO:

@Ralle: ich verwende einen IndexDB.
In diesem sind die Namen der DB als Symbol hinterlegt.
Die Aufrufe gehen von 0 bis x.
Daraus wird der DB ermittelt.
Ändert sich der das Symbol, so muss dies in diesem IndexDb gemacht werden und sonst nirgends.

Ist nicht die schönste Art und Weise, doch funktioniert schon in Step7 Classic.
Auch in Hochsprachen müssen Variablen definiert werden, und wie ist eine Symboltabelle zu bezeichnen?
Und eine PLC ist nach wie vor nicht zur Datenverwaltung gebaut und das muss auch nicht sein, nach meiner Meinung.


bike
 
Zurück
Oben