Beispiel 1: ADSREAD-Indication/-Response
In der Beispielapplikation werden von einer VB-Applikation READ-Requests an die SPS-Task eines BC9000 gesendet um eine SPS-Zählervariable zu inkrementieren/dekrementieren oder zurückzusetzen. Die READ-Requests werden bei dem Buscontroller als Indications abgefangen und die gewünschte Operation an der Zählervariable ausgeführt. Danach wird von dem Buscontroller ein Response mit dem aktuellen Wert der Zählervariable an die VB-Applikation zurück gesendet. Der Wert der Zählervariable wird auf der Form ausgegeben. Um mit der SPS-Task zu kommunizieren 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 BC9000 aufgebaut. Der gewünschte Dienst in der SPS-Task wird in dem Index-Group-Parameter verschlüsselt:
- IG:0x80000001 -> Die Zählervariable inkrementieren;
- IG:0x80000002 -> Die Zählervariable dekrementieren;
- IG:0x80000003 -> Die Zählervariable = 0 setzen;
- IO: 0x0
![]() | 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, ob er die SPS-Variable inkrementieren/dekrementieren oder zurücksetzen soll. |
Option Explicit
Dim tmpData(1) As Integer
Dim AdsResult As Integer
Private Sub Command1_Click()
AdsResult = AdsOcx1.AdsSyncReadReq(&H80000001, &H0, 2, tmpData)
Label1.Caption = "Ads result:" & AdsResult & " PLC data:" & tmpData(0)
End Sub
Private Sub Command2_Click()
AdsResult = AdsOcx1.AdsSyncReadReq(&H80000002, &H0, 2, tmpData)
Label1.Caption = "Ads result:" & AdsResult & " PLC data:" & tmpData(0)
End Sub
Private Sub Command3_Click()
AdsResult = AdsOcx1.AdsSyncReadReq(&H80000003, &H0, 2, tmpData)
Label1.Caption = "Ads result:" & AdsResult & " PLC data:" & tmpData(0)
End Sub
Private Sub Form_Load()
AdsOcx1.AdsAmsServerNetId = "172.16.17.63.1.1"
AdsOcx1.AdsAmsServerPort = 800 'PLC task number'
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.
Die Requests werden in der SPS-Task von einer Instanz des ADSREADIND-Funktionsbausteins als Indications abgefangen. Danach werden die Parameter Index-Group, Index-Offset und die angeforderte Datenlänge auf Gültigkeit überprüft. In der CASE-Anweisung wird die gewünschte Operation an der SPS-Variablen durchgeführt. Beim Erfolg wird ein Response von einer Instanz des ADSREADRESBC-Funktionsbausteins an den Aufrufer mit dem aktuellen Wert der SPS-Variablen zurückgesendet. Im Fehlerfall eine entsprechende Fehlermeldung. Zum Schluss werden die Flags CLEAR und RESPOND rückgesetzt um weitere Indications verarbeiten zu können.
PROGRAM MAIN
VAR
fbREADIND : ADSREADIND;
fbREADRESBC : ADSREADRESBC;
szNetId : STRING(23);
Port : UINT;
InvokeId : UDINT;
idxGrp : UDINT;
idxOffs : UDINT;
cbLength : UDINT;
ErrorNumber : UDINT;
varCounter : INT;
END_VAR
fbREADIND( );
fbREADRESBC( );
IF ( fbREADIND.VALID ) THEN
szNetId := fbREADIND.NETID;
Port := fbREADIND.PORT;
InvokeId := fbREADIND.INVOKEID;
idxGrp := fbREADIND.IDXGRP;
idxOffs := fbREADIND.IDXOFFS;
cbLength := fbREADIND.LENGTH;
fbREADIND( CLEAR := TRUE ); (*clear indication entry*)
ErrorNumber := 0;
IF idxOffs = 0 THEN
IF cbLength >= 2 THEN
CASE idxGrp OF
16#80000001:
varCounter := varCounter + 1;
16#80000002:
varCounter := varCounter - 1;
16#80000003:
varCounter := 0;
ELSE
ErrorNumber := 1793; (* ADS error: Service is not supported by server*)
END_CASE
ELSE
ErrorNumber := 1797; (*ADS error:Parameter size not correct*)
END_IF
ELSE
ErrorNumber := 1795; (*ADS error: Invalid index offset*)
END_IF
fbREADRESBC.NETID := szNetId;
fbREADRESBC.PORT := Port;
fbREADRESBC.INVOKEID := InvokeId;
fbREADRESBC.RESULT := ErrorNumber;
IF ErrorNumber = 0 THEN
fbREADRESBC( LEN := SIZEOF(varCounter),DATAADDR := ADR(varCounter), RESPOND := TRUE );
ELSE
fbREADRESBC( LEN := 0,DATAADDR :=0, RESPOND := TRUE );
END_IF
END_IF
(*reset fb's*)
IF NOT fbREADRESBC.BUSY THEN
fbREADIND( CLEAR := FALSE );
fbREADRESBC( RESPOND := FALSE );
END_IF
Hier können Sie die kompletten Sourcen zu der Beispielapplikation entpacken: Beispielapplikation mit den erweiterten ADS-Funktionsbausteinen