Twincat ADS 事件驱动的读取在一段时间后停止工作(Java)

Posted

技术标签:

【中文标题】Twincat ADS 事件驱动的读取在一段时间后停止工作(Java)【英文标题】:Twincat ADS event driven reading stops working after a while (Java) 【发布时间】:2018-07-19 07:13:20 【问题描述】:

我们开发了一个 Java 应用程序,它使用 TwinCat ADS 库 (DLL) 来读取、写入和处理来自 Beckhoff PLC (CX5120) 的事件。 我们在几台机器上成功地运行了它,但不幸的是,我们目前遇到了事件处理突然停止的问题。 这是我们经历的确切场景:

正确处理读取、写入和事件。 突然间,我们再也没有收到任何事件,但读取和写入仍然正常工作。 更换了另一台PLC,再次开始正常工作。我们当时认为这是一个许可问题。 在无人值守运行一周后,同样的问题再次出现,PLC/ADS 库似乎不再触发事件,我们似乎无法以任何方式使其再次工作。读/写仍然可以正常工作。

在另一台装有 Java 应用程序的 PC 上进行了测试,同样的问题。所以 PLC 中的某些东西似乎冻结/停止工作。

以下是我们设置事件处理的方式:

// Implementation of the CallbackListenerAdsState interface
public class ADSEventController implements CallbackListenerAdsState 

......

// Register itself as listener for the ADS events (in constructor)
callObject = new AdsCallbackObject();
callObject.addListenerCallbackAdsState(this);

....

// Event handling
public void onEvent(AmsAddr addr, AdsNotificationHeader notification, long user) 
    log.info("Got ADS event for handle[] and with raw data[]", user, notification.getData());

......

// Registering notification handles for PLC variables
// If we already assigned a notification, delete it first (while reconnecting)
    JNILong notification = new JNILong();
if(var.getNotification() != null) 
    notification = var.getNotification();
    AdsCallDllFunction.adsSyncDelDeviceNotificationReq(addr,notification);


// Specify attributes of the notificationRequest
AdsNotificationAttrib attr = new AdsNotificationAttrib();
attr.setCbLength(var.getSize());
attr.setNTransMode(AdsConstants.ADSTRANS_SERVERONCHA);
attr.setDwChangeFilter(1000);   // 0.01 sec
attr.setNMaxDelay(2000);        // 0.02 sec

// Create notificationHandle
long err = AdsCallDllFunction.adsSyncAddDeviceNotificationReq(
    addr,
    AdsCallDllFunction.ADSIGRP_SYM_VALBYHND, // IndexGroup
    var.getHandle(), // IndexOffset
    attr, // The defined AdsNotificationAttrib object
    var.getHandle(), // Choose arbitrary number
    notification);
var.setNotification(notification);

if (err != 0) 
    log.error("Error: Add notification: 0x for var[]", Long.toHexString(err), var.getId());

【问题讨论】:

【参考方案1】:

我们设法找到了原因。 当我们注册一个变量时,我们会从 PLC 获得一个句柄(long),在我们的例子中,它在一段时间后意外地开始为负值。 我们也将此长值用作通知的用户引用,但是,我们发现用户引用在 ADS 库中是一个无符号长整数。

因此,如果我们设置负值,例如-1258290964 作为 adsSyncAddDeviceNotificationReq 调用中的“任意数字”,CallbackListenerAdsState onEvent 方法的参数“user”(Long)得到了我们有符号长用户引用的无符号长表示,即 3036676332。 在我们的 Java 应用程序中,我们使用此用户引用通过此句柄将事件与特定 plc 变量匹配。由于在我们的示例中,我们期望 -1258290964 但得到 3036676332,因此我们从未处理任何事件。

【讨论】:

请考虑将您的答案标记为已接受的答案。它可能会帮助未来有类似问题的访问者认识到是什么解决了您的问题。谢谢。

以上是关于Twincat ADS 事件驱动的读取在一段时间后停止工作(Java)的主要内容,如果未能解决你的问题,请参考以下文章

TwinCAT 3的基本功能

Pyads 读取通知值:当 TwinCat 循环发生时

如何从 TwinCat 读取包含结构数组的结构到 C#

通过 ADS.Net 将数组从 C# 发送到 TwinCat 3

twincat ads sample 怎么打开的

Twincat 运行模式错误 1861