Example 1: ADSREAD Indication/Response

In the sample application, READ requests are sent from a VB application to the PLC task of a BC9000, in order to increment/decrement or reset a PLC counter variable. The READ requests are intercepted as indications at the bus controller, and the desired operation is executed at the counter variable. The bus controller then sends a response with the current value of the counter variable back to the VB application. The value of the counter variable is output on the form. In order to communicate with the PLC task the VB application uses the ActiveX control: AdsOcx. The bus controller must be entered as a remote PC in the TwinCAT system menu in order to be able to route the requests of the VB application to the bus controller via the Ethernet. Here you can unpack the complete sources relating to the sample application.

Entering BC9000 as remote PC in the TwinCAT system menu

Example 1: ADSREAD Indication/Response 1:

The TwinCAT system menu can be accessed by clicking the TwinCAT icon->properties in the taskbar. Select Add in the AMS Router tab. Enter an arbitrary name for the remote PC in the dialog. The network address is entered in AMS Net Id. It consists of the IP address of the BC9000 and two further digits: "1.1". The IP address of the BC9000 is entered again in Address. The IP address must correspond to the address that was set via the dip switches on the bus controller.

The VB application

Example 1: ADSREAD Indication/Response 2:

 

A connection to the PLC task of the BC9000 is established in the Form_Load routine. The required service in the PLC task is encoded in the index group parameter:

Example 1: ADSREAD Indication/Response 3:

So that the requests can be routed to the PLC task, the most significant bit must be set in the index group parameter. The values of the index group and index offset parameters can be freely defined. In our example, the bus controller detects whether the PLC variable is to be incremented/decremented or reset via the index group and index offset parameters.

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

The PLC program

Create a new PLC project for the bus controller. The following PLC libraries for the bus controller must be integrated under library management: Standard.lb6, PlcHelperBC.lb6 and TcAdsBC.lb6. 

The requests are intercepted as indications in the PLC task by an instance of the ADSREADIND function block. Afterwards the index group and index offset parameters and the required data length and validity are checked. In the CASE instruction the desired operation with the PLC variables is carried out. If successful a response is sent back by an instance of the ADSREADRESBC function block to the caller with the current value of the PLC variables. In the case of an error an appropriate error message. At the end the CLEAR and RESPOND flags are reset in order to be able to process further indications.

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

Here you can unpack the complete sources for the sample application: sample application with the extended ADS function blocks