Программирование привода стрелы шлагбаума ========================================= Начнем с программирования той части проекта, которая поднимает стрелу. Для этого применим стандартный функциональный блок триггер. Он имеет два устойчивых положения: включен или выключен. Переключение происходит по входам установки и сброса. Для начала просто вставим блок, затем нарастим соответствующую логику управления. Выберем на панели :guilabel:`Блоки` функциональный блок :guilabel:`RS-триггер` и перетащим его на схему: .. figure:: ../../zwb/lib/910.png :align: center Если необходимо добавить на схему несколько одинаковых блоков, то перетаскивать с панели блок необходимо с помощью правой кнопки мыши или удерживая одновременно кнопку :guilabel:`Shift`. В этом случае выбранный блок как бы ``«повиснет»`` на указатели мыши, и его можно вставлять неограниченное количество раз простым щелчком мыши на схеме. Для выхода из режима вставки блока надо нажать :guilabel:`Esc` или кнопку :guilabel:`Режим выделения` на панели рисования. Дважды щелкнем по вставленному блоку и откроем редактор свойств. Установим имя блока :guilabel:`RSBarrierUp` , поставим галочку в окне ``Вывод заголовка``, чтобы показывать название и нажмем кнопку :guilabel:`ОК` : .. figure:: ../../zwb/lib/5.png :align: center Начнем добавлять логику управления. Переменную :guilabel:`Action` подадим на вход ``S``. Для этого надо выделить её в списке переменных и ``«перетащить»`` на схему. На схеме добавится блок для управления переменной. Логическая переменная :guilabel:`Action` имеет значение 1, если управляющая кнопка шлагбаума нажата и удерживается. Все действия в нашей программе должны происходить четко при нажатии кнопки, то есть по переднему фронту сигнала. Чтобы детектировать его, используем соответствующий блок :guilabel:`Передний фронт`. Находим его в панели блоков (группа ``Битовые операции``) и вытаскиваем на схему. Далее соединяем соответствующие выходы связями. Для создания простой связи достаточно выделить нужный вход или выход блока и протянуть связь до нужного выхода или входа. Соединение выходов с выходами и входов с входами не допускается. После создания связей схема будет выглядеть следующим образом: .. figure:: ../../zwb/lib/step6.png :align: center Поскольку одной и той же кнопкой стрела и поднимается и опускается, то нужно как-то различать текущее положение и что делать дальше. Введем вспомогательную логическую переменную :guilabel:`NextUp`. Если она имеет значение 1, то стрела будет открываться. Объединим ее по логике :guilabel:`И` (**AND**) с переменной :guilabel:`Action`. Выберем в панели блоков элемент :guilabel:`И` группы ``Битовые операции`` и перетащим его на схему. Соединим элементы связями, как показано на рисунке: .. figure:: ../../zwb/lib/step7.png :align: center Следующим шагом мы подключим переменную :guilabel:`BarrierUp` привода стрелы к выходу ``Q`` блока :guilabel:`RS`. Для этого вытаскиваем нужную переменную на схему и так-как эта переменная должна записываться, меняем тип блока переменной на ``Запись``. Для этого надо двойным щелчком мыши вызвать окно редактирования свойств блока и выбрать нужный параметр: .. figure:: ../../zwb/lib/n_step6.png :align: center .. figure:: ../../zwb/lib/step9.png :align: center В нашей задаче определены три возможных причины останова процесса открытия стрелы. Поставим оператор :guilabel:`ИЛИ` (:guilabel:`OR`) с тремя входами, перед входом `R` блока :guilabel:`RS`. Этот оператор соберет все три причины на свои входы: Датчик :guilabel:`BarrierOpen` сообщает о достижении стрелы шлагбаума верхнего положения. Эта переменная уже объявлена и может быть подключена к одному из входов оператора :guilabel:`OR`, так как мы уже делали ранее. Пользователем нажата кнопка управления во время работы привода :guilabel:`BarrierUp`. Эта логика будет реализована блоком :guilabel:`И` (:guilabel:`AND`) с двумя входами: переменной кнопки :guilabel:`Action`, детектором переднего фронта и переменной :guilabel:`BarrierUp`. Ошибка движения. Она должна генерироваться при перегрузке привода стрелы, либо если процесс открытия/закрытия недопустимо затянулся. Переменная ошибки будет иметь название :guilabel:`Error`. Наша первая цепь готова: .. figure:: ../../zwb/lib/step10.png :align: center Вторая цепь будет отвечать за процесс закрытия ворот. Она будет сходна с первой. Давайте скопируем ее. Выделим ее, в меню редактирования выберем команду ``Копировать`` (или клавиши :guilabel:`Ctrl`+ :guilabel:`C`), затем команду ``Вставить`` (или клавиши :guilabel:`Ctrl`+ :guilabel:`V`). Вторая цепь появилась ниже первой. Переместим ее ниже первой и заменим переменные, отвечающие за открытие на переменные, отвечающие за закрытие. Замена переменных в блоках управления переменных делается в окне их свойств: .. figure:: ../../zwb/lib/step11.png :align: center Обратите внимание на то, в этой цепи нужно применить инверсное значение переменной :guilabel:`NextUp`. Добавим инверсию. Для этого выделим нужный вход, откроем его свойства и установим флажок ``Инверсия``. Инверсный вход будет отображаться с кружочком. Третья цепь нужна для установки вспомогательной переменной :guilabel:`NextUp`, отображающей направление движения. Новую цепь вставим ниже существующих. Затем вставим уже знакомый нам :guilabel:`RS` и назовем его :guilabel:`RSNextDirection`. Подключим переменную :guilabel:`NextUp` на выход этого блока. Направление предстоящего движения может быть предсказано по предыдущему движению. Так, если переменная :guilabel:`BarrierOpen`, отвечающая за поднятие стрелы, имеет задний фронт (перепад сигнала с 1 в 0), мы знаем, что процесс открытия успешно завершен. Следовательно, в дальнейшем стрела будет опускаться. В свою очередь, этот процесс завершится задним фронтом переменной :guilabel:`BarrierDown`. Эти переменные надо подать на входы блока :guilabel:`RS` через детекторы фронтов :guilabel:`Задний фронт`: .. figure:: ../../zwb/lib/step12.png :align: center Это все, что нам потребуется для управления шлагбаумом. Теперь осталось сделать управление лампой и контроль аварийных ситуаций.