July 3, 2019

Дребезг на трех языках

Паттерны и шаблоны можно находить в любой системе и на любом языке программирования. У Скотта Витлока (Scott Whitlock) в блоге про автоматизацию есть любопытная подборка паттернов (или шаблонов) Patterns of Ladder Logic Programming на языке лестничных диаграмм, релейной логики или просто LD. Всё как в большом и кровавом энтерпрайзе с рейтингом R.


Обычно в проектах я использую ST и C# за редким исключением, когда возникает необходимость в других языках, поэтому было особенно интересно посмотреть как будет выглядеть один и тот же алгоритм на трех разных языках программирования МЭК. Я взял паттерн "Дребезг контактов" (Debounce) и переписал его на LD, ST и CFC.

FBD брать не стал, так как есть CFC, а это более продвинутая и современная версия блочных диаграмм. На картинке выше, адаптация паттерна на языке LD под TwinCAT 3. Про объявление переменных чуть позже.

Вообще проблему с дребезгом лучше устранять на уровне железа, но если что, то в модули дискретных входов уже встроены фильтры. Правда они не настраиваются и не отключаются, что заказано, то заказано. Поэтому, чтобы иметь возможность подкрутить время нечувствительности, я воспользуюсь готовым паттерном, и проверю его работу одновременно на трех языках программирования. Сразу и одновременно.


Continuous Flow Chart


Паттерн настолько простой, что перенос не должен вызывать затруднения, разве что расставить последовательность операций, ну и бывает трудно найти панель инструментов с кнопками элементов диаграммы. Она прячется во View → Toolbox (Ctrl + Alt + X). Она же хранит элементы для LD и прочих конструкторов.

Объявление переменных остается прежним. Забегая вперед, оно будет таким же и для LD.


Structured Text


LD легко транслируется на ST. Интересно, что шапка с объявлением переменных и ФБ остается по прежнему одинаковой для всех трех языков:

FUNCTION_BLOCK DebounceLD // DebounceST // DebounceCFC
VAR_INPUT
    IN: BOOL;
    Delay: TIME := T#50MS;
END_VAR
VAR_OUTPUT
    Q: BOOL;
END_VAR
VAR
    DelayOn: TON;
    DelayOff: TOF;
END_VAR

Копируем в программу на ST шапку с объявлением переменных, переименовываем название функционального блока в DebounceST и дописываем тело программы. Текст лаконичнее картинки, редкий случай когда лучше один раз прочитать, чем долго скользить взглядом по картинке. Хотя, на вкус и цвет...

DelayOn(IN := IN, PT := Delay);
DelayOff(IN := IN, PT := Delay);
Q := DelayOn.Q OR (Q AND DelayOff.Q);

Количество строк (равное трем) также совпадает с тремя "ступенями" лестничной диаграммы LD.


Испытания


Подвергнем три функциональных блока различным испытаниям. С помощью визуализации можно на глазок проверить правильно ли они зажигают и гасят лампочки, а с помощью цикла мы внезапно проверим какой же из языков быстрее:

PROGRAM MAIN
VAR
    DebLD : DebounceLD;
    DebST : DebounceST;
    DebCFC: DebounceCFC;

[...]

lastExecTime := _TaskInfo[1].LastExecTime;

Timer(IN := TRUE);
IF Timer.Q THEN
    Timer(IN := FALSE);
    state := SEL(state >= 3, state + 1, 0);
END_IF

FOR i := 0 TO 10000 DO
    CASE state OF
    1:
        DebLD ( IN := in, Delay := delay, Q => outLD  );
        
    2:
        DebCFC( IN := in, Delay := delay, Q => outCFC );

    3:
        DebST ( IN := in, Delay := delay, Q => outST  );
    END_CASE
END_FOR

На самом деле правильность работы я определял по цифровому осциллографу, там же случайно выяснилось, что один из языков незначительно проигрывает в производительности... Это все очень не точно и не имеет большого значения, но все-равно интересно:


Синяя линия отражает значение переменной state, нулевое значение которой соответствует пустому циклу (когда внутри цикла практически ничего не происходит). Заметен небольшой всплеск активности в момент работы CFC функционального блока.

Правда все это крутилось внутри ноутбука, а я сталкивался с ситуацией, когда рантайм настоящего контроллера отличался от рантайма на ноуте. Поэтому я специально перепроверил поведение на 32-х разрядном контроллере CX9020 под WinCE.

Ситуация аналогичная:

Только не воспринимайте эти результаты всерьез: языки все равно равноценны и равнозначны. Пишите на том, который вам нравится или удобен в каждом конкретном случае.

No comments

Post a Comment

Note: Only a member of this blog may post a comment.