Ü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:
- Ordnen Sie die Membervariablen in der VB-Struktur nach der belegten Speichergröße: Zuerst die größten und zum Schluss die kleinsten Datentypen.
- Die letzten Bytes können (müssen aber nicht) auf volle 4 Bytes aufgefüllt 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
- With user-defined types, Len returns the size as it will be written to the file.
- With user-defined types, LenB returns the in-memory size, including any padding between elements.
Sprache / IDE | Beispielprogramm auspacken |
---|---|
Visual Basic 6 |