Code Monkey home page Code Monkey logo

ads's People

Contributors

asolchen avatar ccvca avatar david-n11 avatar jasperdekeuk avatar jheuking avatar jole-bhf avatar klassenh avatar marcus-sonestedt avatar miq avatar mwiarda avatar nicolatimeus avatar pbruenn avatar pylipp avatar sdirkwinkel avatar simonschmeisser avatar soberschmidt avatar tboegi avatar vossjannik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ads's Issues

dev-ooi: Handles currently can "outlive" the global AmsRouter object

Hi,

I'm currently working on the ooi branch and its looking good so far.
However, there is a problem with the HandleGuard and the HandleDeleter functor.
HandleDeleter::() uses the global AmsRouter object to delete the handle.
However, in the "relatively special" case that an AdsVariable object is global and outlives the router we currently run into an exception.

The Construct On First Use Idiom would probably solve this.

Regards
Michael

make install failing

Following readme:
:~/ADS$ make install
make: *** No rule to make target 'install'. Stop.

Fresh Ubuntu 17.04 install.

/edit/ I see the note on the most recent change to Makefile says "remove install, use lib directly". Can you please update the readme to reflect the new steps? Not sure what needs to go where to use directly.

can the PLC send an "unsolicited" message

I see the bit for request|response in the header. As a client it is clear to set as request --- when the reply comes the response bit should be set. So, in the event that the PLC decides to send a block of data --- what would the instruction be in the PLC and what should the header/command would look like at the client when the message is received ?

AdsNotificationAttrib

Hi,
Could you please help me to understand the event notification related queries

AdsNotificationAttrib::cbLength : Length of the data that is to be passed to the callback function.

What would be the length of cbLength data of the AdsNotificationAttrib structure variable passed as a
parameter to register a notification via a call to the AdsSyncAddDeviceNotificationReq

is this related to the

AdsSyncAddDeviceNotificationReq::hUser parameter
[in] 32-bit value that is passed to the callback function.
if yes, it would be 4 bytes value always right?

So, What kind of data would be passed back to the callback function via pNotification->data and what would be the size of the data?

How to handle if i require more than 550 notification?

nCycleTime
The ADS server checks whether the variable has changed after this time interval. The unit is 100 ns.

What would be the time delay if i registered for 100 notification with the nCycleTime set to 100ns?

dev-ooi: different AmsPort for symbol/index access

Moved from #35:
xift wrote:
And now a problem I ran into when playing around a little:
My test PLC project has several inputs and outputs. Application port is the usual 851 and the tasks symbol port is 350. Here is the problem. When I read or write arrays by name I have to use the application port and when I use index group and index offset I need to use the symbol port.
I basically have to set up two separate AdsClient instances for that. It is highly inconvenient and the error message when using the wrong port (1793) is too cryptic to easily spot the mistake.

To visualize the problem:
image

How can we solve that?

  1. Add symbolPort to the AdsClient constructor
  2. New GetAdsVariable parameter: GetAdsVariable(symbolPort, indexGroup, indexOffset)

dev-ooi: AdsClient.h does not compile with Visual Studio 2015

moved from #35:
xift wrote:
Sidenote: AdsClient.h does not compile with Visual Studio 2015.
It doesn't like the HandleGuard.

return AdsHandleGuard {new uint32_t {handle}, std::bind(&ReleaseHandle, address, port, std::placeholders::_1)};

No instance of constructor "std::unique_ptr<_Ty, _Dx>::unique_ptr [with _Ty=uint32_t, _Dx=std::_Binder &>]" matches the argument list.
Argument types are: (uint32_t , std::_Binder<std::_Unforced, void ()(AmsAddr address, long port, uint32_t *handle), const AmsAddr &, long &, const std::_Ph<1> &>)
You seem to be quite familiar with modern C++. Do you often use ? I know what bind does but I have never had the opportunity to use it. I just don't think about that. How did you start using it?

TCP/IP Disconnect Notification

Hi Sven,

Is there a way to get a disconnect event notification from the ADS Library in case of any network connection loss or manual network disconnect from the PLC (CX hardware) ?

or

Do we need to have our own keep alive packet transaction with the PLC?

AdsNotificationHeader has nTimeStamp & nNotification backwards

In AdsDef.h at line 287,
nTimeStamp and hNotification are in the wrong order.

typedef struct {
    uint64_t nTimeStamp;
    uint32_t hNotification;
    uint32_t cbSampleSize;
#ifndef __cplusplus
    uint8_t data[];
#endif
} AdsNotificationHeader, * PAdsNotificationHeader;

My reference for this is from these two places.

TwinCat2 docs

typedef struct {
  ULONG           hNotification;
  __int64         nTimeStamp;
  ULONG           cbSampleSize;
  UCHAR           data[ANYSIZE_ARRAY];
} AdsNotificationHeader, *PAdsNotificationHeader;

TwinCat3 docs

      typedef struct {

       ULONG
      hNotification;
      __int64
      nTimeStamp;
      ULONG
      cbSampleSize;
      UCHAR
      data[ANYSIZE_ARRAY];
      } AdsNotificationHeader, *PAdsNotificationHeader;

Beckhoff ADS

How do i get the Beckhoff ADS component working in homeassistant on a PI3 ?
I added the component and getan error.
I know al lot about Beckhoff TwinCat2 and 3

Linux WebServer to host visualization and connect to CX via ADS

Hello!

For our visualization we currently always use the WebServer on CX (CX8090 or CX9020 with WinCE). There is both - the TcAdsWebService.dll and our visualization (NO php or asp - only html and js). The access (read / write) then takes place via ADS - TAME 3 (http://tomcx.github.io/tame3/). The visualization is called from Firefox (on Windows) or on a Linux-touch display (Garz & Fricke) or from an Android / iOS Phone in the network.

So far so good. Now we have a requirement that we do not use the WebServer on CX, but the one on a Linux-touch panel PC. The aim should therefore be, to host the visualization and the AdsWebService (?) on Linux and then again from the visualization via JavaScript via WebService (?) to gain access to CX via ADS.

  • is that possible?
  • What is needed to prepare a route between CX and Linux (is probably necessary ?!)?
  • is there an equivalent to TcAdsWebService.dll?
  • Which libraries etc. are necessary?

The touch panel is a device made by Hainzl from Linz (http://www.hainzl.at/de).

  • WebServer nginx 1.10.0
  • Linux kernel version: Linux mmi13 3:16:35 # 1 SMP PREEMPT Tue Jun 28 09:56:37 CEST 2016 armv7l GNU / Linux

Thanks for your support!

regards
Petra Niederkofler

PS:
Attached you find a list of installed packages:
packages.txt

non-GUI way to add remotes to the router table possible?

From all the documentation I read, they all reference to some GUI interface to add a remote to the router table. is there any API or steps that can be automated programably?

If this is possible,I'd like to write a small stub program on the TWinCAT server helping this adslib to register itself before any ADS communication.

ADS -1 Error

Hi Sven,

Sometimes i am getting an error -1 from the ADS library and i have no idea how to interpret the issue with the error code -1.

I am seeing this particular warning message before getting the error -1 sometimes in a loop when I tried to call the ads function “AdsSyncReadDeviceInfoReqEx” with 2 seconds of delay

Message:
“Warning: Port: 30000 already in use as xxxxx" and that comes from the function “AmsConnection::Reserve” which is called from “AmsConnection::Write”

AmsResponse* AmsConnection::Reserve(uint32_t id, uint16_t port)
{
uint32_t isFree = 0;
if (!queue[port - Router::PORT_BASE].invokeId.compare_exchange_weak(isFree, id)) {
LOG_WARN("Port: " << port << " already in use as " << isFree);
return nullptr;
}
return &queue[port - Router::PORT_BASE];
}

Thanks,
Satheesh

ADS error 1861

Hi,

I'm using the lib with the example file and after adding the static route and it does appear in the target and the client routes.

But I still get the timeout error, If I just use the standard block ADS read and call for the same index, it does read from the target PC.

Not sure, what can I check

Thanks,
Ram

ADS Remote Access and Security

I propose to add a precondion to the README file in the repository in the "Prepare your target to run the example" section.
In this section the routing is addresses, but security isn't.
And please add a link to the "Remote Access" of the Beckhoff docs covering the Firewall configuration.

Multiple connections to a single TwinCAT computer.

Hi, I'm having trouble connecting multiple instances of the same AdsLib application to a single TwinCat computer.

Program instance 1.
AdsAddRoute
AdsPortOpenEx
while(1)
{
read/write some data on interval.
}

This works fine but if i start another instance of the same program and try to connect to the same TwinCat computer, program 1 fails and I get ClientSyncTimeout(1861) as soon as the program instance 2 hits AdsAddRoute.

Is this just not an option in the implementation of the ADS, or further more how would you achieve the same functionality in case I have overlooked something?

Another thing I've noticed is that reading the same variable with AdsSyncReadWriteReqEx2 doesn't take constant time in fact it varies as you can see on the image below(from 0.5-2,5 ms). Is this just something to be expected?

image

Any help/pointers would be appreciated.

Regards Emil.

Win32 Error Code

Hi Sven,

Are we following the same win32 error codes in the ADS Library for the Network and other related issues

For Example:

0x274c 10060 A socket operation was attempted to an unreachable host
Host unreachable Check network connection via ping

ADS Library Crash

Hi,

I am seeing the Library is crashing with a segmentation fault and core dump after the connection has been established with the ADS Server.

Please find the Call stack from the core dump below
#0 0x000000000041f345 in std::__atomic_base::load(std::memory_order) const ()

at /cadappl/gcc_euv/4.8.2/gcc_euv/include/c++/4.8.2/bits/atomic_base.h:496

#1 0x000000000041eb4f in std::__atomic_base::operator unsigned int() const ()

at /cadappl/gcc_euv/4.8.2/gcc_euv/include/c++/4.8.2/bits/atomic_base.h:367

#2 0x000000000041cade in AmsConnection::GetPending(unsigned int, unsigned short) () at AmsConnection.cpp:138
#3 0x000000000041d6e5 in AmsConnection::Recv() () at AmsConnection.cpp:250
#4 0x000000000041d43e in AmsConnection::TryRecv() () at AmsConnection.cpp:226
#5 0x000000000042205b in ZNKSt7_Mem_fnIM13AmsConnectionFvvEEclIJEvEEvPS0_DpOT ()

at /cadappl/gcc_euv/4.8.2/gcc_euv/include/c++/4.8.2/functional:601

#6 0x0000000000421f6f in _ZNSt12_Bind_simpleIFSt7_Mem_fnIM13AmsConnectionFvvEEPS1_EE9_M_invokeIJLm0EEEEvSt12_Index_tupleIJXspT_EEE

() at /cadappl/gcc_euv/4.8.2/gcc_euv/include/c++/4.8.2/functional:1732

#7 0x0000000000421e23 in std::_Bind_simple<std::_Mem_fn<void (AmsConnection::)()> ()(AmsConnection)>::operator()() ()

at /cadappl/gcc_euv/4.8.2/gcc_euv/include/c++/4.8.2/functional:1720

#8 0x0000000000421d72 in std::thread::_Impl<std::_Bind_simple<std::_Mem_fn<void (AmsConnection::)()> ()(AmsConnection)> >::_M_run() () at /cadappl/gcc_euv/4.8.2/gcc_euv/include/c++/4.8.2/thread:115
#9 0x00007f01221c457e in execute_native_thread_routine () from /home/msc/HPC_Driver/Libraries/libstdc++.so.6
#10 0x0000003e97e07851 in start_thread () from /lib64/libpthread.so.0
#11 0x0000003e97ae890d in clone () from /lib64/libc.so.6

"make test" Error on macOS 10.13.3

on "make test" I get an error:
c++ AdsLibTest/main.cpp AdsLib-Darwin.a -lpthread -lc++ -I AdsLib/ -I tools/ -std=c++11 -pedantic -Wall -o AdsLibTest.bin
AdsLibTest/main.cpp:9:10: fatal error: 'fructose/fructose.h' file not found
#include <fructose/fructose.h>
^~~~~~~~~~~~~~~~~~~~~
1 error generated.
make: *** [AdsLibTest.bin] Error 1

ADS function Delay

I am seeing delay of two minutes with either Deleting the Device Notification with the call to “AdsSyncDelDeviceNotificationReqEx” or with Closing the port with a call “AdsPortCloseEx”.

In both the cases I am seeing it tries to erase the notification in a loop and it takes approximately 2 minutes every time.
And this happen when the PLC connection is disconnected manually from the Ethernet port.

void AmsPort::Close()
{
std::lock_guardstd::mutex lock(mutex);

auto it = std::begin(notifications);
while (it != std::end(notifications)) {
    it->second->Erase(it->first, tmms);
    it = notifications.erase(it);
}
port = 0;

}

bool AmsPort::DelNotification(const AmsAddr& ams, uint32_t hNotify)
{
std::lock_guardstd::mutex lock(mutex);
for (auto it = notifications.begin(); it != notifications.end(); ++it) {
if (it->first == hNotify) {
if (std::ref(it->second->conn.second) == ams) {
it->second->Erase(hNotify, tmms);
notifications.erase(it);
return true;
}
}
}
return false;
}

Could you please help me solve this delay of 2 minutes.

AdsAmsRegisterRouterNotification, AdsAmsUnRegisterRouterNotification

Hello. I use TwinCAT3 on Windows regularly and use AdsAmsRegisterRouterNotification and AdsAmsUnRegisterRouterNotification to detect changes in the router (AMSEVENT_ROUTERSTOP, AMSEVENT_ROUTERSTART, AMSEVENT_ROUTERREMOVED). I've been using this library to port the program I wrote to other operating systems, but can't find an replacement for these functions. Is there a way of detecting changes in the remote router state using this library?

Thanks!

Which port to connect

We are developing a driver -- we see port 851, but also see port AMSPORT_R0_PLC_RTS1
What is the difference? I see in the h files --- RTS1, 2, 3 and RTS4. Which one should we use ?
Is this fixed in the PLC ?

DeadLock with the event Notification

Hi ,

We kind of getting into a deadlock situation, when we tried to subscribe to a bunch of events by calling the function "AdsSyncAddDeviceNotificationReqEx" with the "Mutex A" locked; which internally called the NotificationDispatcher::Emplace function which uses another mutex "std::lock_guardstd::recursive_mutex lock(mutex)" to synchronize between "NotificationDispatcher::Run()", 'NotificationDispatcher::Erase" and "NotificationDispatcher::Emplace"

But the deadlock occurs here when an event is received during the call to subscribe and the registered event call back function is called with "std::lock_guardstd::recursive_mutex lock(mutex)" locked inside the
"NotificationDispatcher::Run()" function and waiting for the call back to return which in turn requires the "Mutex A" to do something before returning.

We tried to get out of this issue by releasing the mutex "std::lock_guardstd::recursive_mutex lock(mutex)" before calling the callback function (code attached) and that seems to be working fine. Could you please look into this issue and release an update with this fix.

Code Snippet

std::map<uint32_t, std::shared_ptr<Notification> > notifications;
void NotificationDispatcher::Emplace(uint32_t hNotify, Notification& notification)
{
   LOG_ERROR("From Inside NotificationDispatcher::Emplace before trying to get the mutex lock");
    std::lock_guard<std::recursive_mutex> lock(mutex);
    LOG_ERROR("From Inside NotificationDispatcher::Emplace After lock has acquired");
    notifications.emplace(hNotify, std::make_shared<Notification>(notification));
}

void NotificationDispatcher::Run()
{
   while (sem.Wait())
   {
      const auto length = ring.ReadFromLittleEndian<uint32_t>();
      (void)length;
      const auto numStamps = ring.ReadFromLittleEndian<uint32_t>();
      for (uint32_t stamp = 0; stamp < numStamps; ++stamp) {
         const auto timestamp = ring.ReadFromLittleEndian<uint64_t>();
         const auto numSamples = ring.ReadFromLittleEndian<uint32_t>();
         for (uint32_t sample = 0; sample < numSamples; ++sample) {
             const auto hNotify = ring.ReadFromLittleEndian<uint32_t>();
             const auto size = ring.ReadFromLittleEndian<uint32_t>();
             std::shared_ptr<Notification> ptr;
             {
                LOG_ERROR("From Inside NotificationDispatcher::Run before trying to get the mutex lock");
                std::lock_guard<std::recursive_mutex> lock(mutex);
                LOG_ERROR("From Inside NotificationDispatcher::Run After lock has acquired");
                auto it = notifications.find(hNotify);
                if (it != notifications.end())
                {
                   ptr = it->second;
                }
             }
             LOG_ERROR("From Inside NotificationDispatcher::Run released the lock");
             if (ptr)
             {
                auto& notification = *ptr;
                if (size != notification.Size())
                {
                   LOG_WARN("Notification sample size: " << size << " doesn't match: " << notification.Size());
                   ring.Read(size);
                   return;
                }
                notification.Notify(timestamp, ring);
             }
             else
             {
                ring.Read(size);
             }
         }
      }
   }
}

Thanks,
Satheesh

Error: Connect TCP socket failed with: 110 ?

I am wondering if I understood the programming model correctly.
Here is the IP info:

  • My Windows-PC with TwinCAT-3: 192.168.2.41
  • My Linux-target : 192.168.2.116

Here is what I did on my Windows-PC:

  • Add static route to TwinCAT-3: "any-name 192.168.2.116.1.1 192.168.2.116 TCP_IP"
  • Restart TwinCAT-3
  • (so far I do nothing with "PLC-TestProject")

Here is what I did on Linux target:

static const AmsNetId remoteNetId { 192, 168, 2, 41, 1, 1 };
static const char remoteIpV4[] = "192.168.2.41";     // "ads-server";
  • make
  • make test

Then I got:

debian@beaglebone:~/ADS/example$ make test
./example.bin
     (after a couple of minutes)
2018-03-17T21:34:43+0000 Error: Connect TCP socket failed with: 110
Adding ADS route failed, did you specified valid addresses?

Anything wrong with my procedure?

Thanks!
Jerry

handling multiple nics

Hi, I noticed that there is no support for the computer running your library to have multiple network interfaces, each with ads machines on.

For example two networks cards, each with an ADS machine on.

In the router there is the concept of 'local address' and this is populated with the ip address used by the first connection's 'own ip'.
The write function then uses this as the 'src address' when sending all further commands,

If a new connection is made it is assumed that the src ip address is the same, however if this is done through a different network interface then the write command sets the 'src address' incorrectly and the transaction fails.

I have implemented the following patch as a workaround

diff --git a/AdsLib/AmsConnection.h b/AdsLib/AmsConnection.h
index 6efc72c..540769b 100644
--- a/AdsLib/AmsConnection.h
+++ b/AdsLib/AmsConnection.h
@@ -80,10 +80,10 @@ struct AmsConnection : AmsProxy {
     template<class T> long AdsRequest(AmsRequest& request, uint32_t tmms)
     {
         AmsAddr srcAddr;
-        const auto status = router.GetLocalAddress(request.port, &srcAddr);
-        if (status) {
-            return status;
-        }
+        AmsNetId netId = AmsNetId {ownIp};
+        memcpy(&srcAddr.netId, &netId, sizeof(netId));
+        srcAddr.port = request.port;
+
         AmsResponse* response = Write(request.frame, request.destAddr, srcAddr, request.cmdId);
         if (response) {
             if (response->Wait(tmms)) {

This utilises the fact that each connection object knows it own src ip, and so it uses that rather than calling the router's GetLocalAddress method.
What this does not take into account is there are external API's for getting and setting the local address, and these would still just affect the variable localAddress stored in the router object (which this workaround bypasses). I am not sure why the external API's to get and set the local address are required, but I would like to get a fix in that does not alter any of these external API's.

Another way to solve this (and keep the get and set method's valid), is to keep a 'map' of src addresses and use the portnumber as a key. This would require some API changes though, e.g to store each src address in the Router's AddRoute method, the AddRoute method would need the portnumber passed in, so the API for AdsAddRoute would need this extra portnumber parameter.
Also the get and set local address methods, would also need to pass in a portnumber too.

Please can you let me know what you think the best solution would be, as I am keen to get this support into your great library, rather than hacking a patch into my version locally

Thanks,
Dominic

Batch Delete Notifications Failing

According to the documentation for TC3 here:

http://infosys.beckhoff.de/content/1033/tc3_adsdeviceplc/html/tcadsdeviceplc_indexadsservice.htm?id=10419422066105251481

I should be able to delete a batch of notification handles in a single request. I can close them individually using AdsDelDevNotification, but closing 500 notifications on a single target/port takes up to a second when theoretically we should be able to do so in ~2ms.

// given valid handles from AdsAddDevNotification(...)
std::uint32_t handle1, handle2, ...

std::vectorstd::uint32_t handles = { handle1, handle2 };
std::vectorstd::uint32_t responses(2);

std::uint32_t len = handle.size() * sizeof(std::uint32_t);

long code = AdsSyncReadWriteEx2(
local_port,
&target,
0xF086, //ADSIGRP_SUMUP_DELDEVNOTE,
handles.size(),
len,
responses.data(),
len,
handles.data(),
nullptr);

// tested against TC3.1.4020.10 on a CX5020
// code == 0
// responses[0] = 0x704
// responses[1] = 0x704

Am I misusing the index group/read write request, is this an issue with the AdsLib, or is this just an implementation bug/never implemented in the twincat runtime server?

Alarm&Events through ADS

The documentation indicates it's possible to access TcEventLogger remotely with ADS. However the API details seem to say only Windows CE accepts such remoting.

  • TcEventLogger seems to be a separate COM server, is it accessible from the same TCP ports this project uses.
  • Is the support of fetching alarms and Events from TcEventLogger within the scope of this project if the answer to the above question is yes?

Error 1861

Hi Sven,

I am getting the error 1861 in one my linux machine when i try to read some data back after the connection established successfully with the Twincat service running on a windows machine,

I have used the application "example" to test this scenario.

I did turn off the firewall and all the route has been added on the twincat service.

Could you help me more to understand and debug this issue.

1861: timeout elapsed "Check ADS routes of sender and receiver and your firewall setting"

Thx

Problem with routes in TwinCAT

Hi,
i just tried the new function AdsSetLocalAdress(). I tested the endings ...1.1 and ...1.2. For that, I added two routes in TwinCAT, as you can see on the picture:

grafik

When i then started to test, only ...1.1 worked, while ...1.2 didnt receive any responses from TwinCAT. Then i deleted the ...1.1 route in TwinCAT, and the ...1.2 route started to work. After that, i added the ...1.1 route again. Now ....1.2 was on top of ...1.1, and ...1.2 still worked while ...1.1 didnt. So it seems like only the upper route works, while the others are getting ignored. I also used Wireshark, for the second route there are no responses.
Is it supposed to work like this?
TwinCAT Version is 3.1.4020.

Thanks,
Chris

Suggestion: Add additional interfaces to the library

Hi,
thanks for making this open source. I work with TwinCAT daily and was happy to see some of the implementation. The library code is pretty clean as well. Nice work!

So my suggestion would be to build upon this library and add interfaces.
Something that comes to mind is a class based interface for C++ which uses templates to enable compile time type checks for the read and write functions. Or a Matlab file which provides wrapper methods.
I know there are Matlab examples and things like pyAds. However, I'd like to see it bundled in one repository.

Regards
Michael

Notification example does not report updated values

I'm testing the notification mechanism from the ADS protocol using the AdsSyncAddDeviceNotificationReqEx call.
The provided example has been build on Ubuntu 14.04 LTS and Windows7-64bit cygwin64.
On both platform the ADS client runs without errors.
The application data from the PLC-TestProject in the array is continously updated.
The reported value from the ADS client for indexgroup 0x4020 with offset 4 is always 0 on both plaforms, that is incorrect. Even with a sample size of 1, the byte value should be update conform the value in the array.
Check the attached screenshots of the PLC application and the reported output of the ADS clients on both platforms.
The screenshot of the About TwinCAT System is also attached.

screenshot 2015-10-27 21 57 20
screenshot 2015-10-27 22 01 59
screenshot 2015-10-28 00 03 06
screenshot_windows7-64
ubuntu_14 04lts

timeout with TC2 v2.11.2248

I cloned the latest version into a VMware with TC2 v2.11.2248 installed. It compiled smoothly with no error.
So I tried to run the example with necessary changes:

  • at line #193, I changed from AMSPORT_R0_PLC_TC3 to AMSPORT_R0_PLC.
  • at line #177&178, I also made necessary changes to the Addresses.

Then I create a TC2 PLC project, with the code I extracted from your test project:

PROGRAM MAIN
VAR
    byByte      AT %MB0 : ARRAY [0..1027] OF BYTE;
    i           : INT;
END_VAR

FOR i := 4 TO 1027 BY 1 DO
    byByte[i] := byByte[i] + 1;
END_FOR

Then I tested it's working well with pyads e.g.

adsSyncReadByName(adr, "MAIN.byBYTE", PLCTYPE_ARR_INT(1028))

all good.

However, when running the example.exe. It always ends up with timeout.

2016-07-25T11:12:20 Info: Connecting to 192.168.150.142
Add device notification failed with: 1861
notificationByNameExample():
Create handle for 'MAIN.byByte' failed with: 0x745
Add device notification failed with: 1861
readExample():
ADS read failed with: 1861
readByNameExample():
Create handle for 'MAIN.byByte' failed with: 0x745
ADS read failed with: 1861
ADS read failed with: 1861
2016-07-25T11:12:55 Info: connection closed by remote

Do you know why?

By the way, is this this repo the official implementation that's shipped with TWinCAT , or an alternative implementation?

Thanks.

PLC Simulator

Hi Sven,

Is that possible to develop a complete PLC simulator on Visual studio with Twincat?

dev-ooi: Usage of AdsRoute not intuitive

Hi,
I just read through the example code.
Love the easy way to establish a route using the AdsRoute class.
However, if you forget about it you just get the TargetMachineNotFound error code when you try to create an AdsVariable for the first time.
I believe that a good API would prevent me from making a request without having a route.

Currently trying out some ideas and options.
But haven't found a good one yet :-(
Best one so far goes along the lines of replacing the AmsAddr with AdsRoute in the AdsVariable<> constructor.

AdsLocalPort is better, but I would love the handling to be internal and not pass it every time I do something. So if you request a variable for the first time a port is opened.

Regards
Michael

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

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

Does anybody have .pdf file for ADS specification?

As I remembered, there is .pdf file for ADS specification, which can be downloaded from somewhere.

  • But I googled, and found nothing.

So weird, I thought I downloaded this file before, but could not find it in my computer either!

  • Maybe something wrong with my memory? (but I remembered it so vividly!)

Thanks,
Jerry

Socket reuse

Is there a reason why the SO_REUSEADDR option is not set when the TCP socket is configured

I have an application where the ADS module ends up being restarted on occasion and we tend to get the EADDRINUSE error from the socket due to the previous TCP socket hanging around for a while due to TCP connection timeouts.

I am happy to submit a patch with the change if required.

IO task notifications

Hi
I don't think that opening an issue was the right choice for asking questions about the lib, sorry if I did wrong.

After testing the reading/writing/ features, I found myself stuck while trying to use notification feature with a "non-memory" variable. In the lib example we subscribe to a variable declared as follows:

byByte      AT %MB0 : ARRAY [0..1027] OF BYTE;

It works fine.
But when I adapt the example with a var declared as below:

monitoredOutput  AT %Q*: BOOL;

It doesn't work and I get a 0x701 error code (ie. Service is not supported by server). Note the * char. I don't have physical I/O to address.

I'm using TwinCAT 3 and I got the Index group/offeset from the variable detail view. For example, inside of the ADS Info field I had an Index group of 0x1010010 and a Index offset of 0x8107D209. The same field specifies a port of 350 which is different from the one (851) the TwinCAT PLC listens on. I even thought that my problem came from that so I tried to use that port (350) as a parameter to the AdsSyncAddDeviceNotificationReqEx function. It failed.

So my question is does the AdsSyncAddDeviceNotificationReqEx function support variables declared with the % character?

Best regards,
Jeyfel B

examples refactored

I did some refactoring my branch. I'm not sure if you are interested or OK with the style. My changes are mainly for easy adaption to new remote targets and grouping of similar functions.

Eventually, I'd like to use this lib to build a remote HMI, be it CLI or GUI, starting from this example.
By the way, do you have an example for ADS-sum command? is it supported in this implementation?

dev-ooi-v2: manage device state changes

Advance AdsDevice to automatically detect device state changes.

  • reconnect on connection loss
  • renew symbolHandles, when they got invalidated by the AdsServer

Makefile weirdness

CC = g++
is a bit weird, generally CXX refers to the default C++ compiler
to make it more cross-build frieldly, I'd suggest CXX ?= g++

AdsLibTest.bin: $(LIB_NAME)
$(CC) AdsLibTest/main.cpp $&lt; -I AdsLib/ -I ../ -std=c++11 $(LIBS) -o $@
is a bit weird, why not
AdsLibTest.bin: $(LIB_NAME) main.o
$(CC) main.o $&lt; -I AdsLib/ -I ../ -std=c++11 $(LIBS) -o $@
so all .o are build by the .cpp.o rule
is -I ../ needed?
I think -I and std=c++11 can be dropped when purely linking

use $(AR) instead of plain ar (cross-build)

ADS read error example: 1861

Hi, I am trying to run the example of ADS library but I am getting same error " ADS read error example: 1861", probably I am doing something wrong. It looks it get connection to the ADS server v2.11. I developed a tiny program running on TwinCATon Windows XP with IP:192.168.10.116. I changed the code in runExample:
static const AmsNetId remoteNetId {"192.168.10.116.1.1"}; // { 192, 168, 10, 54, 1, 1 };
static const char remoteIpV4[] = "192.168.10.116";
....
const AmsAddr remote { remoteNetId, 801 };
I created on TwinCAT very simple project with some DIs with address 0.0-0.7 (Port: 801, IGrp: 0xF021, IOffs:0x0, Len:1) and DI -Byte with address 0 (Port: 801, IGrp: 0xF020, IOffs:0x1, Len:1)

In the readExample I changed:
const long status = AdsSyncReadReqEx2(port, &server, 0xF020, 0, 1, &buffer, &bytesRead);

But I am getting the error mentioned all time. I tried also with 0xF021, 1, but same. I am able to ping TwinCAT computer, running it online, get connection but not read. I did also mapping, check configuration, activate configuration and get TwinCAT running.

Please below is the screenshot.
testing_ads
Thank you so much for any help

Reyan

Hardcoded frame size

: frame(4096),

Dear sir/madam,

We are using this library to interface with a Beckhoff PLC.
We would actually like to receive ADS results that are larger than 4096.

Therefore we were wondering why the frame size is hard coded to 4096?
Is it possible to extend it?

If it cannot be extended, what would be the preferred way to obtain an object from the PLC that is larger than 4096 bytes?

Thanks in advance for your response.

Best wishes,
Hugo van den Brand

Multiple Request/Response

Support for multiple requests (read/write) is missing. Implementing these would allow fast access to several variables.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.