Access by variable name

Download: 'Access by Variable Name'

The following program accesses a PLC variable that does not have an address. Access must therefore be made by the variable name. Once the PLC variable in the example program exceeds 10 it is reset to 0.

All data that ADS devices make available to the outside is organised by means of IndexGroups and IndexOffset. An IndexGroup can be thought of as a table, with each entry being addressed by the IndexOffset. The TwinCAT PLC has, for example, IndexGroups in which the variables that belong to the input/output or flags regions are stored. IndexGroups are also available to the TwinCAT PLC through which system functions may be addressed.

The IndexGroups ADSIGRP_SYM_HNDBYNAME and ADSIGRP_ SYM_VALBYHND are important for the example program. The IndexGroup ADSIGRP_SYM_HNDBYNAME is used to request a handle from a PLC variable identified by name. The variable can be accessed with the aid of this handle and the IndexGroup ADSIGRP_SYM_VALBYHND. The variable's handle is passed as the IndexOffset.

#include <iostream.h>
#include <windows.h>
#include <conio.h>


// ADS headers for TwinCAT 3
#include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsDef.h"
#include "C:\TwinCAT\AdsApi\TcAdsDll\Include\TcAdsAPI.h"

void main()
{
long nErr, nPort;
AmsAddr Addr;
PAmsAddr pAddr = &Addr;
ULONG lHdlVar, nData;
char szVar []={"MAIN.PLCVar"};

// Open communication port on the ADS router
nPort = AdsPortOpen();
nErr = AdsGetLocalAddress(pAddr);
if (nErr) cerr << "Error: AdsGetLocalAddress: " << nErr << '\n';

// TwinCAT 3 PLC1 = 851
pAddr->port = 851;

// Fetch handle for an <szVar> PLC variable
nErr = AdsSyncReadWriteReq(pAddr, ADSIGRP_SYM_HNDBYNAME, 0x0, sizeof(lHdlVar), &lHdlVar, sizeof(szVar), szVar);
if (nErr) cerr << "Error: AdsSyncReadWriteReq: " << nErr << '\n';
do
{
// Read value of a PLC variable (by handle)
nErr = AdsSyncReadReq( pAddr, ADSIGRP_SYM_VALBYHND, lHdlVar, sizeof(nData), &nData );
if (nErr)
cerr << "Fehler: AdsSyncReadReq: " << nErr << '\n';
else
cout << "Wert: " << nData << '\n';
cout.flush();
if (Data > 10)
{
// Reset the value of the PLC variable to 0
nData = 0;
nErr = AdsSyncWriteReq(pAddr, ADSIGRP_SYM_VALBYHND, lHdlVar, sizeof(nData), &nData);
if (nErr) cerr << "Error: AdsSyncWriteReq: " << nErr << '\n';
}
}
while ( getch() == '\r'); // read next value with RETURN, else end


//Release handle of plc variable
nErr = AdsSyncWriteReq(pAddr, ADSIGRP_SYM_RELEASEHND, 0, sizeof(lHdlVar), &lHdlVar);
if (nErr) cerr << "Error: AdsSyncWriteReq: " << nErr << '\n';

// Close communication port
nErr = AdsPortClose();
if (nErr) cerr << "Error: AdsPortClose: " << nErr << '\n';
}