Чтение, управляемое событиями Twincat ADS, через некоторое время перестает работать (Java)

Мы разработали Java-приложение, которое использует библиотеку TwinCat ADS (DLL) для чтения, записи и обработки событий из ПЛК Beckhoff (CX5120). Мы успешно запустили это на нескольких машинах, но, к сожалению, в настоящее время у нас возникла проблема, когда обработка событий внезапно останавливается. Это точный сценарий, который мы прошли:

  • Чтение, запись и события обрабатываются правильно.
  • Внезапно мы вообще больше не получаем никаких событий, хотя чтение и запись по-прежнему работают правильно.
  • Заменил ПЛК на другой, снова заработал успешно. Тогда мы предположили, что это проблема с лицензией.
  • После недели работы без присмотра та же проблема началась снова, библиотека PLC / ADS, похоже, больше не запускает события, и мы никак не можем заставить ее снова работать. Чтение/запись все еще работает как надо.

Протестировано на другом ПК с приложением Java, та же проблема. Значит что-то в ПЛК зависает/перестает работать.

Вот как мы настроили обработку событий:

// 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());
}

person Inth_TS    schedule 19.07.2018    source источник


Ответы (1)


Нам удалось найти причину. Когда мы регистрируем переменную, мы получаем дескриптор (длинный) от ПЛК, который в нашем случае через некоторое время неожиданно начал принимать отрицательные значения. Мы также использовали это длинное значение в качестве пользовательской ссылки для уведомлений, однако мы обнаружили, что пользовательская ссылка — это беззнаковое длинное значение в библиотеке ADS.

Поэтому, если мы установим отрицательное значение, например. -1258290964 в качестве «произвольного числа» в вызове adsSyncAddDeviceNotificationReq, параметр «пользователь» (Long) метода CallbackListenerAdsState onEvent получил длинное представление без знака нашей подписанной длинной ссылки на пользователя, которая равна 3036676332. В нашем приложении Java мы использовали эту ссылку на пользователя для сопоставления событие для определенной переменной ПЛК этим дескриптором. Поскольку в нашем примере мы ожидали -1258290964, а получили 3036676332, мы никогда не обрабатывали никаких событий.

person Inth_TS    schedule 19.07.2018
comment
Пожалуйста, подумайте о том, чтобы отметить ваш ответ как принятый ответ. Это просто может помочь будущим посетителям с похожими проблемами узнать, что решило вашу проблему. Спасибо. - person froeschli; 25.09.2020