Forwarding parameter and configuration data to the PLC

To be able to transfer the parameter and configuration data to the PLC, these must be sent to the ADS server in the slave. The corresponding option is activated via TwinCAT.

Proceed as follows:

1. Select the PROFIBUS slave in the structure tree on the left,
2. Activate the SetPrm/ChkCfg handled by ADS Server... option.
Forwarding parameter and configuration data to the PLC 1:
3. Use port 851 for the first PLC task.
The data is now sent to the PLC via ADS indication. The data must be accepted and acknowledged in the PLC.

Accepting and acknowledging data in the PLC

First of all, you should check where the data comes from. The CX7031 supports up to 4 slaves, which are coded in the port number of the slave, namely the PROFIBUS address + 0x1000hex.

The telegram is coded in IdxOffset:

When starting the master, you will always receive two indications, both of which you must acknowledge with Result=0, otherwise an error will be sent to the corresponding PROFIBUS master and the connection will not be established.

Code sample:

VAR
   i               : INT;
   sNetId          : STRING;
   nPort           : UINT;
   udInvokeId      : UDINT;
   iCase           : INT;
   udGroup         : UDINT;
   udOffset        : UDINT;
   udLenght        : UDINT
   ptrByte         : POINTER TO BYTE; (* Datenpointer *)

   strPrmData2     : ARRAY[0..127] OF BYTE;
   strCfgData2     : ARRAY[0..127] OF BYTE;
   strPrmData3     : ARRAY[0..127] OF BYTE;
   strCfgData3     : ARRAY[0..127] OF BYTE;
   fbAdsWriteInd   : ADSWRITEIND;
   fbAdsWriteRes   : ADSWRITERES;
   bExecute        : BOOL;
   stAdsInfo AT %I*: ST_AmsAddr;
   nState    AT %I*: WORD;
   UnKonwnoffset   : UDINT;
END_VAR

fbAdsWriteInd(
   CLEAR := ,
   VALID => ,
   NETID => ,
   PORT => ,
   INVOKEID => ,
   IDXGRP => ,
   IDXOFFS => ,
   LENGTH => ,
   DATAADDR => );

IF fbAdsWriteInd.VALID THEN
   (* You have to check the NETID and port number if you use ADS notification also for other things *)
   i := i + 1;
   sNetId := fbAdsWriteInd.NETID;            // AMD Net ID from device (CX7031)
   nPort := fbAdsWriteInd.PORT;              // PB Adresse + 1000 dec
   udInvokeId := fbAdsWriteInd.INVOKEID;     // for the Response
   udGroup := UDINT_TO_DWORD(fbAdsWriteInd.IDXGRP);
   udOffset := fbAdsWriteInd.IDXOFFS;        // Prm or Cfg Data
   udLength := fbAdsWriteInd.LENGTH;         // Len of the data
   ptrByte := fbAdsWriteInd.DATAADDR;        // Pointer from the data

   fbAdsWriteRes.RESULT := 0;                // Result without Error, if you want to send an Error use "1" 

   IF nPort = 1002 THEN // Slave with Adress 2
      CASE udOffset OF
         16#03230020:       // Prm Data 
            MEMCPY(ADR(strPrmData2), ptrByte, udLength);
         16#03230021:       // Cfg Data
            MEMCPY(ADR(strCfgData2), ptrByte, udLength);
         ELSE
            fbAdsWriteRes.RESULT := 1;
            UnKnownOffset := udOffset;
      END_CASE
   END_IF

   IF nPort = 1003 THEN   // Slave with Adress 3
      CASE udOffset OF
         16#03230020:       // Prm Data 
            MEMCPY(ADR(strPrmData3), ptrByte, udLength);
         16#03230021:       // Cfg Data
            MEMCPY(ADR(strCfgData3), ptrByte, udLength);
         ELSE
            fbAdsWriteRes.RESULT := 1;
            UnKnownOffset := udOffset;
      END_CASE
   END_IF

   IF iCase = 0 THEN
      iCase := 10;      // Send response
   END_IF
END_IF

CASE iCase OF
   0: (* WAIT *);
   10: (* send ADS-Response *)    
      fbAdsWriteRes(
         NETID := sNetId,
         PORT := nPort,
         INVOKEID := udInvokeId,
         RESULT := ,
         RESPOND := TRUE);

      fbAdsWriteInd(CLEAR := TRUE); (* confirm ADS-Indication *)
      iCase := 20;
   
   20: 
      fbAdsWriteRes(RESPOND := FALSE);
      fbAdsWriteInd(CLEAR := FALSE);
      iCase := 0;
END_CASE