TwinCAT 3: глобальный вызов метода без создания функционального блока в VAR-определениях?

Я хочу использовать глобальный метод для устранения дребезга цифровых входов, передав IO и желаемое время устранения дребезга методу и используя возвращаемое значение для установки Bool-Variable. Сам метод работает, но мне нужно создать функциональный блок для каждого входа. Я хотел бы дополнительно оптимизировать, устранив необходимость создания экземпляра.

Есть ли возможность настроить функциональный блок/метод, чтобы среда выполнения выделяла память и создавала экземпляр метода всякий раз, когда он вызывается?

METHOD NO : BOOL
VAR_INPUT
    IN  : BOOL;
    T       : TIME;
END_VAR
VAR_INST
    _timer  : TON;
END_VAR

_timer (IN := IN, PT := T);
IF _timer.Q
THEN
    NO := TRUE;
ELSIF _timer.ET < T
THEN
    RETURN;
ELSE
    NO := FALSE;
END_IF

Вызов:

debouncedInput := debounce.NO(digitalInput, T#500MS);

где Debounce — локальный экземпляр функционального блока.

Заранее спасибо за конструктивные ответы.


person momo0815    schedule 11.03.2021    source источник


Ответы (1)


Если я правильно понял ваш вопрос, то это невозможно.

Избавиться от инициализации можно только в том случае, если вам не нужно сохранять состояние переменных вашего метода между циклами. В этом случае вы можете использовать FUNCTION. Поскольку вы используете TON внутри своего функционального блока, экземпляр _timer должен быть доступен для следующего цикла. Это сохранение состояния возможно только при использовании его в файле FUNCTION BLOCK. Именно поэтому вы объявили _timer как VAR_INST. Объявление его как VAR не сработает, поскольку таймер будет повторно инициализироваться при каждом вызове метода NO.

Безотносительно к вопросу. Ваш метод NO делает то же самое, что вызов обычного TON. Не уверен, почему вы реализовали это таким образом, но я думаю, что вы также можете реализовать его с помощью таймера следующим образом:

PROGRAM Test
VAR
    timer : TON;
    digitalInput : BOOL;
    debouncedInput : BOOL;
END_VAR

timer(IN:=digitalInput, PT:=T#500MS, Q=>debouncedInput);

Или сохранить метод

METHOD NO : BOOL
VAR_INPUT
    IN  : BOOL;
    T       : TIME;
END_VAR
VAR_INST
    _timer  : TON;
END_VAR

_timer (IN := IN, PT := T);
NO := _timer.Q
person Roald    schedule 11.03.2021
comment
Спасибо за ответ. Я думал, что это невозможно. Как я уже сказал: я искал более удобный способ устранения дребезга входных данных. Если вы знаете какое-либо другое элегантное решение, дайте мне знать! Я думаю, что буду продолжать использовать метод с экземпляром для каждого ввода. - person momo0815; 18.03.2021
comment
Я предложил лучший способ, используя только таймер. Я не думаю, что есть способ без создания какого-то функционального блока для каждого входа, так как вам нужен отдельный таймер для каждого входа. - person Roald; 18.03.2021