Array ohne Pointer übergeben? (SCL)

tahren

Level-1
Beiträge
28
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich bin gerade dabei mich mit SCL zu beschäftigen. Ich habe mir nun in SCL einen kleinen Funktionsbaustein erstellt, mit u.a. einem Array als Eingangsparameter. Dieses Array möchte ich beim Aufruf des FB´s gerne mit Werten aus einem Datenbaustein füllen. Das funktioniert auch alles einwandfrei bisher, indem ich es beim Aufruf über Pointer mache.

CALL FB 1 , DB 1
feld:=meinDB.meinFeld // P#DB2.DBX0.0
in1 :=...
in2 :=...
out1:=...
out2:=...

Ich möchte mich bei der späteren Programmierung meiner Bausteine an die Norm IEC 61131-3 halten. Die besagt, dass es dort keine Pointer gibt. Aus diesem Grund würde ich gerne wissen, ob es irgendwie möglich ist, ein Array beim Aufruf ohne Pointer mit Werten vorzubelegen.

Vielen Dank schonmal im Voraus für die Infos!!

Gruß
tahren
 
Aus diesem Grund würde ich gerne wissen, ob es irgendwie möglich ist, ein Array beim Aufruf ohne Pointer mit Werten vorzubelegen.
Sollen die Werten "vorbelegt" sein beim erzeugen, also die Initial-werten ?
In den Fall, hier ist ein Beispiel:
Code:
DATA_BLOCK AI
    STRUCT
        iInpRAW :           ARRAY[1..32] OF INT ;
        iInpMIN :           ARRAY[1..32] OF INT ;
        iInpMAX :           ARRAY[1..32] OF INT ;
        iInploAlarmLevl :   ARRAY[1..32] OF INT := 32 (2500) ; // 2500 matches 2.5mA for 0-20mA channels
        iFilter :           ARRAY[1..32] OF INT ;
        iDecimal :          ARRAY[1..32] OF INT ;
        iScaled :           ARRAY[1..32] OF INT ;
        rScaleMin :         ARRAY[1..32] OF REAL ;
        rScaleMax :         ARRAY[1..32] OF REAL ;
        rScaled :           ARRAY[1..32] OF REAL ;
        boEnable :          ARRAY[1..32] OF BOOL := 32 (FALSE)  ;
        boLoAlarmsign :     ARRAY[1..32] OF BOOL := 32 (FALSE)  ;
    END_STRUCT
BEGIN
 
// update the below initial values for each project.
 
//channel 1 
iInpMIN[1] := 5530 ; 
iInpMAX[1] := 27648 ; 
iFilter[1] := 2 ; 
iDecimal[1] := 0 ;
iInploAlarmLevl[1] := 2500 ;
rScaleMin[1] := 0.0 ;
rScaleMax[1] := 100.0 ; //
 
//channel 2 
iInpMIN[2] := 5530 ; 
iInpMAX[2] := 27648 ; 
iFilter[2] := 2 ; 
iDecimal[2] := 0 ;
iInploAlarmLevl[2] := 2500 ;
rScaleMin[2] := 0.0 ;
rScaleMax[2] := 100.0 ; 
 
// usw...
 
END_DATA_BLOCK

Oder sollen die Werten dynamisch belegt sein ?
Du kannst zum jeden zeitpunkt einzelne array addressen zugreifen.
Z.B.:

Code:
// STL
L 10
T "AI.iFilter[2]
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Bin nicht 100% sicher was Du meinst, aber wenn Du Array-daten zwisschen DB's übertagen willst, dann definierts Du einfach die gleiche Adressen Strukturen, und übertrage von einer nach der andere wie so:

IntenData.myArray := "ExternDB".myArray ;

IntenData.myArray und "ExternDB".myArray sind dann beide z.B. ARRAY[1..10] OF INT.

Du kannst auch Arrays als Eingansparameter und Ausgangsparameter anlegen.
Wenn es in ein FC programmiert ist, dann werden die daten in werklicheit als Pointer übertragen. Ich glaube das es funktioniert auch bei IEC. Nur hat man bei IEC nicht die Pointer in der Art von Siemens (L D[AR1,P#6.0] usw.)
 
Vielleicht beschreibe ich das nochmal etwas detaillierter:
Ich möchte einen Neuentwurf aller S7- Bausteine machen, die zu einem Identifikationssystem gehören. Hierbei werden des Öfteren große Datenblöcke in einen bzw. mehrere Datenbausteine geschrieben/gelesen. Die bisherige Version arbeitet dabei mit ANY Pointern, womit es ja bekanntlich leicht realisiert werden kann. Ich möchte nun aber unter Einhaltung der IEC einen Neuentwurf dieser Bausteine realisieren. Tatsache ist, dass ich leider keinen ANY-Pointer verwenden darf dabei. Somit habe ich mir gedacht, dass ich auf den Datenbaustein über Indizes zugreife kann. Deswegen habe ich mich auch für die SCL- Programmierung entschieden, da man hier auf ein Array über Indizees zugreifen kann.
Nun muss ich nur noch dafür sorgen, dass meine existierenden Datenbausteine beim Aufruf eines Bausteins in die deklarierten Arrays transferiert werden, so dass ich hieraus dann über eine FOR- Schleife die Indizees hochzählen lasse (also ohne ANY-Pointer) und somit zusammenhängende große Datenblöcke auslesen bzw. in den Datenbaustein schreiben kann.
 
Hallo,
wenn du einem Baustein in Step7 einen Datentyp größer DWORD (also Strukturen, Strings oder Arrays) übergeben willst, so geschieht dies IMMER über einen Pointer. Das ist auch unabhängig von der gewählten Sprach-Syntax. Innerhalb von SCL solltest du es dir verkneifen, etwas mit Pointern machen zu wollen. Willst du deinem Baustein Daten übergeben oder von ihm übernehmen dann bist du auf jeden Fall wieder in der Step7-Welt - außer du arbeitest komplett in SCL - dann sollten aber immer allen Bausteinen alle Typen bekannt sein und du solltest nicht mit absoluten Adressen arbeiten.

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hier eine kleine Beispiel wie man Daten mittels Index manipulieren kann.
Code:
(* Sample data structure *)
TYPE "UDT_data"
    STRUCT
        iIdent : INT := 0 ;
        iEANtype : DINT := L#1 ;
        iName : STRING[16] := 'undefined' ;
    END_STRUCT
END_TYPE

(* Sample DB created via UDT *)
DATA_BLOCK "List"
    STRUCT
        data : ARRAY[0..99] OF "UDT_data" ;
    END_STRUCT
BEGIN
 
    data[0].iIdent := 22 ;
    data[0].iEANType := L#678933443 ;
    data[0].iName := '22 mm nut' ;
 
    data[1].iIdent := 23 ;
    data[1].iEANType := L#12341454 ;
    data[1].iName := '22 mm bolt' ;
 
END_DATA_BLOCK

(* Sample access to DB via index *)
FUNCTION "FC_load_data" : VOID
 
VAR_INPUT
    inData : "UDT_data" ;
    iNo : INT ;
END_VAR
 
IF iNo >= 0 AND iNo <=99 THEN
    "List".data[iNo] := inData ;
END_IF ;
 
END_FUNCTION
 
Hallo,
wenn du einem Baustein in Step7 einen Datentyp größer DWORD (also Strukturen, Strings oder Arrays) übergeben willst, so geschieht dies IMMER über einen Pointer.

Danke für Eure Hilfestellungen! Werde den Aufruf dann wohl zwangsläufig über einen Pointer machen, so wie ich es vorher schon mal gemacht hatte.
Nun habe ich allerdings noch eine Frage zu Arrays in SCL.

Wenn ich ein Array als IN/OUT- Parameter deklariere und den Baustein dann aufrufe...wie kann ich das dann übergebene Array an einen weiteren Funktionsbaustein übergeben?

grobes Beispiel:

Aufruf im OB1:

call FB x,DB x
IN/OUT := meinDB.meinArray


---(FB x)----------------------------------------------
|VAR_IN_OUT
| Daten_x : ARRAY[0...9] OF BYTE
|END_VAR
|
|call FB y, DB y
|IN/OUT := Daten_x // PARAMETRIERUNGSFEHLER
|
|
| ---(FB y)---------------------------------------
| |VAR_IN_OUT
| |Daten_y : ARRAY[0...9] OF BYTE
| |END_VAR
| |
| |
| -----------------------------------------------
|
------------------------------------------------------

Wenn ich die Bausteinaufrufe im FB x so mache, wie in dem Beispiel beschrieben, dann kommt die Fehlermeldung, dass ich dort einen Parametrierungsfehler habe (siehe oben). Sobald ich das Array im FB x als IN- Parameter deklariere, dann läuft das. Kann mir jemand sagen, wie das auch mit IN/OUT- Deklaration zum Laufen bringe?

mit freundlichen Grüßen
tahren
 
Hallo,
du kannst einen Pointer NICHT durchreichen.
Hast du etwas in der Art vor, so müßtest du die Daten des ersten Bausteins in diesem selbst noch einmal abbilden und diese abgebildeten dann weiterreichen.

Gruß
LL
 
AWL oder SCL ?

In SCL müßtest du dir einfach eine Variable gleichen Typs anlegen und den Eingang darauf zuweisen :
Code:
VAR_IN_OUT
  Daten_x : ARRAY[0...9] OF BYTE
END_VAR

VAR
  myDaten_x : ARRAY[0...9] OF BYTE
END_VAR
 
und dann im Code :
 
myDaten_x := Daten_x ;
in AWL würdest du das entweder mit dem Blockmove oder mit einer Schleife machen, wo du das Eine in das Andere überträgst.

Gruß
LL
 
Zurück
Oben