Ereignisgesteuertes Lesen (mit Konvertierung in einen anderen Typ)
Ab TwinCAT 2.8 Build > 743 und höher
Aufgabe
In der SPS befinden sich 4 Variablen vom unterschiedlichen Typ. Die Variablen sollen auf möglichst effektive Weise ausgelesen und die Werte auf einer Visual Basic Form dargestellt werden. Mit einer Checkbox kann zwischen zwei Verbindungsmodi (ADSTRANS_SERVERCYCLE oder ADSTRANS_SERVERONCHA) umgeschaltet werden. Mit zwei Buttons kann die Verbindung zu den SPS-Variablen aufgebaut oder abgebaut werden.
Bei den SPS-Variablen handelt es sich um strukturierte Datentypen. Diese werden z. B. von der SPS als ein Datenblock an den AdsOcx-Client gesendet. Das AdsOcx kann aber an die VB-Ereignisroutine nur Variablen vom bestimmten Datentyp als Parameter übergeben, darunter den Variant-Typ. Mit der Methode AdsReadVarConvertConnect kann der Typ der Variant-Variablen in der VB-Ereignisroutine vom Benutzer vorher festgelegt werden. Die Ereignisdaten werden dann vom AdsOcx in die Variant-Variable kopiert und so an die VB-Ereignisroutine übergeben. Ein Variant-Array kann auch eine komplexe Struktur in der SPS abbilden. Wieviele Daten in die einzelnen Variant-Elemente kopiert werden, wird durch den Typ der einzelnen Elemente festgelegt. Einige Ausnahmen z. B. bei Strings (die Stringlänge muss vorher entsprechend gesetzt werden) und boolschen Variablen (aus 1 Byte Daten wird ein 2 Byte VB-Boolean ) sind dabei zu beachten.
Folgende SPS-Variablen sollen auf der Form angezeigt werden:
- Der Wert eines Aufzählungstyps (Enum) soll in eine Long-Variable eingelesen und im Label angezeigt werden.
- Der Wert eines Strukturierten-Datentyps (Struktur mit 4-Booleans) soll in eine Long-Variable eingelesen und in einer CheckBox dargestellt werden. Die CheckBox soll ausgewählt werden, wenn eine der boolschen Variablen in der SPS den Wert TRUE besitzt.
- Der Wert eines Stringarrays soll in einer ListBox angezeigt werden.
- Der Wert eines Strukturierten-Datentyps soll in ein Variantarray eingelesen und in einer weiteren ListBox angezeigt werden.
Die SPS-Applikation
VAR_GLOBAL
eColors : E_Colors := cWhite;
st4Switches : ST_4Switches;
arr3Strings : ARRAY[1..3] OF STRING :=1('First'), 1('Second'),1('Third');
stBigStruct : ST_BigStruct;
END_VAR
Online-Ansicht der SPS-Daten:
die Definition des Aufzählungstyps:
TYPE E_Colors :
(
cUnknown,
cWhite := 1,
cBlue := 2,
cRed := 3,
cBlack
);
END_TYPE
Die Definition der Struktur mit 4 boolschen Variablen:
TYPE ST_4Switches :
STRUCT
bLevel1 : BOOL;
bLevel2 : BOOL;
bLevel3 : BOOL;
bLevel4 : BOOL;
END_STRUCT
END_TYPE
Die Definition des Strukturierten-Datentyps:
TYPE ST_BigStruct :
STRUCT
single : REAL;
long : DINT;
boolean : BOOL;
stSub1 : ST_Sub1;
counter : DINT;
datetime : DT := DT#2003-01-20-15:12:44;
END_STRUCT
END_TYPE
Dieser besitzt wiederum 2 Unterstrukturen:
TYPE ST_Sub1 :
STRUCT
bFirst : BOOL;
bSecond : BOOL;
bThird : BOOL;
stSub2 : ST_Sub2;
END_STRUCT
END_TYPE
TYPE ST_Sub2 :
STRUCT
integer : INT;
double : LREAL;
string20 : STRING(20) := 'Unknown';
END_STRUCT
END_TYPE
Visual Basic 6 Programm
Option Explicit
Dim adsErr As Long
Dim hConnect_EnumVar As Long
Dim hConnect_4Switches As Long
Dim hConnect_StringArray As Long
Dim hConnect_BigStruct As Long
Beim Laden der Form wird eine Verbindung zum ersten SPS-Laufzeitsystem aufgebaut:
Private Sub Form_Load()
AdsOcx1.AdsAmsServerNetId = AdsOcx1.AdsAmsClientNetId
AdsOcx1.AdsAmsServerPort = 801
AdsOcx1.EnableErrorHandling = True
End Sub
Bei einem Mausklick auf den AdsReadVarConvertConnect - Button wird eine Verbindung zu den SPS-Variablen aufgebaut. Beim Erfolg liefert die Methode AdsReadVarConvertConnectein Handle zurück. Nur über dieses Handle wird die Verbindung identifiziert und kann später abgebaut werden.
1. Der Aufzählungstyp in der SPS belegt nur 2 Byte Speicher. Diese 2 Byte werden in eine Long-Variable (4 Byte) eingelesen und in der Ereignisfunktion zurückgeliefert. Man könnte aber genauso gut den VB Integer-Datentyp verwenden.
2. Die 4 boolschen Werte der Strukturvariablen belegen in der SPS 4 einzelne Bytes SPS-Speicher. Diese werden in eine Long-Variable eingelesen und in der Ereignisfunktion als eine Long-Variable zurückgeliefert.
3. Die Strings in dem Array belegen in der SPS insgesamt 243 Byte Speicher (Definierte Stringlänge + 1 Byte für die Nullterminierung) *3. Die Länge der einzelnen VB-Strings muss der Länge der SPS-Strings entsprechen, um die einzelnen Strings trennen zu können. Besitzt der String die Länge Null, werden keine Ereignisdaten in eine Stringvariable hineinkopiert.
4. Die Strukturvariable kann in ein eindimensionales Variant-Array eingelesen werden. Die einzelnen Arrayelemente können vom unterschiedlichen Typ sein. Vor dem Aufbau der Verbindung müssen aber die einzelnen Arrayelemente mit entsprechendem Typ initialisiert werden.
Private Sub cmdConnect_Click()
Dim adsTransMode As ADSOCXTRANSMODE
adsTransMode = IIf(chkTransMode.Value = vbChecked, ADSTRANS_SERVERCYCLE, ADSTRANS_SERVERONCHA)
'Connects to enum var
Dim convertedEnumVar As Long
adsErr = AdsOcx1.AdsReadVarConvertConnect(".eColors", adsTransMode, 300, hConnect_EnumVar, convertedEnumVar, lblEnum)
'Connects to struct with 4 boolean variables
Dim converted4Switches As Long
adsErr = AdsOcx1.AdsReadVarConvertConnect(".st4Switches", adsTransMode, 300, hConnect_4Switches, converted4Switches, chk4Switches)
'Connects to array of strings
Dim convertedStringArray(1 To 3) As String
Dim i As Integer
For i = LBound(convertedStringArray) To UBound(convertedStringArray)
convertedStringArray(i) = String(81, "#")
Next i
adsErr = AdsOcx1.AdsReadVarConvertConnect(".arr3Strings", adsTransMode, 300, hConnect_StringArray, convertedStringArray, lstStringArray)
'Connects to struct variable
Dim convertedBigStruct(1 To 11) As Variant
convertedBigStruct(1) = CSng(0) 'stBigStruct.single
convertedBigStruct(2) = CLng(0) 'stBigStruct.long
convertedBigStruct(3) = CBool(False) 'stBigStruct.boolean
convertedBigStruct(4) = CBool(False) 'stBigStruct.stSub1.bFirst
convertedBigStruct(5) = CBool(False) 'stBigStruct.stSub1.bSecond
convertedBigStruct(6) = CBool(False) 'stBigStruct.stSub1.bThird
convertedBigStruct(7) = CInt(0) 'stBigStruct.stSub1.stSub2.integer
convertedBigStruct(8) = CDbl(0) 'stBigStruct.stSub1.stSub2.double
convertedBigStruct(9) = CStr(String(21, "*"))'stBigStruct.stSub1.stSub2.string20
convertedBigStruct(10) = CLng(0) 'stBigStruct.counter
convertedBigStruct(11) = CDate(0) 'stBigStruct.datetime
adsErr = AdsOcx1.AdsReadVarConvertConnect(".stBigStruct", adsTransMode, 300, hConnect_BigStruct, convertedBigStruct, lstBigStruct)
cmdConnect.Enabled = False
cmdDisconnect.Enabled = True
End Sub
Bei einem Mausklick auf AdsDisconnectEx - Button werden die Verbindungen zu den SPS-Variablen getrennt:
Private Sub cmdDisconnect_Click()
adsErr = AdsOcx1.AdsDisconnectEx(hConnect_EnumVar)
adsErr = AdsOcx1.AdsDisconnectEx(hConnect_4Switches)
adsErr = AdsOcx1.AdsDisconnectEx(hConnect_StringArray)
adsErr = AdsOcx1.AdsDisconnectEx(hConnect_BigStruct)
cmdConnect.Enabled = True
cmdDisconnect.Enabled = False
End Sub
Die Ereignisroutine AdsReadConvertConnectUpdate. Diese Ereignisroutine wird zyklisch (wenn ADSTRANS_SERVERCYCLE ausgewählt) oder immer nur dann aufgerufen, wenn sich der Wert der SPS-Variablen geändert hat (bei ADSTRANS_SERVERONCHA). Der hUser Parameter kann dafür benutzt werden, um die Ereignisdaten dem passenden Control (Label, CheckBox, ListBox ) zuordnen zu können.
Private Sub AdsOcx1_AdsReadConvertConnectUpdate(ByVal dateTime As Date, ByVal nMs As Long, ByVal hConnect As Long, data As Variant, Optional hUser As Variant)
Dim i As Integer
If TypeOf hUser Is CheckBox Then
chk4Switches.Value = IIf(data = 0, vbUnchecked, vbChecked)
chk4Switches.Caption = IIf(data = 0, "ALL disbled", "At least ONE enabled")
ElseIf TypeOf hUser Is ListBox Then
If hUser Is lstStringArray Then
Call lstStringArray.Clear
For i = LBound(data) To UBound(data)
Call lstStringArray.AddItem("Type: " & TypeName(data(i)) & " Value: " & data(i))
Next i
ElseIf hUser Is lstBigStruct Then
Call lstBigStruct.Clear
For i = LBound(data) To UBound(data)
Call lstBigStruct.AddItem("Type: " & TypeName(data(i)) & " Value: " & data(i))
Next i
End If
Else 'lblEnum
Dim objLabel As Label
Set objLabel = hUser
objLabel.Caption = "eColors: " & data
End If
End Sub
Sprache / IDE | Beispielprogramm auspacken |
---|---|
Visual Basic 6 |