我们开发了一个 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());
}