Язык программирования FBDЯзык программирования FBD (Function Block Diagram) является составной частью стандарта IEC- 6. IEC- 6. 14. 99. Язык программирования FBD представляет собой графический язык, спроектированный для описывания процессов прохождения сигналов через разнообразные объекты. Язык FBD имеет сходство с электрическими схемами, потому инженеры- схемотехники, не имя опыта программирования, легко смогут составить на его базе электрическую схему системы управления. Язык программирования FBD оперирует различными функциональными блоками между входными и выходными переменными. FBD блоки представляют собой некую функцию, написанную на IL, SFC или других языках, а так же, из других блоков, которые могут быть многократно использованы в разных частях программы. Каждый FBD блок имеет графическое изображение, принятое при разработке функциональных схем электронных устройств.
Представлены они в виде прямоугольников и являются собой единичной операцией над входными переменными. Выходные контакты могут подключаться к выходным и внутренним переменным. Кроме того, можно передавать выходной сигнал на вход другому функциональному блоку или же функции. Переменные и входы соединяют специальными линиями связи. Эта линия и указывает распространение сигнала FBD программы . Идеология программирования на языке FBD подразумевает, что время исполнения каждой программы должно быть вполне определенным, т.
Функциональные блоки инкапсулируют данные и методы, чем подобны объектно- ориентированным языкам программирования, но они не поддерживают наследование и полиморфизм. Описание fbd элементов в целом схоже с описанием функций и методов в привычных языках программирования.
Информация из Wikipedia. FBD — графический язык программирования стандарта МЭК 61131-3. Предназначен для программирования .
К типовым FBD блокам относятся блок таймера, ПИД- регулятора, блок секвенсора, триггера, генератора импульсов, фильтра, и т.
Кроме того, имея перед глазами схему из пары десятков блоков, сложно сразу сообразить, что, как и для чего используется. Поэтому в данном примере будет применен несколько другой подход. Я постараюсь просто и наглядно показать, как сделать простейшую программу шаг за шагом, затратив при этом минимум времени и усилий.
И заодно подробно прокомментирую каждый шаг. В качестве примера была выбрана игра «Электроника ИМ- 0. Веселый повар». Под катом описание по шагам, как написать эту игрушку на языке программирования FBD.*Все большие картинки под спойлером имеют ссылку на оригиналы. Постановка задачи.
Итак, сегодня мы делаем игру «Веселый повар». Суть игры: повар подбрасывает четыре предмета. Задача состоит в том, чтобы вовремя подбежать к падающему предмету, подставить сковородку и снова подбросить его вверх. За каждое удачное подбрасывание начисляется одно очко. Скорость полета предметов увеличивается с количеством набранных очков.
Еще есть кот, который периодически ловит вилкой колбасу тем самым мешая повару. Если предмет падает на пол, то его хватает мышь и начисляется штрафное очко. После трех упавших на пол предметов игра прекращается.
Вот такая простая игрушка. Теперь будем ее реализовывать. Реализация. Шаг 1.
Чистый лист. Создаем контроллер и в нем новую задачу для реализации нашей игры. Шаг 2. Бегающий по полю повар. Теперь нам нужен повар, который по командам с операторской станции будет бегать по полю. Для реализации этого делаем простейшую схему: селектор будет подавать «команду 1» (для движения вправо) или «команду 2» (для движения влево); дальше ставим два блока «Выбор» и при наличии единицы на соответствующем выходе селектора передаем на выход выбора «1» для движения вправо и .
Таким образом получаем длительность команды в один цикл контроллера. Шаг 3. Сосиски и рыба. Теперь, когда у нас есть бегающий по полю повар, пора делать еду, которой он будет жонглировать. Тут тоже все стандартно: берем «Интегратор» и задаем на нем пороги верхний и нижний; к порогам подключаем обычный RS- триггер, по достижении верхнего порога взводим этот триггер и по достижению нижнего сбрасываем; к выходу RS- триггера подключаем алгоритм «Выбор», на котором будем выбирать скорость приращения интегратора. Ставим на вход «Если.
Да» отрицательное значение (верхний порог достигнут и интегратор должен пойти вниз) и на вход «Если. Нет» положительное; заводим с алгоритма «Выбор» обратную связь на «Интегратор»; к выходу интегратора подключаем алгоритм преобразования дискретного в целое, отбрасывая тем самым дробную часть; копируем эту схему еще три раза (т. Приделываем графический интерфейс. Раз повар у нас уже бегает по полю и еда прыгает, пришло время прикрутить простейшую графическую часть и посмотреть, как это будет выглядеть. Для отладки нам красота не нужна, поэтому делаем все максимально быстро и просто: Промежуточный итог.
Основа программы готова. На все затрачено минут пять.
Но текущая реализация только внешне похожа на желаемый результат. На самом деле играть в это невозможно, потому что предметы прыгают сами по себе и никогда не падают, а повар может уходить погулять за пределы поля.
Но это только основа. Начинаем надевать на наш скелет программы дополнительные опции, приближая ее к оригиналу. Ограничиваем повара. Как несложно заметить, в данный момент повар у нас управляется командами вправо- влево на единицу и может уходить куда ему заблагорассудится т. Но по правилам игры повар может занимать только одно из четырех положений и не может уходить за экран. Для реализации этого добавим повару рамки. Сделать это предельно просто и можно пойти двумя путями: при достижении поваром крайней правой или левой координаты («4» и «1» соответственно) заблокировать возможность нажатия на кнопку «вправо» или кнопку «влево»; при достижении поваром крайней правой или левой координаты («4» и «1» соответственно) запретить приращение или уменьшение сумматора, на котором мы храним текущую координату повара.
Просто повар дойдя в крайнее положение больше не реагировал на команду в ту же сторону. Реализуем его. Для этого поставим два алгоритма сравнения координаты с минимальным и максимальным возможным значением. И на алгоритм «Выбор» заведем команду не напрямую, как это было реализовано изначально, а через «И» с признаком соответствующего сравнения. Если повар находится на четвертой позиции, то условие «позиция меньше четвертой» уже не выполнится, и команда с селектора, перемножившись на алгоритме «И» с нулем, дальше не пойдет. Шаг 6. Повар подбрасывает еду.
Теперь добавим нашему повару возможность подбрасывать предметы. Как видно из основной схемы, сам предмет может занимать шесть положений.
Этого мы добились, когда отбросили дробную часть выхода интегратора и получили целые числа от нуля до пяти. Теперь вспоминаем, что подбрасывание предмета вверх у нас осуществляется путем сбрасывания триггера и выбора положительной скорости приращения интегратора. Изначально у нас триггер сбрасывался по достижению интегратором нижнего порога.
Но теперь мы уберем эту связь и поставим вместо нее простейшую схему: сложим по «И» положение повара и признак того, что координата предмета равна единицы (т. Если оба условия выполнились, то сбрасываем триггер и начинаем наращивать интегратор. Шаг 7. Добавляем анимацию повару. Если повар подбрасывает предмет, то он должен взмахнуть сковородкой снизу вверх. Для этого на нашем экране предусмотрено два варианта отрисовки повара на каждой позиции: вариант 1 — повар стоит с опущенной сковородой; вариант 2 — повар стоит с поднятой сковородой. Нужно чтобы анимация отрабатывала, во- первых, синхронно с подбрасыванием предмета, а во- вторых, занимала четко определенное и небольшое время. Попробуем представить, что же происходит в программе: предмет падает, т.
При этом повар должен поднять сковородку, чтобы получился визуальный эффект подбрасыванияно мы можем «подбросить» предмет как при значении на выходе интегратора 1,9. И решить ее очень просто. При выполнении условия (наша еда в первой координате т. Я предлагаю взять значение 1,8. Теперь вспоминаем, что когда значение на выходе интегратора превысит двойку, то подброшенный предмет перерисуется в новой (второй) координате, и нам нужно еще перерисовать повара с поднятой сковородкой. Но он не должен все время стоять с поднятой рукой, а должен отпустить ее через некоторое непродолжительное время.
Для этого мы поставим еще один алгоритм сравнения и будем сравнивать значение на выходе интегратора со значением 2,2. Таким образом по кодам 1,2,3 и 4 мы будет отрисовывать повара с опущенной сковородкой в позиции 1,2,3 и 4 соответственно, а по кодам 5,6,7 и 8 — с поднятой сковородкой в позиции 1,2,3 и 4 соответственно. Шаг 8. Прикручиваем счетчик. Тут вообще все просто.
У нас уже есть признак того, что повар подбросил предмет (обработанные по «И» два условия: координата предмета равна единице и координата повара соответствует номеру предмета). Выделяем фронт и заводим на сумматор, который по стандартной схеме обвязываем обратной связью через алгоритм «Выбор», чтобы иметь возможность обнулить показания сумматора по условию. Шаг 9. Кнопки «Старт» и «Стоп»Без них никак. Нужно, чтобы человек сказал контроллеру: «Вот сейчас я готов поиграть. Запускай игру!». А потом смог сбросить результат и вернуться к исходному положению.
Реализуем эту задачу. Вообще один селектор у нас уже есть (для управления поваром) и можно было бы использовать его, добавив еще третью и четвертую команду для старта и сброса соответственно. Но чтобы не загромождать схему сделаем отдельный селектор, управляющий игрой.
Точно так же заведем сброс по обратной связи через «ИЛИ» с первого и второго выхода. И поставим на выходе RS- триггер, который будем взводить по команде «Старт» и сбрасывать по команде «Сброс». Игра идет пока у нас триггер взведен.
Одновременно нужно по команде «Сброс» обнулить все счетчики в игре, а по команде «Старт» выставить исходное положение. Это просто, т. к. Одновременно по команде «Старт» выделяем фронт (сигнал длительностью в один цикл), и по этому фронту добавляем единичку к положению повара (тем самым устанавливая его в крайнее левое положение) и принудительно устанавливаем начальное значение координаты еды на интеграторах. Шаг 1. 0. Дорабатываем графику. У нас появились новые элементы в программе.
Внесем их в графическую часть и запустим игру. Как видно из картинки, повар у нас уже двигается только в ограниченном допустимыми позициями интервале, сковородку поднимает и еду подбрасывает. Все предметы тоже уже не прыгают сами по себе, а падают и больше не появляются, если повар не успел их поймать и снова подбросить в воздух. Так же работает счетчик количества успешных попыток повара подбросить очередной падающий предмет.
Это уже 8. 0% всего функционала игры, на который в сумме затрачено минут двадцать. И в эту игру уже можно играть.
Осталось реализовать всего несколько опций: паузу на время падения и перезапуск упавшего предмета; подсчет очков и выдачу сигнала «Game. Over» при превышении максимально допустимого числа ошибок; кота, ловящего колбасу; ускорение игры в зависимости от количества набранных очков. Ставим игру на паузу при падении предмета и перезапускаем упавший предмет. Предмет считается упавшим, если его координата равна нулю и одновременно приходит признак «Идет игра». Если оба этих условия выполнились, то выделяем фронт и по этому фронту взводим триггер «Упало». Биодека 5 Инструкция. Одновременно даем задержку на две секунды, спустя которые сбрасываем триггер «Упало».
Пока триггер взведен с помощью дополнительного алгоритма «Выбор» приравниваем нулю скорость приращения всех интеграторов, таким образом получая паузу в игре (Примечание: в игре пауза только для летающих предметов. Сам повар может двигаться в это время и занять удобную позицию для продолжения игры.
Это сделано специально для помощи игроку. Если нужно одновременно заблокировать и движение повара, то на алгоритмы «И», которые мы добавили, чтобы запретить повару выходить за пределы поля, добавляется еще один вход, куда заводится инверсный сигнал с триггера «Упало»).