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