Beispiel 2: ADSWRITE-Indication/-Response
Die VB-Applikation sendet ein Array mit 10 Integer-Werten zu der SPS-Task eines Buscontrollers BC9000. In der SPS-Task des Buscontrollers sollen die empfangenen Daten in eine Array-Variable zur weiteren Verarbeitung kopiert werden. Um mit dem Buscontroller kommunizieren zu können, benutzt die VB-Applikation das ActiveX Control: AdsOcx. Der Buscontroller muss als Remote-PC im TwinCAT-System-Menü eingetragen werden um die Anfragen der VB-Applikation zu dem Buscontroller übers Ethernet routen zu können. Hier können Sie die kompletten Sourcen zu der Beispielapplikation entpacken.
BC9000 als Remote-PC im TwinCAT System Menü eintragen
Das TwinCAT Systemmenü kann mit einem Mausklick auf das TwinCAT Icon -> Eigenschaften in der Taskleiste erreicht werden. Auf dem AMS Router-Reiter wählen Sie Add. In dem Dialog geben Sie einen beliebigen Namen für den Remote-PC ein. Unter AMS Net Id wird die Netzwerkadresse eingetragen. Diese setzt sich aus der IP-Adresse des BC9000 und zwei weiteren Stellen zusammen.:"1.1". Unter Address wird noch mal die IP-Adresse des BC9000 eingetragen. Die IP-Adresse muss der Adresse entsprechen, die mit den DIP-Schaltern auf dem Buscontroller eingestellt wurde.
Die VB-Applikation
In der Form_Load-Routine wird eine Verbindung zu der SPS-Task des Buscontrollers BC9000 aufgebaut ( Port 800 und Netzwerkadresse: "172.16.17.63.1.1" ). Die ersten vier Stellen der Netzwerkadresse entsprechen der IP-Adresse des Buscontrollers. Der gewünschte Dienst in der SPS-Task wird in dem Index-Group und Index-Offset Parameter verschlüsselt. Z.B.:
- IG:0x80000005 und
- IO:0x00000007-> Die gesendeten Daten in den Array in der SPS kopieren.
Die VB-Applikation benutzt die Methode AdsSyncWriteReq um 20 Byte Daten an den Buscontroller zu senden. Die zuletzt gesendeten Werte werden zur Kontrolle einer Liste hinzugefügt.
![]() | Damit die Requests an die SPS-Task weiter geleitet werden, muss in dem Index-Group-Parameter das höchstwertige Bit gesetzt werden. Die Werte der Index-Group und Index-Offset Parameter können frei definiert werden. In unserem Beispiel erkennt der Buscontroller anhand der Index-Group und Index-Offset-Parameter, dass er die empfangenen Daten in ein Array kopieren soll. |
Option Explicit
Dim AdsResult As Integer
Dim arrData(0 To 9) As Integer
Private Sub cmdWrite_Click()
Call List1.Clear
Dim i As Long
For i = LBound(arrData) To UBound(arrData)
arrData(i) = arrData(i) + 1 'change values
Call List1.AddItem("arrData(" & i & ") = " & arrData(i))
Next i
'calculate the byte length parameter
Dim cbWriteSize As Long
cbWriteSize = (UBound(arrData) - LBound(arrData) + 1) * LenB(arrData(LBound(arrData)))
AdsResult = AdsOcx1.AdsSyncWriteReq(&H80000005, &H7, cbWriteSize, arrData) 'send data to PLC
Label1.Caption = "Ads result: " & AdsResult
End Sub
Private Sub Form_Load()
AdsOcx1.AdsAmsServerNetId = "172.16.17.63.1.1"
AdsOcx1.AdsAmsServerPort = 800 'PLC task number of the BC9000 buscontroller'
Dim i As Long
For i = LBound(arrData) To UBound(arrData)
arrData(i) = i 'init data
Next i
End Sub
Das SPS Programm
Erstellen Sie ein neues SPS-Projekt für den Buscontroller. Unter Bibliotheksverwaltung müssen folgende SPS-Bibliotheken für den Buscontroller eingebunden werden: Standard.lb6, PlcHelperBC.lb6 und TcAdsBC.lb6.
In der SPS-Task des Buscontrollers wird eine Instanz von dem ADSWRITEIND-Funktionsbaustein benutzt um die Daten zu empfangen und eine Instanz von dem ADSWRITERESBC-Funkstionbaustein um den Empfang der Daten zu quittieren. Die Anfragen werden in der SPS-Task von dem ADSWRITEIND-Funktionsbaustein als sogenannte Indications abgefangen. Danach werden die Parameter Index-Group, Index-Offset und die gesendete Datenlänge auf Gültigkeit überprüft und die empfangenden Daten in eine Array-Variable kopiert. Als Nächstes wird ein Response von einer Instanz des ADSWRITERESBC-Funktionsbausteins an den Aufrufer (eventuell mit einem Fehlercode) zurückgesendet. Damit wird der VB-Applikation mitgeteilt, daß die gesendeten Daten erfolgreich empfangen wurden.
![]() | Mit der steigenden Flanke am CLEAR-Eingang des ADSWRITEIND-Funktionsbausteins wird der Adresspointer auf die zuletzt gesendeten Daten ungültig ( == NULL ). Aus diesem Grund werden die gesendeten Daten zuerst in die SPS-Variable kopiert und dann der CLEAR-Eingang auf TRUE gesetzt. Zum Schluss werden die Flags CLEAR und RESPOND rückgesetzt, um weitere Indications verarbeiten zu können. |
PROGRAM MAIN
VAR
fbWRITEIND : ADSWRITEIND;
fbWRITERESBC : ADSWRITERESBC;
szNetId : STRING(23);
Port : UINT;
InvokeId : UDINT;
idxGrp : UDINT;
idxOffs : UDINT;
cbLength : UDINT;
ErrorNumber : UDINT;
arrInt : ARRAY[0..9] OF INT;
END_VAR
fbWRITEIND( );
fbWRITERESBC( );
IF ( fbWRITEIND.VALID ) THEN
szNetId := fbWRITEIND.NETID;
Port := fbWRITEIND.PORT;
InvokeId := fbWRITEIND.INVOKEID;
idxGrp := fbWRITEIND.IDXGRP;
idxOffs := fbWRITEIND.IDXOFFS;
cbLength := fbWRITEIND.LENGTH;
ErrorNumber := 0;
CASE idxGrp OF
16#80000005:
CASE idxOffs OF
16#00000007:
IF cbLength <= SIZEOF( arrInt ) THEN
IF ( MEMCPY( ADR( arrInt ), fbWRITEIND.DATAADDR, UDINT_TO_INT(cbLength) ) = 0 ) THEN
ErrorNumber := 4000; (*MEMCPY fail*)
END_IF
ELSE
ErrorNumber := 1798; (* ADS error: invalid parameter value(s)*)
END_IF
ELSE
ErrorNumber := 1795; (*ADS error: Invalid index offset*)
END_CASE
ELSE
ErrorNumber := 1794; (*ADS error: invalid index group*)
END_CASE
fbWRITEIND( CLEAR := TRUE ); (*clear indication entry*)
fbWRITERESBC.NETID := szNetId;
fbWRITERESBC.PORT := Port;
fbWRITERESBC.INVOKEID := InvokeId;
fbWRITERESBC.RESULT := ErrorNumber;
fbWRITERESBC( RESPOND := TRUE ); (*send response*)
END_IF
(*reset fb's*)
IF NOT fbWRITERESBC.BUSY THEN
fbWRITEIND( CLEAR := FALSE );
fbWRITERESBC( RESPOND := FALSE );
END_IF
Hier können Sie die kompletten Sourcen zu der Beispielapplikation entpacken: Beispielapplikation mit den erweiterten ADS-Funktionsbausteinen