Beckhoff / ADS

Beckhoff protocol to communicate with TwinCAT devices.
MIT License
517 stars 197 forks source link

Read or Write a list of variables with one single ADS-command #24

Closed Satheesh-satz closed 8 years ago

Satheesh-satz commented 8 years ago

This is regarding writing a list of variables with one single ADS-command as referred in the following link. http://infosys.beckhoff.com/english.php?content=../content/1033/tcsample_labview/html/tcsample_labview_overview.htm&id=

From the provided sample application "ADS_Demo_SumReq.cpp" it has used data structure

typedef struct dataPar { unsigned long indexGroup1; // index group in ADS server interface unsigned long indexOffset1; // index offset in ADS server interface unsigned long length1; // count of bytes to read unsigned long indexGroup2; // index group in ADS server interface unsigned long indexOffset2; // index offset in ADS server interface unsigned long length2; // count of bytes to read unsigned long data1; // count of bytes to read unsigned long data2; // count of bytes to read } TDataPar;

But with this data structure it is limited to only two variables right? And also i am not finding this data structure defined any where on the ADS library header files.

My question here is :

  1. How to modify the data structure and use it to write multiple variables?
  2. Can we have this data structure captured on any of the ADS header files

Thanks, Satheesh

pbruenn commented 8 years ago

Are you sure your link is correct? I think you are looking for this one: http://infosys.beckhoff.com/content/1033/tcsample_vc/html/tcadsdll_api_cpp_sample17.htm?id=20654114132734386906

Satheesh-satz commented 8 years ago

Hi Patrick, You are right, That the link i am talking about.

pbruenn commented 8 years ago

Okay, there you find this example: http://infosys.beckhoff.com/content/1033/tcsample_vc/Samples/API/CPP/Sample17/Sample17-C-ADS-DLL-SumRequests.zip

There is this struct used:

typedef struct dataPar {
    unsigned long       indexGroup; // index group in ADS server interface
    unsigned long       indexOffset;    // index offset in ADS server interface
    unsigned long       length;     // count of bytes to read
} TDataPar;
TDataPar parReq[2];

And AdsSyncReadWriteReq() called like this:

nErr = AdsSyncReadWriteReq(pAddr, 
                        0xf080, 
                        reqNum, 
                        4*reqNum+reqSize,   // we request additional "error"-flag(long) for each ADS-sub commands
                        (void*)(mAdsSumBufferRes), 
                        12*reqNum,          // send 12 bytes (3 * long : IG, IO, Len) of each ADS-sub command
                        &parReq);
Satheesh-satz commented 8 years ago

Hi Patric,

I referring to the Multiple write sample, in that the structure is define just to write only two variable at a time

typedef struct dataPar { unsigned long indexGroup1; // index group in ADS server interface unsigned long indexOffset1; // index offset in ADS server interface unsigned long length1; // count of bytes to read unsigned long indexGroup2; // index group in ADS server interface unsigned long indexOffset2; // index offset in ADS server interface unsigned long length2; // count of bytes to read unsigned long data1; // count of bytes to read unsigned long data2; // count of bytes to read } TDataPar; TDataPar parReq;

So, my question here is, what if i want to write more than two variable at a time.

Thanks, Satheesh

pbruenn commented 8 years ago

Did you try:

typedef struct dataTriple {
    unsigned long indexGroup1; // index group in ADS server interface
    unsigned long indexOffset1; // index offset in ADS server interface
    unsigned long length1; // count of bytes to read
    unsigned long indexGroup2; // index group in ADS server interface
    unsigned long indexOffset2; // index offset in ADS server interface
    unsigned long length2; // count of bytes to read
    unsigned long indexGroup3;
    unsigned long indexOffset3;
    unsigned long length3;
    unsigned long data1; // count of bytes to read
    unsigned long data2; // count of bytes to read
    unsigned long data3;
} TDataTriple;

Personally I would reuse TDataPar from the read example:

template <class T, size_t N>
struct AdsWriteTuple {
    TDataPar header[N];
    T data[N];
};

And use it like this:

static const size_t reqNum = 3;
AdsWriteTuple<unsigned long, reqNum> parReq;

nErr = AdsSyncReadWriteReq(pAddr,
                           0xF081, // ADS list-write command
                           reqNum, // number of ADS-Sub commands
                           4*reqNum, // we expect an ADS-error-return-code for each ADS-Sub command
                           (void*)(mAdsSumBufferRes), // provide space for the response containing the return codes
                           sizeof(parReq),
                           &parReq);   // buffer with data

As we are on suggestions. I highly recommend to use uint32_t instead of unsigned long, when you expect to work with an unsigned 32-Bit value, because unsigned long could be 64-Bit on different compilers.