Dynamische Datenstrukturen in S7-SCL

jck0815

Level-1
Beiträge
28
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ist es irgendwie möglich dynamische Datenstrukturen in SCL anzulegen? Speziell möchte ich in Abhängigkeit eines Parameters ein UDT (oder auch DB) mit Verschiedenem Inhalt erzeugen.

Prinzipiell stelle ich mir solch eine Struktur vor:

Code:
TYPE
  myType: STRUCT
    myVar :ANY; // ich weiss ANY geht leider nicht in Strukt
  END_STRUCT;
END_TYPE
 
...
 
VAR
  aStruct : STRUCT
    iInt1 : INT;
    iInt2 : INT;
  END_STRUCT;
  
  bStuct: STRUCT
    iInt1 : INT;
  END_STRUCT;
 
  variable : myType;
 
END_VAR
 
 
...
 
if ... THEN
  variable.myVar := aStruct
ELSE
  variable.myVar := bStruct
END_ELSE;


Geht sowas? Oder hat jemand eine Idee wie man sowas in der Art realisieren kann?

Grüsse
Jens
 
Zuletzt bearbeitet:
Hallo Jens,
SCL kann nur mit Strukturen arbeiten, die dem Compiler zum Zeitpunkt der Compilierung bekannt sind. Dynamisch oder Variabel im Sinne deiner Vorgabe geht so ohne Weiteres also nicht ...

Was willst du denn konkret machen ? Vielleicht gibt es ja trotzdem eine Alternative ...

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
also ich möchte konkret eine UDP-Kommunikation zwischen einer
Dezentrale Peripherie ET 200S Interfacemodul IM151-8 PN/DP CPU
und einer WinAC bewerkstelligen.

Der Datenteil kann abhängig einer ID im Header verschieden aufgebaut sein. Es sind 17 verschiedene Typen möglich.

Ich dachte mir, ich bilde die einzelnen Strukturen nach und je nach ID im Header packe ich den passenden UDT mit in ein Struct (Datenbaustein), den ich dann per TUSend verschicke. Alternativ kann ich auch einfach alle Möglichkeiten abbilden, einfügen und nur den relevanten Teil mit Daten füllen, danach wegschicken / lesen. Also sowas wie:
Code:
type 
  packet : STRUCT
 
    headerVar1: INT;
    headerPacketType : INT;
    headerDataLenght : INT;
 
    data : STRUCT
      intData : INT;
      sData : String;
      // je nach PacketType evtl. noch ein paar Variablen oder andere... 
    END_STRUCT;
 
-------- bis hier wäre schön -------------
    data2 : STRUCT
      shortData : SHORT;
      wData : WORD;
      // je nach PacketType evtl. noch ein paar Variablen oder andere... 
    END_STRUCT;
....
 
    data17 : STRUCT
      intData : INT;
      dwData : DWORD;
      // je nach PacketType evtl. noch ein paar Variablen oder andere... 
    END_STRUCT;
 
-------- wäre halt die unschöne Lösung --------
 
  END_STRUCT;
END_TYPE;


Aber da ich aus der Informatik-Ecke komme wiederstrebt mir noch solch eine Lösung :)

Grüsse
Jens
 
Zuletzt bearbeitet:
Ich habe mich versucht. Aber keine ahnung ob es geht. Es kompiliert aber ist nicht getestet.

Das trick ist mit AT dieselbe Speicheraddressen mit verschiedene Strukturen anzusprechen.

Code:
TYPE DefaultStructure
    STRUCT
    byteArray : ARRAY[0..99] OF BYTE ; // Platz reservieren so das es ausreicht für jeden Fall!
    END_STRUCT 
END_TYPE
 
TYPE Specifictype1
    STRUCT
    bi1, bi2 : BOOL ;
    r1 : REAL ;
    END_STRUCT 
END_TYPE
 
TYPE Specifictype2
    STRUCT
    bi1, bi2, bi3, bi4 : BOOL ;
    r1, r2, r3 : REAL ;
    END_STRUCT 
END_TYPE
 
FUNCTION FC20 : VOID
VAR_INPUT
    inData : DefaultStructure ;
    inType1 AT inData : SpecificType1 ;
    inType2 AT inData : SpecificType2 ;
    inDataTyp : INT ;
END_VAR
VAR_output
   outData : DefaultStructure ;
   outType1 AT outData : SpecificType1 ;
   outType2 AT outData : SpecificType2 ;
END_VAR
 
BEGIN
 
IF inDataTyp = 1 THEN 
  OutType1.bi1 := TRUE ;
  OutType1.r1 := 12.34 ;
  OutType1.bi2 := InType1.bi2 ;
END_IF ;
 
IF inDataTyp = 2 THEN 
  OutType2.bi4 := TRUE ;
  OutType2.r3 := 34.56 ;
  OutType2.bi1 := InType2.bi1 ;
END_IF ;

 
END_FUNCTION

geändert: Jetzt passiert etwas verschieden wenn inDataTyp ist 1 oder 2 !
 
Zuletzt bearbeitet:
Guten Morgen allerseits!
Danke schon mal für Eure Hilfe! Gestern hatte ich keine Lust mehr, aber nun, mit einem frischen Café mache ich mich sofort ans Werk und teste... Ich werde auf jdene Fall von meinen Ergebnissen berichten.

Grüsse
Jens
 
@Jesper:
Das finde ich interessant ... allerdings nach mienem Verständnis kannst du doch jetzt an "inData" als Struktur nur Daten von Typ "DefaultStructure" übergeben ...!? Das der AT intern eine andere Interpretation zuläßt ist klar ... Aber wenn du an "inData" z.B. Daten vom Typ "Specifictype1" übergeben willst - was macht der Baustein dann aussen ? Ich kann das gerade nicht testen, aber m.E, läßt er das nicht zu - oder ?

Gruß
LL
 
@LL

Die Daten das man an den Baustein versorgt als Quelle, kann nur "DefaultStructure" haben.
Alles was man flexibel machen will kann nur innerhalb von den SCL Baustein passieren.

Es gibt weitere Möglicheiten.
Man kann Quellen DBs direkt zugreifen innerhalb von SCL den code.
Z.b: myData.InData1 ist ein SpecificType1, und myData.InData2 ist ein SpecificType2.
Dann kan man so schreiben:
TYPE DefaultStructure
STRUCT
byteArray : ARRAY[0..99] OF BYTE ;
END_STRUCT
END_TYPE

TYPE Specifictype1
STRUCT
bi1, bi2 : BOOL ;
r1 : REAL ;
END_STRUCT
END_TYPE

TYPE Specifictype2
STRUCT
bi1, bi2, bi3, bi4 : BOOL ;
r1, r2, r3 : REAL ;
END_STRUCT
END_TYPE

DATA_BLOCK MyData
STRUCT
DataType1 : SpecificType1 ;
DataType2 : SpecificType2 ;
END_STRUCT
BEGIN
END_DATA_BLOCK

FUNCTION FC20 : VOID

VAR_INPUT
inDataTyp : INT ;
END_VAR

VAR_output
outData : DefaultStructure ;
outType1 AT outData : SpecificType1 ;
outType2 AT outData : SpecificType2 ;
END_VAR

BEGIN

IF inDataTyp = 1 THEN
outType1 := myData.DataType1 ; // Direkten Zugriff auf DB Daten.
END_IF ;

IF inDataTyp = 2 THEN
outType2 := myData.DataType2 ; // Direkten Zugriff auf DB Daten.
END_IF ;

END_FUNCTION

edit: Kompiliert aber nicht getestet !
 
Zurück
Oben