Übertragen von Strukturen an die SPS

Aufgabe

Von Visual Basic soll eine Struktur in die SPS geschrieben werden. Die Elemente der Struktur haben verschiedene Datentypen.

Beschreibung

Damit die CPU unter Windows NT/2000 schneller auf Variablen zugreifen kann, werden diese von Visual Basic (und auch von anderen Programmiersprachen) im Hauptspeicher nach bestimmten Richtlinien ausgerichtet. Dieses Ausrichten der Variablen wird Alignment (engl. Ausrichten) bezeichnet. Dadurch kann es vorkommen, dass innerhalb einer Struktur 'Speicherlücken' entstehen. Da Visual Basic und IEC1131-3 unterschiedliche Richtlinien für das Alignment besitzen, müssen diese durch Dummyvariablen aufgefüllt werden.
Leider lässt sich unter Visual Basic keine Allgemeinregel für das Alignment definieren. Es besteht aber die Möglichkeit mit zwei Visual Basic Funktionen die Speicherbelegung einer Struktur zu analysieren. Es sind die Funktionen VarPtr() und LenB().
VarPtr() gibt die Adresse einer Variablen zurück, LenB() die Länge in Byte, die eine Variable (oder eine ganze Struktur) belegt. Das untere Beispiel zeigt den Speicheraufbau der Struktur in einer Form an. Anhand dieser Informationen kann ermittelt werden, welche 'Speicherlücken' die Struktur besitzt. In dem Beipielprogramm werden diese durch die Variablen VarDummyX aufgefüllt.
Achtung: Die Funktion VarPtr() steht erst ab Visual Basic 5 zur Verfügung.

In der folgenden Skizze wird die Speicheraufteilung nochmals grafisch dargestellt:

Ein Rechteck bedeutet, dass die Variable an dieser Stelle ein Byte belegt. Ein Kreuz stellt an dieser Stelle ein Byte da, welches von keiner Variablen belegt wird. Die Kreuze wurden in dem Beispielprogramm durch Dummyvariablen aufgefüllt.

Strukturdeklaration in Visual Basic

Type VBStruct
    VarInteger   As Integer
    VarDummy1    As Integer
    VarLong      As Long
    VarByte      As Byte
    VarDummy2    As Byte
    VarDummy3    As Byte
    VarDummy4    As Byte
    VarDouble    As Double
    VarSingle    As Single
End Type

Strukturdeklaration in der SPS

Nachdem die Struktur im Visual Basic-Programm dem Alignment angepasst wurde, muss die Struktur im SPS-Programm ebenfalls ergänzt werden:

TYPE PLCStruct
STRUCT 
    PLCVarInteger : INT;
    PLCVarDummy1  : INT;
    PLCVarLong    : DINT;
    PLCVarByte    : SINT;
    PLCVarDummy2  : SINT;
    PLCVarDummy3  : SINT;
    PLCVarDummy4  : SINT;
    PLCVarDouble  : LREAL;
    PLCVarSingle  : REAL;
END_STRUCT
END_TYPE

Visual Basic 6 Programm

Dim hVar As Long
Dim VBVar As VBStruct

'--- wird beim Starten aufgerufen ---
Private Sub Form_Load()
      '--- Exception freigeben --- AdsOcx1.EnableErrorHandling = True
     Call AdsOcx1.AdsCreateVarHandle("Main.PLCVar", hVar)
      '--- Adressen der Variablen anzeigen ---
     lblInteger.Caption = VarPtr(VBVar.VarInteger)
    lblLong.Caption = VarPtr(VBVar.VarLong)
    lblByte.Caption = VarPtr(VBVar.VarByte)
    lblDouble.Caption = VarPtr(VBVar.VarDouble)
    lblSingle.Caption = VarPtr(VBVar.VarSingle)
      '--- Länge der Struktur anzeigen ---
     lblVarLength.Caption = LenB(VBVar)
End Sub

'--- wird beim Beenden aufgerufen ---
Private Sub Form_Unload(Cancel As Integer)
    Call AdsOcx1.AdsDeleteVarHandle(hVar)
End Sub

'--- wird vom Bediener aufgerufen ---
Private Sub cmd_write_Click()
    Dim intIndex As Integer
      '--- Struktur auffüllen ---
     VBVar.VarInteger = CInt(txtInteger.Text)
    VBVar.VarLong = CLng(txtLong.Text)
    VBVar.VarByte = CByte(txtByte.Text)
    VBVar.VarDouble = CDbl(txtDouble.Text)
    VBVar.VarSingle = CSng(txtSingle.Text)
      '--- Struktur in SPS schreiben ---
     Call AdsOcx1.AdsSyncWriteIntegerVarReq(hVar, LenB(VBVar), VBVar.VarInteger)
End Sub

SPS-Programm

PROGRAM MAIN
VAR 
    PLCVar : PLCStruct;
END_VAR

 

Optimierungen

Durch eine geschickte Anordnung der VBStruct-Membervariablen in der VB-Applikation kann das hinzufügen der Dummy-Bytes vermieden werden. Folgende Regel muss dabei beachtet werden:

Optimierte Strukturdeklaration in Visual Basic

Type VBStruct
    VarDouble As Double     ' 8 bytes
 VarSingle As Single     '+4 bytes
    VarLong As Long     '+4 byte
    VarInteger As Integer   '+2 bytes
    VarByte As Byte     '+1 byte       '+1 hidden padding byte in memory
                '=20 bytes (LenB result)
End Type

Optimierte Strukturdeklaration in der SPS

TYPE PLCStruct
STRUCT
    PLCVarDouble : LREAL;
    PLCVarSingle : REAL;
    PLCVarLong : DINT;
    PLCVarInteger : INT;
    PLCVarByte : SINT;
END_STRUCT
END_TYPE

Unsere optimierte VB Struktur beginnt jetzt mit einem Double, entsprechend muss das VB-Programm geändert werden:

'--- wird vom Bediener aufgerufen ---
Private Sub cmd_write_Click()
...
    '--- Struktur in SPS schreiben ---
 call AdsOcx1.AdsSyncWriteDoubleVarReq(hVar, Len(VBVar), VBVar.VarDouble)
End Sub

Neben dem geänderten Methodennamen muss die zu schreibende Datenlänge mit der Len-Funktion und nicht mit LenB ermittelt werden. Wenn Sie LenB benutzen, werden die Daten nicht in die SPS geschrieben. Die Ursache liegt darin, daß LenB eine Länge = 20 Bytes zurückliefert (inklusive eines padding bytes im VB Speicher), unsere Struktur in der SPS aber nur 19 Bytes lang ist.

Len vs. LenB

 

Sprache / IDE

Beispielprogramm auspacken

Visual Basic 6

ADS-OCX Sample02.exe