TIA Datenbaustein mittels Schleife durchlaufen

fabianfischer

Level-2
Beiträge
55
Reaktionspunkte
38
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich habe folgendes Problem und suche eine Lösung:

Ich möchte auf einer S7 1500 einen Datenbaustein anlegen,welcher eine definierte Anzahl von immer gleichen Strukturen enthält.

Im Detail:

Datenstruktur Vars:
- value (STRING)
-old_value (STRING)

DatenbausteinDB10:
Motor1(Vars)
Motorxyz(Vars)
HVAC1 (Vars)
Lights(Vars)

Nun möchte über ein SCL Programm den Datenbausteinmittels einer Schleife von Anfang bis Ende durchlaufen und z. B. Motor1.valuenach Motor1.old_value kopierenund genau an dieser Stelle komme ich nicht weiter, da ichja keinen Index für die Schleife habe über den ich auf den Wert zugreifenkönnte.

Das das Ganze mit einem Array of Vars im DB funktioniert ist mir klar, jedoch verliere ich dann die Möglichkeit in demAnwenderprogramm über den symbolischen Klartext-Namen auf die Werte zuzugreifen z. B.DB10.Lights.value.

Hat vielleicht jemand einen Lösungsansatz für dasProblem?

Vielen Dank im Voraus.

 
Ich würde versuchen, mittels AT-Sicht ein Array[1..5] of vars und ein Struct mit 5 vars-Variablen übereinander zu legen (falls das auf der 1500 geht). Bei 100 Variablen macht das aber keinen Spaß mehr.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich muss gestehen, dass ich aus deiner Frage nicht so recht schlau werde.
Folgenden Vorschlag habe ich allerdings :
Warum das Ganze in einem externen DB verwalten ? Der SCL-FB könnte doch die gewünschten/benötigten Variablen direkt und selbst haben. Dadurch hast du den gewünschten symbolischen Zugriff und dein SCL-Code passt IMMER zu deiner Datenquelle.

Gruß
Larry
 
Ich würde versuchen, mittels AT-Sicht ein Array[1..5] of vars und ein Struct mit 5 vars-Variablen übereinander zu legen (falls das auf der 1500 geht). Bei 100 Variablen macht das aber keinen Spaß mehr.

Harald

Hallo Harald,

danke für den TIP, mit der AT-Ansicht habe ich jedoch noch nicht gearbeitet, werde mich aber kurzfristig belesen.
Hatte bereits eine gedanklich ähnliche Idee, dass ich den händisch angelegten DB oder vielmehr seinen Inhalt in eine Struktur verpacke und dann die Struktur zur Laufzeit in einen Temp DB mit Array kopiere.

Gruß Fabian
 
Hallo,
ich muss gestehen, dass ich aus deiner Frage nicht so recht schlau werde.
Folgenden Vorschlag habe ich allerdings :
Warum das Ganze in einem externen DB verwalten ? Der SCL-FB könnte doch die gewünschten/benötigten Variablen direkt und selbst haben. Dadurch hast du den gewünschten symbolischen Zugriff und dein SCL-Code passt IMMER zu deiner Datenquelle.

Gruß
Larry

Hallo Larry,
zum besseren Verständnis nachfolgende Erläuterung.

Ich möchte einen globalen DB als eine Art globale Variablenliste deklarieren in dem Werte in Form einer Struktur enthalten sind.

Die Werte sollen im Anwendungsprogramm gesetzt und ausgelesen werden. Um die Übersichtlichkeit nicht zu verlieren soll der Zugriff auf die Werte über den symbolischen Namen z. B. db10.Motor1.value anstatt db10.daten[1].value erfolgen. Soweit ist das ganze ja ohne Probleme realisierbar.

Nun möchte ich aber wenn alle FBs abgearbeitet sind mittels einer Schleife den DB durchlaufen und jeweils den aktuellen Wert (z. B. db10.Motor1.value) in den alten Wert (z. B. db10.Motor1.old_value) umkopieren und vorher durch Vergleich prüfen ob sich die Wert (alt/aktuell) im Gegensatz zum letzten Zyklus geändert hat.

Der DB soll ca. 200 gleiche Strukturen enthalten.

Gruß Fabian
 
Ich habe in Step7 classic so gut wie nie mit Pointern gearbeitet, deshalb nur vielleicht eine Möglichkeit:

den DB nicht optimiert einstellen und das ganze wie in der classic-Welt mit Pointern abarbeiten?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Irgendwas in Deinem Programm beschreibt doch den String .value in den Strukturen (idealerweise ein FB oder eine Function, der genau eine vars-Struktur übergeben wird, gerne als UDT). Es wäre elegant und schön gekapselt, wenn dieser Code auch das Umkopieren von .value nach .old_value machen würde. Dann müßtest Du nicht nochmal die List_of_vars als Array_of_vars durchgehen.

Harald
 
Ich habe jetzt ersteinmal die Variante mit der AT-Sicht probiert und musste feststellen, dass dies erst einmal nur in einem FB geht dazu bin ich folgt vorgegangen.

Datenstruktur Vars:
- value (STRING)
- old_value (STRING)

Datenstruktur Alle_Vars:
- Motor1 (Vars)
- HVAC1 (Vars)

Programm1 FB1 (SCL):

Variablendeklaration
Variablen (Alle_Vars)
Variablen_Schleife AT Variablen (Array[0..1] of Vars)

Nun kann ich im Anwenderprogramm über den symbolischen Namen (z. B. FB1.Variablen.Motor1.value) auf die Werte zugreifen und über Variablen_Schleife[0] das ganze in der Schleife verarbeiten.
Jetzt bleibt aber noch zu lösen wie ich die Namen (Motor1, HVAC1) der Strukturen in der Schleife herausbekomme, da ich die Informationen ja mit Variablen_Schleife[0] bis Variablen_Schleife[1] überschrieben habe.

Gruß Fabian
 
Irgendwas in Deinem Programm beschreibt doch den String .value in den Strukturen (idealerweise ein FB oder eine Function, der genau eine vars-Struktur übergeben wird, gerne als UDT). Es wäre elegant und schön gekapselt, wenn dieser Code auch das Umkopieren von .value nach .old_value machen würde. Dann müßtest Du nicht nochmal die List_of_vars als Array_of_vars durchgehen.

Harald

Das Programm unterteilt sich in folgende Blöcke:

Eingabe:

Es werden UDP Telegramme im Format Motor1=12#Lights=1# empfangen, der String wird zerlegt und die entsprechenden Werte (z. B. DB1.Motor1.value) im DB aktualisiert.

Verarbeitung:

Gegebenenfalls wird ein Wert auf Grund der SPS Logik verändert, der Zugriff erfolgt über den symbolischen Namen (z. B. DB1.Motor1.value) wegen der Übersichtlichkeit.

Ausgabe:

Der DB wird per Schleife durchlaufen um zu prüfen ob .oldvalue ungleich .value ist, sollte dem so sein wird der Wert an eine Stringkette angefügt, welche mittels UDP versandt wird. Im gleichen Schritt wird .old_value mit value gefüllt um im nächsten Zyklus wieder den Vergleich auf Änderung zu machen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nun möchte ich aber wenn alle FBs abgearbeitet sind mittels einer Schleife den DB durchlaufen und jeweils den aktuellen Wert (z. B. db10.Motor1.value) in den alten Wert (z. B. db10.Motor1.old_value) umkopieren und vorher durch Vergleich prüfen ob sich die Wert (alt/aktuell) im Gegensatz zum letzten Zyklus geändert hat.

Hallo Fabian,
das angeführte Argument spricht jetzt aber nicht gegen meinen Vorschlag sondern viel eher dafür.
Die Instanz eines FB ist ein DB wie jeder andere auch - sie/er wird "nur" durch den FB verwaltet - und genau das wäre ja hier der "Trick". Du könntest so über den/einen spezifizierten FB-Aufruf diese Kummulations-Verarbeitung iniziieren.

Gruß
Larry
 
Also wenn in dem DB ein Array of UDT liegt kannst dir einen FB machen und das UDT da als Variable deklarieren, dann machste eine Schleife in der als Index die Arraynummer hochgezählt wird, kopierst das UDT aus dem Array in dein lokales, kannst da symbolisch alles kopieren was du willst und kopierst das lokale UDT am Ende wieder in das Array mit dem entsprechenden Index. So kannst du durch das gesamte Array rennen und alles symbolisch machen.
Ich mach das aber immer in SCL, sollte aber in AWL auch so funktionieren.
 
Also wenn in dem DB ein Array of UDT liegt
Ich fasse mal zusammen, wie ich den TE verstehe:

Es geht um eine S7-1500 und TIA.

Der TE hat einen Global-DB mit einer Ansammlung von 200 "UDT" hintereinander (wie in einem Array of UDT). Er könnte diese Ansammlung von UDTs als Array deklarieren, doch er will im Programm jeden UDT mit einem eigenen "sprechenden" symbolischen Name ansprechen, und nicht als "anonymes" Arrayelement[x].

Zusätzlich will er aber diese Ansammlung von UDTs auch in einer Schleife bearbeiten, wozu diese Ansammlung als Array deklariert sein müßte oder auf ein Array abgebildet werden müßte oder sonstwie indiziert ansprechbar sein müßte.

Anscheinend sollen die UDTs nicht Teil von FB-Instanzen sein und jeden der 200 UDT in einen eigenen DB legen scheint auch nicht gewünscht zu sein. Den kompletten DB mit mehreren KByte zweimal umzukopieren (auf ein Array und zurück) ist keine schöne Lösung.


Seine Frage: Wie kann man einem Arrayelement einen eigenen symbolischen Name geben oder wie kann man eine nicht als Array deklarierte Datenstruktur indiziert ansprechen?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Nun kann ich im Anwenderprogramm über den symbolischen Namen (z. B. FB1.Variablen.Motor1.value) auf die Werte zugreifen und über Variablen_Schleife[0] das ganze in der Schleife verarbeiten.
Jetzt bleibt aber noch zu lösen wie ich die Namen (Motor1, HVAC1) der Strukturen in der Schleife herausbekomme, da ich die Informationen ja mit Variablen_Schleife[0] bis Variablen_Schleife[1] überschrieben habe.
Wozu willst Du in der Schleife die Namen der Strukturen herausbekommen?
Aus einem gegebenen Arrayindex i kann NICHT der zugehörige alternative Name der Struktur ermittelt werden.

Außerhalb der Schleife bzw. des FB kannst Du die Variablen als IDB1.Variablen.Motor1.value direkt ansprechen, in der Schleife kannst Du sie als Variablen_Schleife.value indiziert ansprechen. In dem FB außerhalb der Schleife kannst Du die Variablen als Variablen.Motor1.value oder als Variablen_Schleife[0].value direkt ansprechen.


Ich kenne das TIA und die S7-1500 nicht, doch eine Frage: kann man vielleicht an einem FB-IN_OUT ein "Array[1..200] of Vars" deklarieren und außen beim Aufruf eine Struktur mit 200 sequentiellen Vars anschalten/übergeben?

Harald
 
Wozu willst Du in der Schleife die Namen der Strukturen herausbekommen?
Aus einem gegebenen Arrayindex i kann NICHT der zugehörige alternative Name der Struktur ermittelt werden.

Außerhalb der Schleife bzw. des FB kannst Du die Variablen als IDB1.Variablen.Motor1.value direkt ansprechen, in der Schleife kannst Du sie als Variablen_Schleife.value indiziert ansprechen. In dem FB außerhalb der Schleife kannst Du die Variablen als Variablen.Motor1.value oder als Variablen_Schleife[0].value direkt ansprechen.


Ich kenne das TIA und die S7-1500 nicht, doch eine Frage: kann man vielleicht an einem FB-IN_OUT ein "Array[1..200] of Vars" deklarieren und außen beim Aufruf eine Struktur mit 200 sequentiellen Vars anschalten/übergeben?

Harald


Hallo Harald,

du hast das Problem vollständig und richtig erkannt.

Die Struktur Namen in der Schleife benötige ich um den UDP Sende String wieder zusammen zu bauen.

Beispiel Sende String: Motor1=12#Lights=1#

Erläuterung: Motor1 entspricht dem Struktur Namen und 12 ist der in der Struktur gespeicherte Wert.

Da ich auch zu dem Ergebnis gekommen bin, dass man zu einem Array Element in der AT-Ansicht NICHT den zugehörigen alternative Name der Struktur ermitteln kann, habe ich in der Struktur eine weitere Variable angelegt in der ich den symbolischen Namen noch einmal eintragen muss.

Ist nicht ganz das was ich gesucht habe lässt sich aber technisch scheinbar nicht anders lösen.

Gruß Fabian
 
Hallo Fabian,
das angeführte Argument spricht jetzt aber nicht gegen meinen Vorschlag sondern viel eher dafür.
Die Instanz eines FB ist ein DB wie jeder andere auch - sie/er wird "nur" durch den FB verwaltet - und genau das wäre ja hier der "Trick". Du könntest so über den/einen spezifizierten FB-Aufruf diese Kummulations-Verarbeitung iniziieren.

Gruß
Larry

Hallo Larry,

dein Vorschlag wird meiner Meinung nach nicht funktionieren, denn wenn ich im SCL FB auf die Strukturen zugreifen will benötige ich einen Zeiger auf ein Array, wenn ich die Strukturen aber über ein Array im FB initiiere kann ich für die Strukturen keine Namen mehr vergeben um symbolisch über den Instanz DB auf selbigen zuzugreifen.

Oder habe ich etwas falsch verstanden?

Gruß Fabian
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... denn wenn ich im SCL FB auf die Strukturen zugreifen will benötige ich einen Zeiger auf ein Array, wenn ich die Strukturen aber über ein Array im FB initiiere kann ich für die Strukturen keine Namen mehr vergeben um symbolisch über den Instanz DB auf selbigen zuzugreifen ...

Hallo Fabian,

kannst du mir den Satz bitte mal ins Deutsche übersetzen ?

Ganz allgemein :
Wenn du dein Array of Struct im Variablen-Bereich deines Bausteins deklarierst dann kennt der Baustein die Struktur, deren Aufbau und alle ihrer Einzel-Elemente darin.
Du kannst sie also voll-symbolisch ansprechen - ganz besonders schön in SCL ...

Gruß
Larry
 
Irgendwie ist das ein Fall von wasch mich, aber mach mich nicht nass.
Solche Konstrukte wie Arrays und UDTs sind ja genau für sowas gedacht, wenn das aus irgendwelchen Gründen nicht gewollt ist muß man sich was einfallen lassen.
Man könnte mit Offsets hantieren, sich quasi ein Unterprogramm schreiben das beim Aufruf der Motornummer den entsprechenden Offset im DB ermittelt wo dieser Datensatz anfängt und dann sich von da weiterhangeln, da ist man allerdings bei absoluter Adressierung und das ist ja irgendwie pfui.
Ansonsten könnteste dir so eine Art Parser schreiben, der Symbolik der Motoren eine Zahl macht die du als Index benutzen kannst. Wobei ich das Array für die sauberste Lösung halte und sich mir nicht wirklich erschließt warum das nicht gehen soll. Array[1] ist eben Motor 1 usw. aber das muß jeder selber wissen.
 
Zurück
Oben