4. Создание fbd программ.
Стандарт IEC-1131 на языки программирования управляющих систем специфицирует пять языков программирования.
Наиболее распространенным стал язык FBD (Function Block Diagram). Он отличается наглядностью, простотой и позволяет строить достаточно сложные процедуры из типовых функциональных блоков. Разработке программы управления на языке FBD посвящен урок 3.
Функциональные блоки
Функциональный блок — это графическое изображение вызова одной функции. Пример его изображения в TRACE MODE представлен на рис.8.
Вход блока может быть аргументом, константой или свободным. Первый вход, называемый RUN, управляет расчетом. Если он не свободен, то вычислений блок не производит. Выход блока соединяется с входами других блоков или подключается к соответствующим каналам базы данных. Входные аргументы блока также привязываются к каналам.
В режиме эмуляции рядом с каждым входом и выходом выводятся их значения.
Пример. Пид — регулятор
В уроке 3 рассматривается ПИД- регулятор с зоной нечувствительности и ограничениями выходного сигнала (рис.9)
Реализация ПИД- регулятора на языке FBD в системе Trace Mode представлена на рис.10
На вход арифметического блока вычитания поступают задание (AD) и текущее значение (AS) регулируемого параметра. Блок управления DZONE реализует функцию нечувствительности с зоной Dlt.
Выходное воздействие блока регулирования PID формируется по уравнению:
,
где: Q — выходное воздействие;
Inp, Inp1 — значения входа на текущем и предыдущем такте;
kp, ki, kd, — коэффициенты пропорциональной, интегральной и дифференциальной части
«Весёлый повар» на FBD шаг за шагом
Предыдущие статьи были о небольших проектах, сделанных по одному и тому же принципу:
- предложенная идея продумывалась в течение некоторого времени;
- общая задача разбивалась на несколько крупных блоков;
- каждый блок продумывался на предмет того, какие у него будут входные данные, какие выходные и как он должен эти данные обрабатывать;
- потом, когда все проблемы в уме были решены, быстро накидывалась сама программа;
- во время отладки правились незначительные ошибки и вносились небольшие коррективы;
- в конце прикручивалась графика и все готово.
В качестве примера была выбрана игра «Электроника ИМ-04 — Веселый повар».
Под катом описание по шагам, как написать эту игрушку на языке программирования FBD.
* Все большие картинки под спойлером имеют ссылку на оригиналы
Постановка задачи
Итак, сегодня мы делаем игру «Веселый повар».
Вот такая простая игрушка. Теперь будем ее реализовывать.
Реализация
Шаг 1. Чистый лист
Создаем контроллер и в нем новую задачу для реализации нашей игры.
Шаг 2. Бегающий по полю повар
Теперь нам нужен повар, который по командам с операторской станции будет бегать по полю. Для реализации этого делаем простейшую схему:
- селектор будет подавать «команду 1» (для движения вправо) или «команду 2» (для движения влево);
- дальше ставим два блока «Выбор» и при наличии единицы на соответствующем выходе селектора передаем на выход выбора «1» для движения вправо и «-1» для движения влево;
- суммируем выходы с алгоритмов «Выбор» на алгоритме «Сложение», который дополним обратной связью для получения интегрального значения команд;
- обратную связь заведем через алгоритм выбор заранее, чтобы впоследствии иметь возможность обнулять наш сумматор;
- собираем первый и второй выходы селектора по схеме «ИЛИ» и по обратной связи подаем на сброс селектора. Таким образом получаем длительность команды в один цикл контроллера.
Шаг 3. Сосиски и рыба
Теперь, когда у нас есть бегающий по полю повар, пора делать еду, которой он будет жонглировать. Тут тоже все стандартно:
- берем «Интегратор» и задаем на нем пороги верхний и нижний;
- к порогам подключаем обычный RS-триггер, по достижении верхнего порога взводим этот триггер и по достижению нижнего сбрасываем;
- к выходу RS-триггера подключаем алгоритм «Выбор», на котором будем выбирать скорость приращения интегратора. Ставим на вход «ЕслиДа» отрицательное значение (верхний порог достигнут и интегратор должен пойти вниз) и на вход «ЕслиНет» положительное;
- заводим с алгоритма «Выбор» обратную связь на «Интегратор»;
- к выходу интегратора подключаем алгоритм преобразования дискретного в целое, отбрасывая тем самым дробную часть;
- копируем эту схему еще три раза (т.к. предметов у нас четыре штуки).
Шаг 4. Приделываем графический интерфейс
Раз повар у нас уже бегает по полю и еда прыгает, пришло время прикрутить простейшую графическую часть и посмотреть, как это будет выглядеть. Для отладки нам красота не нужна, поэтому делаем все максимально быстро и просто:
Промежуточный итог
Основа программы готова. На все затрачено минут пять. Но текущая реализация только внешне похожа на желаемый результат. На самом деле играть в это невозможно, потому что предметы прыгают сами по себе и никогда не падают, а повар может уходить погулять за пределы поля. Но это только основа. Начинаем надевать на наш скелет программы дополнительные опции, приближая ее к оригиналу.
Шаг 5. Ограничиваем повара
Как несложно заметить, в данный момент повар у нас управляется командами вправо-влево на единицу и может уходить куда ему заблагорассудится т.к. по выходу стоит простой сумматор, не ограниченный ничем. Но по правилам игры повар может занимать только одно из четырех положений и не может уходить за экран. Для реализации этого добавим повару рамки. Сделать это предельно просто и можно пойти двумя путями:
- при достижении поваром крайней правой или левой координаты («4» и «1» соответственно) заблокировать возможность нажатия на кнопку «вправо» или кнопку «влево»;
- при достижении поваром крайней правой или левой координаты («4» и «1» соответственно) запретить приращение или уменьшение сумматора, на котором мы храним текущую координату повара.
Шаг 6. Повар подбрасывает еду
Теперь добавим нашему повару возможность подбрасывать предметы. Как видно из основной схемы, сам предмет может занимать шесть положений. Этого мы добились, когда отбросили дробную часть выхода интегратора и получили целые числа от нуля до пяти. Теперь вспоминаем, что подбрасывание предмета вверх у нас осуществляется путем сбрасывания триггера и выбора положительной скорости приращения интегратора. Изначально у нас триггер сбрасывался по достижению интегратором нижнего порога. Но теперь мы уберем эту связь и поставим вместо нее простейшую схему: сложим по «И» положение повара и признак того, что координата предмета равна единицы (т.е. он находится в нижней точке). Если оба условия выполнились, то сбрасываем триггер и начинаем наращивать интегратор.
Шаг 7. Добавляем анимацию повару
Если повар подбрасывает предмет, то он должен взмахнуть сковородкой снизу вверх. Для этого на нашем экране предусмотрено два варианта отрисовки повара на каждой позиции:
- вариант 1 — повар стоит с опущенной сковородой;
- вариант 2 — повар стоит с поднятой сковородой.
Попробуем представить, что же происходит в программе:
- предмет падает, т.е. значение на выходе интегратора уменьшается с какой-то постоянной скоростью;
- далее значение на выходе интегратора становится меньше двух, и это значит, что мы попали в зону, когда повар может снова подбросить предмет, подставив под него сковородку;
- при этом (вспоминаем шестой шаг) когда у нас выполняются оба условия (координата предмета равна единице и повар стоит в этой же позиции) и происходит сброс триггера, и начинается наращивание значения на выходе интегратора все с той же постоянной скоростью;
- как только значение на выходе интегратора станет больше двух, то предмет отрисуется в следующей координате. При этом повар должен поднять сковородку, чтобы получился визуальный эффект подбрасывания
- но мы можем «подбросить» предмет как при значении на выходе интегратора 1,99 (тогда через долю секунды он уже отрисуется в следующей координате), так и при значении на выходе интегратора 1,01 (тогда до отрисовки его в следующей координате придется ждать довольно долгое время);
- пока предмет не отрисовался во второй координате игроку непонятно, подбросил он его или нет.
Теперь вспоминаем, что когда значение на выходе интегратора превысит двойку, то подброшенный предмет перерисуется в новой (второй) координате, и нам нужно еще перерисовать повара с поднятой сковородкой. Но он не должен все время стоять с поднятой рукой, а должен отпустить ее через некоторое непродолжительное время. Для этого мы поставим еще один алгоритм сравнения и будем сравнивать значение на выходе интегратора со значением 2,2. далее по «И» соберем четыре признака:
- триггер сброшен и идет приращение координаты;
- повар находится в той же позиции;
- текущий выход интегратора больше 2;
- текущий выход интегратора меньше 2,2.
Шаг 8. Прикручиваем счетчик
Тут вообще все просто. У нас уже есть признак того, что повар подбросил предмет (обработанные по «И» два условия: координата предмета равна единице и координата повара соответствует номеру предмета). Выделяем фронт и заводим на сумматор, который по стандартной схеме обвязываем обратной связью через алгоритм «Выбор», чтобы иметь возможность обнулить показания сумматора по условию.
Шаг 9. Кнопки «Старт» и «Стоп»
Без них никак. Нужно, чтобы человек сказал контроллеру: «Вот сейчас я готов поиграть. Запускай игру!». А потом смог сбросить результат и вернуться к исходному положению. Реализуем эту задачу.
Вообще один селектор у нас уже есть (для управления поваром) и можно было бы использовать его, добавив еще третью и четвертую команду для старта и сброса соответственно. Но чтобы не загромождать схему сделаем отдельный селектор, управляющий игрой. Точно так же заведем сброс по обратной связи через «ИЛИ» с первого и второго выхода. И поставим на выходе RS-триггер, который будем взводить по команде «Старт» и сбрасывать по команде «Сброс». Игра идет пока у нас триггер взведен.
Одновременно нужно по команде «Сброс» обнулить все счетчики в игре, а по команде «Старт» выставить исходное положение. Это просто, т.к. алгоритмы «Выбор» по обратной связи на сумматорах мы предусмотрели заранее, а триггера сбрасываются подачей команды на вход «Reset». Одновременно по команде «Старт» выделяем фронт (сигнал длительностью в один цикл), и по этому фронту добавляем единичку к положению повара (тем самым устанавливая его в крайнее левое положение) и принудительно устанавливаем начальное значение координаты еды на интеграторах.
Шаг 10. Дорабатываем графику
У нас появились новые элементы в программе. Внесем их в графическую часть и запустим игру.
Как видно из картинки, повар у нас уже двигается только в ограниченном допустимыми позициями интервале, сковородку поднимает и еду подбрасывает. Все предметы тоже уже не прыгают сами по себе, а падают и больше не появляются, если повар не успел их поймать и снова подбросить в воздух. Так же работает счетчик количества успешных попыток повара подбросить очередной падающий предмет. Это уже 80% всего функционала игры, на который в сумме затрачено минут двадцать. И в эту игру уже можно играть. Осталось реализовать всего несколько опций:
- паузу на время падения и перезапуск упавшего предмета;
- подсчет очков и выдачу сигнала «GameOver» при превышении максимально допустимого числа ошибок;
- кота, ловящего колбасу;
- ускорение игры в зависимости от количества набранных очков.
Шаг 11. Ставим игру на паузу при падении предмета и перезапускаем упавший предмет
Предмет считается упавшим, если его координата равна нулю и одновременно приходит признак «Идет игра». Если оба этих условия выполнились, то выделяем фронт и по этому фронту взводим триггер «Упало». Одновременно даем задержку на две секунды, спустя которые сбрасываем триггер «Упало». Пока триггер взведен с помощью дополнительного алгоритма «Выбор» приравниваем нулю скорость приращения всех интеграторов, таким образом получая паузу в игре (Примечание: в игре пауза только для летающих предметов. Сам повар может двигаться в это время и занять удобную позицию для продолжения игры. Это сделано специально для помощи игроку. Если нужно одновременно заблокировать и движение повара, то на алгоритмы «И», которые мы добавили, чтобы запретить повару выходить за пределы поля, добавляется еще один вход, куда заводится инверсный сигнал с триггера «Упало»). По обратному фронту (когда сбросили триггер «Упало») одновременно сбрасываем триггер на выбор скорости интегратора и подаем команду на принудительную установку начального значения.
Шаг 12. Считаем упавшие предметы
Сигнал по упавшему предмету у нас уже есть (он взводит триггер «Упало»). По этому сигналу наращиваем на единицу счетчик упавших предметов. Заводим по стандартной схеме обратную связь на сумматор через выбор, чтобы иметь возможность обнулять счетчик (будем это делать по команде «Сброс»). Далее сравниваем значение на сумматоре с тройкой. При достижении максимального значения выставляем признак «GameOver» и запрещаем сбрасывать триггер «Упало» автоматически через две секунды. По «ИЛИ» разрешаем сброс этого триггера только командой «Сброс» с управляющего селектора.
Шаг 13. Добавляем кота, ловящего колбасу
Применим стандартную схему:
- Ставим интегратор с двумя произвольными порогами;
- По достижению верхнего порога взводим триггер и сбрасываем по достижению нижнего порога;
- Через выбор подаем положительную и отрицательную скорость приращения интегратора. Таким образом получаем постоянно меняющееся по «пиле» значение на выходе интегратора;
- Берем алгоритм текущего времени и делим на выход интегратора;
- Умножаем получившееся после деления значение на 10000 и делим с остатком на 1, тем самым получая отдельно целую и дробную часть;
- выбираем нужный нам шанс, что кот поймал колбасу. Допустим это 30%, т.е. сравниваем остаток с 0,3;
- складываем по «И» четыре признака: остаток меньше 0,3, колбаса перешла с 4 на третью позицию, есть признак «Идет игра» и триггер на выборе скорости интегратора «колбасы» взведен (на вход интегратора поступает отрицательное значение, т.е. колбаса падает вниз);
- по сигналу с алгоритма «И» взводим триггер «Кот» и запускаем таймер. На вход таймаута подаем остаток, умноженный на десять (т.е. случайное количество секунд от 0 до 3);
- по таймауту сбрасываем триггер «Кот»;
- сигнал с триггера «Кот» с инверсией подаем на алгоритм «Выбор», где еще раз выбираем скорость, подаваемую на вход интегратора «колбасы». Т.е. пока на выходе триггера «Кот» логическая единица, на вход интегратора подается ноль и предмет зависает в воздухе;
Шаг 14. Делаем увеличение скорости игры в зависимости от набранных очков
Это финальный штрих. Фактически у нас все готово. Скорость определяется на алгоритме «Выбор», где задается положительная и отрицательная скорости приращения (и уменьшения соответственно) выхода интегратора. По умолчанию мы выбрали какие то числа. Для реализации функции изменения скорости мы показание счетчика успешных попыток подбросить предмет делим на произвольный коэффициент (например 50), и получившееся значение прибавляем к заданному изначально. Таким образом получается, что чем больше у нас очков, тем быстрее будут подпрыгивать сосиски.
Шаг 15. Дорабатываем графику для финальной проверки
Т.к. у нас появились еще несколько важных сигналов, добавляем их на нашу картинку в упрощенном виде. Получается что то в этом роде:
Здесь уже полностью реализован игровой интерфейс. Только это сделано в схематичном виде. В принципе даже в такую игрушку уже можно играть. Разумеется будет реализована полноценная игра, но этот набросанный за пару минут интерфейс прекрасно справляется с функцией отладки и проверки правильности работы программы.
Шаг 16. Финальный вид техпрограммы и gif ее реализации по шагам
Шаг 17. Делаем красивую графику к игре
Для этого нам понадобится картинка из интернета. Берется любая красивая картинка с игрой «Весёлый повар». Режется на кусочки, и каждый объект (повар, сосиска, мышь и кот) оформляется отдельной картинкой. Далее эти картинки расставляются на поле. Макет графической части у нас уже есть. На нем мы отлаживали программу. Просто заменяем кружки и квадратики нужными картинками, а вместо анимации «изменение цвета» ставим анимацию «отображение». С вырезанием, редактированием и обработкой картинок пришлось повозиться. Подозреваю, что какой-нибудь фотошоп позволил бы сделать все это за 15 минут, но и в MS Paint за пару часов было нарисовано все что нужно.
Добавляем на картинку дополнительные кнопочки управления, счетчик очков и надпись «GameOver». Все готово, можно играть.
Шаг 18. Играем
* анимация сделана с частотой 1 кадр в секунду (т.к. скорость игры в начале довольно медленная) и воспроизведена с двойной скоростью.
Подведение итогов
В данной статье я постарался максимально наглядно показать процесс написания простейшей игрушки на языке программирования FBD. И вот игрушка готова. В программе использовано всего 133 алгоритма. Однако если внимательно шаг за шагом проследить процесс реализации программы, то можно увидеть, что часть алгоритмов не нужна. Сразу бросается в глаза что есть несколько лишних выделений фронтов т.к., как я говорил в самом начале, управление было реализовано с помощью селектора со сбросом по обратной связи. Т.е. исходная команда уже обладает длительностью один цикл, и выделять из нее фронт не имеет смысла.
Так же можно заметить, что основная часть программы состоит из четырех одинаковых последовательностей алгоритмов обработки четырех предметов. Исключение составляет только «вмешательство кота» а алгоритм обработки первой сосиски. Но все вмешательство заключается всего-навсего в одном дополнительном алгоритме «И» (который ставит на паузу полет сосиски при появлении признака, что ее подцепил вилкой кот). Т.е. всю эту последовательность можно свернуть в макрос, получив небольшой алгоритм с несколькими входными и выходными параметрами. Это существенно упростит (визуально) задачу а так же облегчит добавление нового функционала (т.к. изменения придется делать только в одном макросе, а не в четырех идентичных цепочках алгоритмов).
Вышеперечисленные доработки приведут нас к задаче, подобной предыдущим примерам. С точки зрения красивости и оптимальности вариант реализации программы из блоков был бы предпочтительнее, однако цель была показать реализацию задачи шаг за шагом.
Есть еще один интересный момент. В результате у нас получилась игра «Весёлый повар». Таких игр была целая куча: «Ну погоди!», «Охота», «Спасающиеся инопланетяне», «Тайны океана», «Хоккей», «Футбол» и т.д. Но все эти игры сделаны по одному и тому же принципу. Фактически менялась только графическая составляющая с минимальным изменением программы. Поэтому за пару минут из нашей программы можно реализовать любую желаемую.
Например «Ну погоди!». Перерисовывается графика. Это понятно. А с точки зрения алгоритма изменение одно: у нас предмет летит сначала снизу вверх, а потом падает обратно, а в «Ну погоди» движение только в одну сторону. Т.е. достаточно убрать RS-триггер и алгоритм «Выбор», отвечающие за скорость наращивания интегратора каждого предмета, и в место них поставить только отрицательную скорость и при появлении нового яйца устанавливать значение интегратора в максимум. Вот и все. Удаляем восемь алгоритмов, проводим восемь новых связей и игра «Ну погоди!» готова.
Язык программирования FBD¶
Редактор в zWorkbench предназначен для визуального построения сложных разветвлённых алгоритмов на языке функциональных блоков (Function Block Diagram, далее — FBD).
FBD — это графический язык программирования стандарта МЭК 61131-3, который предназначен для программирования микропроцессорных контроллеров (в частном случае — контроллеров Zentec). При программировании используются наборы библиотечных блоков и макросы (собственные блоки, также написанные на FBD). Любой FBD блок — это подпрограмма, функция или функциональный блок (И, ИЛИ, НЕ, триггеры, таймеры, математические операции и др.).
Общий принцип работы¶
FBD-программа — это программа для контроллера, создаваемая в FBD-редакторе.Программа, написанная на языке FBD представляет собой выражение, составленное графически из отдельных элементов. К выходу блока подключается следующий блок, образуя цепь. Внутри цепи блоки выполняются строго в порядке их соединения. Результат вычисления цепи записывается во внутреннюю переменную, либо подается на выход ПЛК.
Программа, написанная на языке FBD представляет собой выражение, составленное графически из отдельных элементов. К выходу блока подключается следующий блок, образуя цепь. Внутри цепи блоки выполняются строго в порядке их соединения. Результат вычисления цепи записывается во внутреннюю переменную, либо подается на выход ПЛК.
Пример программы в Редакторе :
Пример программы: значение переменной Var1 умножить на значение переменной Var2 ; к произведению прибавить значение переменной Var3 ; полученный результат записать в переменную result .
Основные функции редактора¶
Редактор в zWorkbench предоставляет разработчику FBD программ обширный набор библиотек, инструментов и интерактивных систем, которые в совокупности обеспечивают выполнение следующих функций:
Визуальное проектирование программы для контроллеров Zentec:
- выбор и установка на сцену функциональных блоков;
- изменение свойств блоков и свойств входов-выходов;
- трассировка связей между блоками;
- ручное и автоматическое распределение переменных в памяти контроллера;
- рисование на поле программы примитивов (эллипс, линия, прямоугольник);
- вставка текстовых комментариев.
Симуляция и отладка FBD программы:
- проверка программы на содержание ошибок с выдачей результатов проверки в окно Сообщения ;
- симуляция на ПК без подключенного контроллера;
- отладка сетей, виртуализация реальных сетей с неограниченным количеством узлов;
- смешанная отладка — подключение к симулятору реальных приборов, реальных и виртуальных сетей в любых сочетаниях;
- отладка в симуляторе и контроллере по шагам;
- отладка в симуляторе и контроллере по точкам остановки и событиям;
- установка констант на входы блоков “на лету”.
Поиск и диагностика:
- поиск и подключение к сети контроллеров, даже при наличие мастера сети;
- остановка мастера сети и подключение к нему;
- идентификация контроллера: номер в сети, модель контроллера, версия программного обеспечения контроллера;
- обновление и восстановление программного обеспечения контроллера.
- копирование, вставка, отмена/повтор действий, масштабирование сцены;
- навигатор проекта;
- проектирование штампов и рамок, их вставка в печатные формы, автоматическая нумерация листов проекта;
- печать всего проекта или его части;
- создание цветовых схем;
- отладка и проектирование в многооконном режиме;
- экспорт переменных в XML формат.
Порядок выполнения блоков¶
Программа, создаваемая пользователем, представляет собой набор схем. В самом простом случае это одна схема. Схема указывает, каким образом выходы устройства зависят от внешних и внутренних данных. Каждая схема состоит из блоков и связей между блоками, а также имеет набор переменных величин, читаемых и записываемых схемой. Блоки выполняют функции взаимодействия между своими входами и выходами: от элементарных логических И, ИЛИ, НЕ до очень сложных. Некоторые виды блоков, кроме вычисления значений выходов, выполняют специальные задачи, например, блок Запись в переменную изменяет значение переменной, присваивая ей значение, полученное на входе. Выполнение блоков происходит последовательно, в порядке следования связей от выходов к входам, т.е. любой блок получает на входы обновленные значения, предварительно рассчитанные соответствующими блоками.
От визуального расположения блоков на схеме их выполнение не зависит, т.е. пользователь может располагать блоки так, как ему удобнее их видеть:
Диаграмма 1 и Диаграмма 2 будут исполняться абсолютно одинаково:
- сначала будет обработан Счетчик ;
- затем Детектор фронта ;
- и последним будет обработан RS триггер .
Циклические связи¶
Связывание блоков требуется выполнять таким образом, чтобы было возможно расположить их в линейную последовательность выполнения.
Циклические связи не допускаются, т.к. они приводят к возможности неоднократного изменения значений входов-выходов блоков, т.е. гарантированное завершение выполнения схемы с обновлением значений входов-выходов невозможно. На диаграмме 1 показана циклическая связь:
Такие связи недопустимы.
Правило запрета циклических связей имеет исключение: есть блоки (например, Счетчики ), внутри которых выходы не имеют прямой связи с входами. Такие блоки, если они включены в циклическую связь, разрывают ее внутри себя, поэтому такая связь разрешена:
На Диаграмме 1 и 2 показаны блоки с псевдоциклическими связями.
Главный цикл, статическая и временная память¶
Шаги схемы выполняются в бесконечном цикле – главном цикле программы устройства.
Данные от последних (в последовательности выполнения) блоков могут быть прочитаны первыми блоками, если эти данные будут записаны в переменные схемы. Переменные, создаваемые пользователем, и специальные переменные устройства являются памятью, хранимой в течение всего времени работы устройства. Далее эту память будем называть «статической».
Для значений входов и выходов блоков, память устройства выделяется и освобождается по мере необходимости, — это «временная» память. Выполнение схемы в целом с точки зрения внешних систем является неделимым шагом, т.е. невозможно прочитать из устройства или увидеть на его выходах данные, обновленные частично. Если какие-либо блоки прерывают выполнение схемы, это прерывание гарантированно выполняется до записи в статическую память. Операции обновления значений физических входов-выходов устройства и обмена данными по каналам связи выполняются между шагами выполнения схемы:
На Диаграмме 1 показан полный цикл исполнения программы на примере кнопки-защелки: каждое нажатие кнопки DIN1 меняет состояние выхода DOUT1 . Блоки пронумерованы в порядке их исполнения.
Рассмотрим полный цикл работы примера по шагам:
- опрос состояния DIN1 . Передача результата с выхода DIN1 на вход D блока Raise ;
- операция в блоке Raise . Передача результата с выхода F на вход C блока D-trigger . Так же чтение блока D (переменная). Передача результата с выхода блока D на вход D блока D-trigger ;
- операция в блоке D-trigger . Чтение выходов Q и
Таким образом, переменная D “разрывает” циклическую связь.
Если рассмотреть пошаговую работу схемы в симуляторе, то при “включении питания” (начало симуляции) в первом шаге в переменной D записано значение 0 :
Во втором шаге значение переменной меняется:
Другими словами, с момента команды записи до момента изменения переменной проходит один цикл программы, то есть происходит задержка на один цикл.
Цикл программы и Базовый таймер¶
Шаги схемы выполняются гарантированно, т.е. значения выходов гарантированно поступают на соответствующие входы; блоки гарантированно выполняют расчеты. В отличие от электронных схем, где каждый элемент имеет временные задержки в работе и может пропустить значения входов, схема FBD работает в общем дискретном времени, где каждый шаг полного расчета схемы соответствует одной единице дискретного времени. А каждая единица дискретного времени схемы соответствует какому-то интервалу физического времени.
Длительность этого интервала зависит только от скорости работы устройства, настройка такого соотношения в системе Редактора отсутствует. Устройство выполняет шаги с максимально возможной скоростью.
При некоторых условиях устройство может быстрее или медленнее выполнять расчет, т.к. схемы при программировании устройства автоматически оптимизируются, чтобы устройство не выполняло расчеты, не нужные в данном шаге.
Гарантия срабатывания блоков в каждом шаге позволяет использовать следующую особенность: многие логические значения выходов, сигнализирующие о возникновении события, работают по принципу «одиночного срабатывания». Это значит, что такой выход выдает 0 в течение большинства шагов выполнения схемы. Только при возникновении события он выдает 1, в течение только одного шага выполнения схемы, а на следующих шагах снова выдается 0. Такая одиночная 1 только в течение одного шага (в течение одной единицы дискретного времени) обязательно будет обработана соответствующими блоками. Само собой разумеется, что если такой выход подключить к физическому дискретному выходу устройства – он будет включаться на время 1 шага схемы, который может длиться от 100 мксек до 1000 мсек, что неправильно, т.к. внешние системы не должны быть зависимы от времени выполнения шага устройства. Поведение таких выходов удобно тем, что для них передний фронт и уровень – одно и то же, при необходимости иметь передний фронт можно просто использовать этот выход, без анализа фронта.
Для синхронизации с реальным временем используется блок Таймер , работа которого определяется Базовым таймером системы. Любое количество блоков Таймер используют один аппаратный Базовый таймер устройства, настраиваемый на определенный постоянный интервал срабатывания. Базовый таймер — это интервал времени, за который гарантированно успевает выполниться вся программа контроллера без учета оптимизации.
Важно понимать:
- цикл системы всегда динамический. Система внутренней оптимизации будет стремиться выполнить программу за минимальное время;
- базовый таймер задает интервал времени, которому кратны все пользовательские таймеры;
- если время динамического цикла выполнения программы будет больше времени базового таймера, то устройство выдаст ошибку.
Работа системы внутренней оптимизации¶
Работа системы внутренней оптимизации основана на динамическом предоставлении ресурсов для выполнения задачи.
Следующий пример поясняет работу этой системы.
Например, необходимо однократно считать данные из подчиненного устройства. На Диаграмме 1 представлена реализация этой задачи:
Блок чтения сетевой переменной 0h производит чтение, так как локальная переменная rdy имеет значение по умолчанию 1 . После успешного чтения на выходе rdy блока чтения появляется уровень лог. 1 , который записывает в локальную переменную rdy уровень лог. 0 (константу 0 на входе переменной). В следующем цикле переменная rdy запрещает работу блока чтения переменной 0h . Это состояние будет до следующего включения питания контроллера.
Очевидно, что данный пример работает несколько циклов после включения питания, а далее состояние блоков не меняется вплоть до сброса питания контроллера. Система внутренней оптимизации анализирует состояние входов и выходов этой программы и, после считывания переменной 0h исключает всю цепь из цикла программы. Остается только значение переменной SET , которое было получено при считывании переменной 0h .
Типы данных. Преобразование данных¶
Пользователю предоставляется возможность оперировать со следующими типами данных:
Типы данных выбираются в свойствах блоков, входов/выходов макросов и переменных:
Редактор в zWorkbench преследует цель достижения однозначности поведения устройства при любых входных данных. Для определенности значений входов, связанных с выходами, имеющими отличный тип данных, имеется требование: тип данных выхода должен быть подмножеством типа данных входа. Если для какой-либо связи это требование является ненужным или недостижимым – пользователь должен вставить блок Преобразование данных в разрыв этой связи. Вход этого блока принимает данные любого типа. Опции этого блока позволяют определить его поведение при наличии значения, не попадающего во множество значений требуемого типа данных. Блоки, значения выходов у которых могут выходить за диапазон значений типа данных (переполнение при математических операциях), имеют опции, определяющие их поведение:
Макросы¶
Для удобства пользователя, разделения задач на подзадачи или многократного использования подпрограмм в проекте, имеется возможность создания макросных схем.
В таком случае в проекте имеется несколько схем, одна из которых является главной. Главная схема выполняется, выполняя другие (макросные) схемы при наличии в главной схеме соответствующих (макросных) блоков, ссылающихся на макросные схемы. Макросные схемы также могут содержать макросные блоки, т.е. макросы могут быть вложены. Однако вложение схемы в саму себя (рекурсия), прямая или косвенная, не допускается. Макросная схема также может содержать переменные, хранимые постоянно (постоянную память макроса). Если макросная схема использована в проекте неоднократно (имеется несколько блоков, использующих ее), каждый макросный блок имеет независимый от других блоков набор переменных. Логика работы устройства не изменится, если какие-либо блоки схемы перенести в макросную схему, и заменить их в главной схеме на макросный блок, или наоборот – заменить макросный блок на блоки, содержащиеся в макросной схеме. От такой замены может незначительно измениться только скорость работы схемы и количество использованной памяти устройства, из-за различно выполняемой оптимизации схемы.
Работа с постоянной памятью контроллера (ППЗУ)¶
Все переменные проекта располагаются в области оперативной памяти (ОЗУ) и имеют свойство Сохранение в ПЗУ . Физически, при активном свойстве, данные из ОЗУ копируется (записывается) в ПЗУ.
Запись переменных в энергонезависимую память выполняется устройством между шагами расчета схемы. Если переменная в ОЗУ изменяется с высокой частотой, а устройство будет производить запись безусловно, то из-за ограниченного количества циклов перезаписи, ППЗУ будет испорчено через некоторое время работы.
Такая проблема решается следующим образом – пользователь должен установить на схему блок Запись переменныx и подать на его вход признак необходимости записи. Его можно формировать либо по таймеру, либо по событию изменения переменной (если переменная изменяется не часто), или по другому событию:
На данной диаграмме показан способ записи значения из ОЗУ в ПЗУ. Когда в переменную Set_temp мастер сети произведет запись, на выходе rdy появится фронт, который будет подан на вход en блока EEPROM . Этот сигнал произведет инициализацию записи всей памяти устройства.
Пользователь должен рассчитать максимальную частоту записи переменных, исходя из количества циклов перезаписи ППЗУ. Событие записи изменившегося значения переменной не должно происходить с большей частотой.
Перед записью переменной ее значение считывается из ППЗУ, запись выполняется только при неравенстве значений в ОЗУ и ППЗУ.
FBD-программа¶
FBD-программа, кроме набора схем, содержит опции, управляющие ее выполнением и работой контроллера в целом. Для просмотра и изменения опций нужно нажать правую кнопку мыши на соответствующем элементе дерева проекта и выбрать пункт Свойства в выпадающем меню.
Имеются следующие опции:
Группа опций “Сохранение переменных в ПЗУ”¶
Сохранение переменных в ПЗУ (Постоянное Запоминающее Устройство, электрически стираемая энергонезависимая память) используется для хранения измененных значений переменных при выключенном питании контроллера. В связи с тем, что количество, сколько можно раз записывать в ПЗУ, ограничено (обычно от 10^6. до 10^12 раз), и что в течение записи происходит пауза в выполнении программы, запись нельзя выполнять постоянно. Если запись выполнять несвоевременно, то при неожиданном выключении питания контроллера последние изменения значений переменных будут утеряны. Поэтому пользователь должен создать в FBD-схеме блок Запись переменных и подать на него логический сигнал о команде выполнения записи. Другой вариант — установка опций автоматического выполнения записи при определенных событиях.
Флажок “Периодически:” и соответствующее ему количество секунд¶
При установке этого флажка FBD-программа будет автоматически выполнять запись в ПЗУ всех переменных, у которых включена опция Сохранение в ПЗУ , периодически с указанным периодом. Таким образом гарантируется, что при выключении питания контроллера будут сохранены значения на какой-то момент времени, и этот момент был не больше, чем указанное время до выключения питания. При создании новой программы этот флажок включен, период записи установлен 10 секунд.
Флажок “Периодически:” и соответствующее ему количество секунд¶
При установке этого флажка FBD-программа будет автоматически выполнять запись в ПЗУ всех переменных, у которых включена опция Сохранение в ПЗУ , периодически с указанным периодом. Таким образом гарантируется, что при выключении питания контроллера будут сохранены значения на какой-то момент времени, и этот момент был не больше, чем указанное время до выключения питания. При создании новой программы этот флажок включен, период записи установлен 10 секунд.
Флажок “По команде записи по сети”¶
При установке этого флажка FBD-программа будет автоматически выполнять запись в ПЗУ всех переменных, у которых включена опция Сохранение в ПЗУ , непосредственно после записи любой из таких переменных через сетевой интерфейс контроллера. Эта опция позволяет сохранять значения переменных, если они изменяются только через сетевой интерфейс. Изменения переменных, вызванные непосредственно из FBD-программы контроллера, с помощью этой опции могут быть записаны только случайно, при команде записи по сети другой переменной. Внимание! Включение этого флажка может привести к ошибке выполнения программы, если через сетевой интерфейс будут поступать команды записи переменных с высокой частотой. При создании новой программы этот флажок включен.
Блоки¶
В данном разделе представлено описание функциональных блоков, поддерживаемых программой.
Описание блока¶
Блок представляет собой прямоугольник, имеющий входы и/или выходы. Входы располагаются слева, выходы справа:
Количество входов и выходов ограничено, оно зависит от типа блока и его свойств.
Каждый вход и выход имеет имя, которое расположено внутри прямоугольника, являющегося границей блока, около левой и правой границ соответственно. Все блоки, используемые в программе, можно разделить на группы:
- Функциональные блоки — это программный объект, который представляет специализированную функцию управления, используемую в управляющих системах.
- Макросные блоки – блоки, содержащие в себе макросную схему (подпрограмму), реализующую определенную задачу. Макросы, как и блоки, выполняют функцию взаимодействия между своими входами и выходами. Но эта функция взаимодействия сложнее, чем у функциональных блоков, и состоит из совокупности отдельных элементарных функций, реализуемых блоками.
- Блоки входы/выходы макросов – содержатся в макросных схемах для определения состава входов и выходов макросных блоков. Они также задают имена, типы данных и другие свойства входов/выходов.
Редактирование свойств блока¶
У каждого блока, созданного на сцене проекта, существует набор изменяемых свойств, который помогает разработчику настроить блок под свои требования и задачи, а также для облегчения понимания функции блока в разрабатываемом проекте.
Вызов свойств блока осуществляется либо нажатием ПКМ по блоку и выбора пункта Свойства , либо нажатием комбинации клавиш клавиатуры Alt + P .
После осуществления перехода к свойствам блока появится новое окно с набором изменяемых параметров. Набор свойств у каждого блока отличается.
Основные параметры, которые есть у всех блоков, перечислены ниже:
- Название: пользовательское название блока для упрощения дальнейшей навигации по программе.
- Описание: текстовое описание назначения блока или любая другая информация для удобства работы пользователя в системе.
- Блокировка: флаг блокировки возможности перемещения этого блока по сцене проекта.
- Вывод заголовка: в случае установки флага имя блока из параметра “Название” будет отображаться над блоком на сцене программы.
Представлены свойства блока Запись в ПЗУ (подробнее см. Блоки чтения-записи ПЗУ ):
Как видно из изображения, в данном наборе параметров представлена возможность менять название блока, его описание, блокировать его перемещения по сцене проекта, что служит для облегчения понимания функции блока в разрабатываемом проекте, а также тип данных записываемой переменной, что уже относится к свойствам по настройке блока под выполнение определенных задач и требований.
Для облегчения изучения используемых блоков функций в zWorkbench, в описании каждого из блоков представлено также описание и его свойств.
В самом верху окна свойств блока создан фильтр, который помогает выделить только то свойство, которое требуется разработчику:
А для настройки отображения окна свойств представлен соответствующий пункт в правом верхнем углу этого окна:
В данном пункте представлена возможность отображения расширенных свойств блока, если таковые имеются, сортировку свойств по алфавиту, а также внешний вид структуры отображаемых свойств.
Кроме того, каждая “ножка” блока также имеет свои свойства, которые вызываются также как и свойства блока, только при этом необходимо выделить интересующую “ножку”:
В представленном на изображении окне предоставляется возможность подать константу на вход, а в математических операциях выбрать тип операции на “ножке”, а также формат числа, или же, в некоторых блоках, тип входа: прямой, инверсный, передний фронт, задний фронт.
Блоки обработки переменных¶
Для хранения данных между “шагами” программы используются переменные величины, или просто переменные. Переменная постоянно занимает в памяти устройства требуемый объем памяти, который задается пользователем. Для обмена данными с переменными имеются соответствующие блоки. Этих блоков нет в окне Блоки , для их создания на сцене программы необходимо перетащить соответствующую переменную в Вашу схему. Созданный блок имеет те же параметры, что были заданы при создании переменной. При перетаскивании пользовательской переменной на сцену, тип блока зависит от точки, в которую перетаскивается переменная и где отпущена кнопка мыши. Если это место – вход блока: создается блок чтения, связанный с этим входом. Если эта точка – выход блока: создается блок записи, связанный с этим выходом. Иначе – создается несвязанный блок чтения.
Переменные, создаваемые пользователем, могут быть считаны и записаны произвольным образом. Однако, каждое устройство имеет специальные переменные, например, переменные, связанные с физическими входами-выходами устройства. Специальные переменные могут иметь ограничения, например, может быть разрешено только чтение или только запись. Блоки чтения-записи специальных переменных устройства имеют несколько иной внешний вид, но логика работы таких блоков полностью совпадает с блоками чтения-записи пользовательских переменных.
Свойства блока переменной¶
Общие свойства: Редактирование свойств блока.
Тип: в этом пункте осуществляет выбор типа блока, работающего с переменной (чтение, запись, условная запись, запись MODBUS).
Чтение после записи: значение выхода блока чтения, также как и любого другого выхода, фиксировано на каждом шаге выполнения программы в зависимости от свойства Чтение после записи : если флаг не установлен (по умолчанию) — блок чтения выполняется гарантированно до блоков записи соответствующей переменной. В таком случае значение, записанное в переменную условно на первом шаге, будет прочитано блоком чтения на втором шаге выполнения схемы. Если флаг Чтение после записи установлен — блок чтения выполняется гарантированно после блоков записи соответствующей переменной.
Приоритет записи: данный параметр задает приоритет записи при возникновении спорных ситуаций.
Переменная: в данной графе осуществлена возможность выбора или изменения переменной, с которой будет работать созданный блок.
Блок чтения переменной¶
Описание: считывает значение переменной, выдает значение на выход.
Количество блоков чтения одной переменной не ограничено, при этом значения всех блоков чтения с одинаковыми свойствами одинаковы.
Блок записи переменной¶
Описание: записывает значение в переменную, поданное на вход.
Для каждой переменной в проекте может быть только один блок записи, в противном случае появляется неопределенность, какое значение требуется записать. Если необходимо записывать значение одного из нескольких выходов, следует использовать блок Условие или Мультиплексор для явного выбора требуемого значения. Блоки записи переменных выполняются гарантированно после блоков чтения соответствующей переменной и после блоков, которые могут прервать шаг программы. Блоки записи не выполняются при отладке схемы в устройстве, в режиме паузы. Блок записи может быть условным, при наличии дополнительно входа en . Такой блок записи выполняется, если значение входа en равно 1. По умолчанию вход en равен 1:
Блок “Запись Modbus”¶
Описание: этот блок позволяет, в режиме подчиненного устройства Modbus, обработать команду записи, полученную от главного устройства. Выходы val и rdy выдают значение, полученное от master-устройства, и признак окончания передачи нового значения, соответственно. При отсутствии команды записи от “главного”, эти выходы выдают 0. Значения выходов блока зависят только от главного устройства, выходы можно связывать с входами того же блока (циклическая связь разрывается внутри блока). Этот блок выполняет сначала обработку выходов, затем, в конце шага схемы – обработку входов. Внимание! Не следует путать значение, полученное в команде записи, со значением переменной! Выход val не выдает значение переменной. Входы val и en обрабатываются независимо от других входов-выходов блока, являясь фактически отдельным блоком условной записи. Как уже было сказано выше, блок записи выполняется в конце шага схемы, эти входы можно связать с выходами val и rdy соответственно. При таком связывании значение, поданное на вход val c одноименного выхода, будет записано как только такая команда будет получена с выхода rdy и передана на вход en :
По сути, это та же условная запись переменной. Но данный блок объединяет в себе три операции: блок Чтения (если выход val получает значение в режиме подчиненного устройства Modbus, то на выходе rdy устанавливается логическое значение 1, признак получения команды записи), блок Условной записи (на вход val записывается обработанное значение, при условии, что вход en получил логическое значение 1) и блок Вывода ошибки err . Обработка значения переменной выполняется согласно поставленной задаче.
Пример: записать в переменную VAR4 значение X, если на выход val получено X < 20. Во-первых, сравниваем X с числом 20 ( Блок сравнения ), во-вторых, чтобы запись значения произошла, нужно, чтобы на входе en была установлена 1. Для этого выход Блока сравнения и выход rdy объединим блоком AND , а выход блока AND соединим со входом en , значение на выходе val соединим со входом val . Итак, если два условия истинны, то в переменную VAR4 будет записано значение, полученное на выходе val :
Но есть еще блок вывода ошибки err . Если значение, поданное на выход val не удовлетворяет условию блока сравнения , то на выходе блока AND установится 0, и вход en получит 0, а вход err должен выдать номер ошибки, почему не произведена запись в переменную. Ошибка 03 – неверные данные запроса. При получении на вход if 1 блок Условие подаст на вход er 0, в противном случае вход err получит номер ошибки 3.
Использовать различные способы записи переменных при разных условиях задачи.
- Просто записать значение в переменную;
- Условная запись. Если на вход en подана 1, то запись произойдет.
- Запись по MODBUS. Если полученное значение предварительно требуется обработать (сравнить, изменить, проверить на соответствие каким-то условиям).
Переменные, имеющие возможность записи по сети, всегда имеют на схеме блок Запись Modbus . Если пользователь его не создал, он создается неявно, как указано на рисунке. Блок с таким связыванием выполняет безусловную запись полученного значения от главного устройства в переменную. Если пользователь хочет проверить записываемое значение на корректность, заменить его или совсем не выполнять запись при каких-либо условиях, он должен вместо указанных связей создать цепь блоков, проверяющую и заменяющую значения требуемым образом. Вход err предназначен для возврата главному устройству кода ошибки в ответ на команду записи. Этот вход имеет уникальную особенность – если команда записи имеется (выход rdy равен 1) и на вход подано ненулевое значение, устройство прекращает выполнять шаг схемы. Обработка входа err всегда выполняется до всех блоков записи в переменные, и переменной этого блока, в том числе. Поэтому команда записи, в таком случае, не выполняется. Т.к. входы val и en записывают значение в переменную, этот блок записи может быть только один на сцене, и не может быть других, в том числе обычных, блоков записи той же переменной.
Битовые операции¶
Блок И¶
Описание: функция “И” анализирует значения на входах и генерирует результат на выходе, подчиняясь правилу булевого умножения:
Если блок логической функции “И” имеет несколько входов, тогда для получения на выходе 1, значения каждого входа должны быть равны 1, в противном случае результат на выходе функции будет равным 0.
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: несмотря на возможность выбрать в выпадающем меню все типы данных, данная функция работает ТОЛЬКО с логическими и целыми беззнаковыми типами данных. В случае выбора иного типа данных, редактор допустит соответствующее изменение, однако при компиляции программы будет выдана ошибка.
Количество входов: в данном пункте предоставляется возможность изменения количества входов соответствующего блока.
В случае, если тип данных отличается от логического, происходит побитовая операция “И”. Данное свойство позволяет выделять определенные биты из переменной. Например, для значений на входах 5(101) и 3(011) результат логической операции будет равен 1(001), т.е. из значения 5 были выделены первые 2 бита.
Блок ИЛИ¶
Описание: функция “ИЛИ” анализирует значения на входах и генерирует результат на выходе, подчиняясь правилу булевого сложения:
Если функция “ИЛИ” имеет несколько входов, то для получения “1” на выходе необходимо, чтобы значение любого из входов было равно “1”. На выходе функции устанавливается “0” только в случае отсутствия “1” на всех входах блока логической функции.
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: несмотря на возможность выбрать в выпадающем меню все типы данных, данная функция работает ТОЛЬКО с логическими и целыми беззнаковыми типами данных. В случае выбора иного типа данных, редактор допустит соответствующее изменение, однако при компиляции программы будет выдана ошибка.
Количество входов: в данном пункте предоставляется возможность изменения количества входов соответствующего блока.
Блок Исключающее ИЛИ¶
Описание: Функция “Исключающее ИЛИ” анализирует значения на входах и генерирует результат на выходе, подчиняясь правилу булевой алгебры:
Если функция “Исключающее ИЛИ” имеет несколько входов, то для получения “1” на выходе необходимо, чтобы значение только одного из входов было равно “1”. На выходе функции устанавливается “0” либо в случае отсутствия “1” на всех входах блока логической функции, либо при наличии “1” более чем на одном входе.
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: несмотря на возможность выбрать в выпадающем меню все типы данных, данная функция работает ТОЛЬКО с логическими и целыми беззнаковыми типами данных. В случае выбора иного типа данных, редактор допустит соответствующее изменение, однако при компиляции программы будет выдана ошибка.
Количество входов: в данном пункте предоставляется возможность изменения количества входов соответствующего блока.
Блок Не¶
Описание: Функция “НЕ” (отрицание) считывает значение со входа, инвертирует и передает результат на выход, подчиняясь правилу булевой алгебры:
Функция “НЕ” имеет только один вход, следовательно для получения “1” на выходе необходимо, чтобы на вход был подан “0” и наоборот.
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Блок Фронт¶
Описание: Функция “Фронт” анализирует значение на входе (In), и при любом изменении данного значения функция выдает “1” на выход на интервал времени, равный 1 шагу выполнения программы. На вход может быть подан любой тип данных (см. ниже “свойства блока”).
Пример: на входе установлено значение 5, и при изменении данного значения как на увеличение (условно 6), так и на уменьшение (условно 4), на выходе установится “1” на один шаг выполнения программы (условно 1 мс), а уже на следующем шаге (через 1 мс) на выходе установится обратно “0”.
Примечание: длительность этого интервала зависит только от скорости работы устройства, настройка такого соотношения в системе zetFBD отсутствует. Устройство выполняет шаги с максимально возможной скоростью (подробнее см. D120213 П.6).
Внимание: Этот блок не делает удержание значения на выходе по времени! После выдачи на выходе 1 непосредственно в следующем шаге выполнения, возможно, будет выдан 0, если значение входа снова не изменится.
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: данный пункт позволяет устанавливать любой тип данных, но только для входа, выход всегда остается логическим. Таким образом данный блок является фиксатором любого изменения состояния на входе.
Блок Передний фронт¶
Описание: Функция “Передний фронт” анализирует значение на входе (In), и при положительном (в сторону увеличения) изменении данного значения функция выдает “1” на выход на интервал времени, равный 1 шагу выполнения программы. На вход может быть подан любой тип данных (см. ниже “Свойства блока”).
Пример: на входе установлено значение 5, и при изменении данного значения в сторону увеличения (5.5, 6, 7.2 и т.д.) , на выходе установится “1” на один шаг выполнения программы (условно 1 мс), а уже на следующем шаге (через 1 мс) на выходе установится обратно “0”. При изменении значения на входе в сторону уменьшения (4, 3.2 и т.д.) состояние выхода не изменится.
Примечание: длительность этого интервала зависит только от скорости работы устройства, настройка такого соотношения в системе zetFBD отсутствует. Устройство выполняет шаги с максимально возможной скоростью.
Внимание: Этот блок не делает удержание значения на выходе по времени! После выдачи на выходе 1 непосредственно в следующем шаге выполнения, возможно, будет выдан 0, если значение входа снова не изменится. 1 клетка горизонтальной оси соответствует 1 шагу выполнения схемы.
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: данный пункт позволяет устанавливать любой тип данных, но только для входа, выход всегда остается логическим. Таким образом данный блок является фиксатором положительного изменения состояния на входе.
Блок Задний фронт¶
Описание: Функция “Задний фронт” анализирует значение на входе (In), и при отрицательном (в сторону уменьшения) изменении данного значения функция выдает “1” на выход на интервал времени, равный 1 шагу выполнения программы. На вход может быть подан любой тип данных (см. ниже “Свойства блока”).
Пример: на входе установлено значение 5, и при изменении данного значения в сторону уменьшения (4, 3.2 и т.д.) , на выходе установится “1” на один шаг выполнения программы (условно 1 мс), а уже на следующем шаге (через 1 мс) на выходе установится обратно “0”. При изменении значения на входе в сторону увеличения (5.5, 6, 7.2 и т.д.) состояние выхода не изменится.
Внимание: Этот блок не делает удержание значения на выходе по времени! После выдачи на выходе 1 непосредственно в следующем шаге выполнения, возможно, будет выдан 0, если значение входа снова не изменится. 1 клетка горизонтальной оси временной диаграммы соответствует 1 шагу выполнения схемы.
Блок «Задний фронт» может быть использован другим способом: в свойствах входов блоков, имеющих логический тип данных, можно указать опцию «Режим входа» «Задний фронт». Эта опция указывает, что в разрыв связи этого входа должен быть вставлен блок фронта.
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: данный пункт позволяет устанавливать любой тип данных, но только для входа, выход всегда остается логическим. Таким образом данный блок является фиксатором отрицательного изменения состояния на входе.
Блок Проверка бита¶
Описание: Функция “Проверка бита” выделяет определенный бит из поданного на вход in значения и передает его на выход out . Номер выделяемого бита определяется значением на входе bit , причем следует не забывать, что нумерация начинается с нулевого бита. На вход может быть подан только целый беззнаковый тип данных (см. ниже “Свойства блока”).
Пример: на вход in подано значение 2(0010). Чтобы считать единицу, на входе bit необходимо установить значение “1”. Пример работы блока битовой операции Проверка бита:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: несмотря на возможность выбрать в выпадающем меню все типы данных, данная функция работает ТОЛЬКО с целыми беззнаковыми типами данных. В случае выбора иного типа данных, редактор допустит соответствующее изменение, однако при компиляции программы будет выдана ошибка.
Блок Установка бита¶
Описание: Функция “Установка бита” выделяет определенный бит из поданного на вход in значения и передает его на выход out . Номер выделяемого бита определяется значением на входе bit , причем следует не забывать, что нумерация начинается с нулевого бита. На вход может быть подан только целый беззнаковый тип данных (см. ниже “Свойства блока”).
Пример: на вход in подано значение 2(0010). Если мы хотим изменить его нулевой бит, значение которого равно “0”, тогда на вход bit необходимо установить 0, а на вход set установить значение “1”. Тогда в нулевой бит значения 2 (010) запишется “1” и новое значение 3 (011) установится на выходе out . Пример работы блока битовой операции Установка бита:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: несмотря на возможность выбрать в выпадающем меню все типы данных, данная функция работает ТОЛЬКО с целыми беззнаковыми типами данных. В случае выбора иного типа данных, редактор допустит соответствующее изменение, однако при компиляции программы будет выдана ошибка.
Блок Сдвиговой регистр¶
Описание: Блок функции “Сдвиговый регистр” осуществляет побитовый сдвиг (вправо или влево — см. Свойства блока) значения, поданного на вход in . Величина сдвига задается на входе shift в целочисленной десятичной форме. Тип данных изменяется, допускаются только беззнаковые 1-4 байтовые целые типы данных.
Пример: при подаче “11” (1011) на вход in и “2” на вход shift (в свойствах задан сдвиг вправо), получаем, что значение 1011 сдвигается вправо на 2 разряда, т.е. результат операции сдвига — 0010, что соответствует “2” в десятичной системе исчисления, и это значение подается на выход out .
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: несмотря на возможность выбрать в выпадающем меню все типы данных, данная функция работает ТОЛЬКО с целыми беззнаковыми типами данных. В случае выбора иного типа данных, редактор допустит соответствующее изменение, однако при компиляции программы будет выдана ошибка.
Направление сдвига: задается направление сдвига: вправо или влево.
Циклический сдвиг: в случае установки данного параметра, сдвинутые биты записываются в зависимости от направления в старшие или младшие разряды той же переменной.
Пример: на вход in подается значение “1”(0000 0001), на вход shift — “2”, направление сдвига — вправо, тип данных — беззнаковый целый 1-байтовый(8 бит), циклический сдвиг — true: результат данной операции 64(0100 0000).
Таймеры и время¶
Таймер¶
Описание: Выдает на выход 1 с заданным интервалом многократно, или однократно после установки разрешающего сигнала. Вход еn – разрешение работы таймера, при установленной 1 – выдача 1 на выходе разрешена, при 0 – запрещена. Вход interval задает период выдачи 1 на выходе.
Выход равен 1, если соблюдены все следующие условия:
- вход en равен 1 в течение времени, в миллисекундах, не меньшего, чем значение на входе interval , сохраненное на шаге переднего фронта входа en ,
- значение выхода на предыдущем шаге выполнения было 0,
- со времени выдачи предыдущей 1 или переднего фронта входа en на выходе прошло время, в миллисекундах, не меньшее, чем значение на входе interval , запомненное в шаге предыдущей 1 или переднего фронта входа en .
Циклограмма работы блока Таймер :
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Однократно:
1 выдается только в «одиночном» режиме, т.е. течение одного шага! Между соседними 1 в течение, как минимум, одного шага, гарантированно выдается 0. Опция Однократно указывает, что выдача 1 будет выполняться только один раз, после каждого переднего фронта входа en . Иначе 1 будут выдаваться многократно. Все блоки-таймеры проекта используют один аппаратный «базовый» таймер устройства, настраиваемый на определенный постоянный интервал срабатывания. Интервал срабатывания базового таймера указывается в свойствах проекта. Переменная – признак срабатывания базового таймера устанавливается перед выполнением каждого шага вычисления схемы, при этом, если на предыдущем шаге была 1, то на этом шаге устанавливается 0, независимо от времени. Для отсчета времени каждый блок использует внутреннюю переменную-счетчик.
Алгоритм выполнения блока:
- если признак срабатывания базового таймера равен 0 – выдать 0, закончить выполнение,
- если вход en равен 0 – выдать 0, записать в переменную-счетчик значение Interval / (Интервал базового таймера), закончить выполнение,
- уменьшить переменную-счетчик на 1,
- если переменная-счетчик равна 0 – выдать 1 и, если свойство Однократно не установлено – записать в переменную-счетчик значение Interval / (Интервал базового таймера) для следующего срабатывания.
Базовый таймер¶
Описание: Все блоки-таймеры проекта используют один аппаратный «базовый» таймер устройства, настраиваемый на определенный постоянный интервал срабатывания. Интервал срабатывания базового таймера указывается в свойствах проекта. Переменная – признак срабатывания базового таймера устанавливается перед выполнением каждого шага программы, при этом, если на предыдущем шаге была 1, то на этом шаге устанавливается 0, независимо от времени. Для отсчета времени каждый блок использует внутреннюю переменную-счетчик.
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Тип данных: в данном пункте предоставляется выбрать любой из предложенных типов данных для выхода val . Тип данных следует указывать таким же, что и тип данных переменных, значения которых собираетесь считывать.
Упаковка времени¶
Описание: Преобразует (упаковывает) множество значений “год, месяц, день, час, минута, секунда” в Упакованный формат . Обратное преобразование выполняет блок Распаковка времени .
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Исп. текущее время: если свойство активно, устанавливает на выходе уже упакованное текущее время контроллера (если он поддерживает часы).
Распаковка времени¶
Описание: Преобразует (распаковывает) Упакованную метку времени во множество значений “год, месяц, день, час, минута, секунда”. Обратное преобразование выполняет блок Упаковка времени .
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Логика¶
Блок Мультиплексор¶
Описание: Блок функции Мультиплексор передает значение на выход out с одного из входов блока ( in0 , in1 и т.д.), причем номер данного входа определяется значением на входе addr . Вход addr может быть логическим ( 2 входа in ) или беззнаковым целочисленным«(2 и более входа «in ), причем данное значение в десятичной форме соответствует номеру входа (начиная с 0). Так при значении 10 на входе addr , на выход out передается значение со входа in9 .
Пример: при подаче 0 на вход addr , на выход передается значение со входа in0 , т.е. 1. А при подаче 3 на вход addr , на выход передается значение со входа in3 , т.е. 4:
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Тип данных: для входов in и выхода out допускаются любые типы данных из предложенных..
Количество входов: в данном пункте предоставляется возможность изменения количества входов соответствующего блока.
Примечание: тип данных адреса задается в свойствах соответствующей “ножки” входа addr и несмотря на возможность выбрать в выпадающем меню все типы данных, для входа addr допускаются ТОЛЬКО логические и целые беззнаковые типы данных . В случае выбора иного типа данных, редактор допустит соответствующее изменение, однако при компиляции программы будет выдана ошибка.
Блок Демультиплексор¶
Описание: Блок функции Демультиплексор передает значение на один из выходов (out0, out1 и т.д.) со входа блока in , причем номер данного выхода определяется значением на входе addr . Вход addr может быть логическим ( 2 входа in) или беззнаковым целочисленным«(2 и более входа in), причем данное значение в десятичной форме соответствует номеру выхода (начиная с 0). Так при значении **10** на входе «addr , значение со входа in передается на выход out9 .
Пример: при подаче 0 на вход addr , значение 5 со входа in передается на выход out0 . При подаче 3 на вход addr , значение 5 со входа in передается на выход out3 :
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Тип данных: для входов in и выхода out допускаются любые типы данных из предложенных..
Количество входов: в данном пункте предоставляется возможность изменения количества входов соответствующего блока.
Примечание: тип данных адреса задается в свойствах соответствующей “ножки” входа addr и, несмотря на возможность выбрать в выпадающем меню все типы данных, для входа addr допускаются ТОЛЬКО логические и целые беззнаковые типы данных . В случае выбора иного типа данных, редактор допустит соответствующее изменение, однако при компиляции программы будет выдана ошибка.
Блок RS-триггер¶
Описание: Реализует логику асинхронного RS-триггера. Функция “RS-триггер” анализирует значения на входах S и R и генерирует результат на выходах Q и
Q по следующему правилу: Триггер (защелка) используется для удержания значения 1 (например, для того, чтобы лампочка загорелась и продолжала гореть)., пока это необходимо, и для сброса в 0, когда нужно отменить это действие. Таблица истинности RS-триггера:
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Примечание: в свойствах соответствующей “ножки” блока на входе осуществялется задание параметров обработки входного сигнала.
Блок D-триггер¶
Описание: Функция “D-триггер” анализирует значения на входах С , R и D и генерирует результат на выходах Q и
Q по следующему правилу:
Таблица истинности D-триггера:
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Примечание: в свойствах соответствующей “ножки” блока на входе осуществляется задание параметров обработки входного сигнала.
Блок Счетчик¶
Описание: Универсальный счетчик. Блок содержит: блок записи фиксированного значения (при старте значение равно 0), операцию сложения-вычитания, операцию сравнения. Блок функции “Счетчик” производит операцию счета количества изменений состояний на входах + и — . При подаче 1 на вход S значение счетчика становится равно значению UL (максимуму), 1 на вход R – значению DL (минимума). Счет производится посредством прибавления к текущему значению 1 при фиксировании изменения состояния из 0 в 1 входа + и вычитания из текущего значения 1 при фиксировании изменения состояния из 0 в 1 входа — . В UL следует записывать верхнюю границу счета, а в DL , соответственно, нижнюю. На выходе out формируется текущее значение счетчика. На выходах up и down фиксируется достижение счетчиком верхней UL и нижней DL границы допустимых значений, при этом счет останавливается, и значение на соответствующем из выходов не меняется, до тех пор пока не будет установлена 1 на вход R или S . Следует учитывать, что счет начнется также только при условии, что значения на входах S и R равны 0. Т.е. сигналы на данных входах должны быть кратковременными. Входы S , R , + , — можно изменять в редакторе свойств на передний фронт, задний фронт, прямой или инверсный.
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Тип данных: в данном пункте предоставляется выбрать любой из предложенных типов данных для выхода val . Тип данных следует указывать таким же, что и тип данных переменных, значения которых собираетесь считывать.
Начальное значение: в данном пункте устанавливается нижняя граница счетчика.
Примером использования данного блока могут служить кнопки увеличения и уменьшения громкости звука на пульте телевизора:
Блок Шифратор¶
Описание: Блок функции Шифратор преобразует биты на входах в целочисленное значение на выходе. Номер входа соответствует позиции бита в двоичной записи числа. Количество входов меняется от 2 до 16. Тип данных на выходе изменяется, допускаются только беззнаковые 1 и 2 байтовые целые типы данных. Тип данных должен содержать количество битов не меньше, чем указанно в количестве входов блока.
Пример: при подаче 1 на нулевой d0 и второй d2 входы, получаем значение 101 в двоичной системе исчисления, что соответствует 5 в десятичной системе исчисления:
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Тип данных: несмотря на возможность выбрать в выпадающем меню все типы данных, данная функция работает ТОЛЬКО с целыми беззнаковыми типами данных на выходе, причем только 1- и 2-байтовые . В случае выбора иного типа данных, редактор допустит соответствующее изменение, однако при компиляции программы будет выдана ошибка.
Количество входов: в данном пункте предоставляется возможность изменения количества входов соответствующего блока. Допускается от 2 до 16 входов (при 2-х байтовом типе данных).
Блок Шифратор адресный¶
Описание: Блок функции Шифратор адресный выдает на выход addr адрес первого (сверху) входа, имеющего значение 1:
Если в редакторе свойств блока включить Приоритет большего, то выход addr будет иметь значение последнего (сверху) входа, имеющего значение 1:
Выход val устанавливает 1, если на входе имеется хотя бы одна 1, в случае отсутствия единиц на входах, выход val имеет значение 0, а выход addr – 255:
Общие свойства: см. Редактирование свойств блока.
Количество входов: в данном пункте предоставляется возможность изменения количества входов соответствующего блока. Допускается от 2 до 32 входов.
Блок Дешифратор¶
Описание: Блок функции Дешифратор раскладывает целочисленное значение на входе в соответствующие биты на выходах. Номер выхода соответствует позиции бита в двоичной записи числа. Количество выходов меняется от 2 до 16. Тип данных на входе изменяется, однако допускаются только беззнаковые 1 и 2 байтовые целые типы данных.
Пример: при подаче 2**(0010) на вход «in« на выходе данное значение раскладывается в двоичное значение, где значения выхода «d1« соответствует позиции второго бита в двоичной записи числа **2, т.е. на выходе d1 = 1:
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Тип данных: несмотря на возможность выбрать в выпадающем меню все типы данных, данная функция работает ТОЛЬКО с целыми беззнаковыми типами данных на выходе, причем только 1- и 2-байтовые . В случае выбора иного типа данных, редактор допустит соответствующее изменение, однако при компиляции программы будет выдана ошибка.
Количество входов: в данном пункте предоставляется возможность изменения количества входов соответствующего блока. Допускается от 2 до 16 входов (при 2-х байтовом типе данных).
Блок Дешифратор с накоплением выхода¶
Описание: На вход in подается число беззнаковое целое 1-байт . Оно указывает, на сколько выходов (сверху вниз) установить единицы. Остальные выходы будут иметь значение 0.
Общие свойства: см. Редактирование свойств блока.
Количество выходов: в данном пункте предоставляется возможность изменения количества входов соответствующего блока. Допускается от 2 до 32 входов.
Использование шифратора и дешифратора¶
Задача: Необходимо передать несколько значений логических переменных, полученных главным контроллером, в подчиненный контроллер по сети MODBUS. Для экономии сетевого трафика будем передавать не каждую переменную отдельно, а передадим одно число, используя блоки шифратора и дешифратора.
Для этого выполним следующие действия:
1. В дереве Обозреватель проекта добавим шаблон программы для главного контроллера Панель Z036 A0 . Подадим значения логических переменных на входы блока шифратора. Напомним, что количество входов шифратора можно изменять от 2 до 16. На выходе имеем десятичное число, которое и передадим по сети MODBUS, используя блок Запись ( slave ).
На вход en установим 1 (константу), чтобы запись произошла.
На вход port подаем номер порта главного контроллера, с которого будет отправлена команда на запись.
На вход dev – адрес подчиненного контроллера, в который будет передано значение.
На вход reg – адрес регистра сетевой переменной, в которую передаем значение, полученное на вход val .
Вход val соединяем с выходом блока Шифратор .
- Создание сетевых переменных.
В дереве Обозреватель проекта добавим шаблон программы для подчиненного контроллера Z036 B1 . «Ловим» переданное значение в сетевую переменную proizv3 с указанным адресом на входе reg . Передаем ее значение в дешифратор, а уже из дешифратора происходит побитовое разделение в логические переменные:
- Настройка шаблонов контроллеров.
В дереве Обозреватель проекта щелкнем ПКМ по Панель Z036 B1 –> Свойства –> вкладка Устройство –> выберем Протокол MODBUS RTU подчиненный для порта COM1 .
Аналогично поступим с Панель Z036 A0 . Только выберем Протокол MODBUS RTU главный для порта COM0 .
При симуляции нескольких контроллеров, подключенных к одному порту, необходимо разделять порт для нескольких задач. Для этого в свойствах порта нужно включить соответствующую опцию:
Блоки чтения-записи ПЗУ¶
Сохранение переменных в ПЗУ (Постоянное Запоминающее Устройство или EEPROM, электрически стираемая энергонезависимая память) используется для хранения измененных значений переменных при выключенном питании контроллера. Пример таких переменных — настроечные величины (“уставки”) программы, счетчики событий, и прочие переменные, которые не должны после выключения-включения питания контроллера сбрасывать свои значения на значения по умолчанию.
В связи с тем, что количество, сколько можно раз записывать в ПЗУ, ограничено (обычно от 10^6. до 10^12 раз), и что в течение записи происходит пауза в выполнении программы, запись нельзя выполнять постоянно. Если запись выполнять несвоевременно, то при неожиданном выключении питания контроллера последние изменения значений переменных будут утеряны.
Работа с ПЗУ может выполняться двумя способами:
1. ПЗУ-переменные
Переменные FBD-программы имеют флаг Запись в ПЗУ , при включении которого данная переменная должна сохраняться в ПЗУ FBD-ядром контроллера. В дальнейшем такие переменные будут называться ПЗУ-переменные . Для каждой ПЗУ-переменной резервируется место (адрес) в ПЗУ, по размеру соответствующее выбранному типу данных. Адреса всех переменных задаются в окне Переменные ПЗУ в контекстном меню программы. При проверке FBD-программы перед программированием контроллера всегда проверяется, чтобы каждая ПЗУ-переменная имела отдельный адрес (диапазон адресов), не пересекающийся с адресами других ПЗУ-переменнных .
ПЗУ-переменные обрабатываются FBD-ядром контроллера так:
При включении питания контроллера FBD-ядро устанавливает во все переменные значения по умолчанию. Затем выполняется проверка целостности содержимого ПЗУ путем проверки значений служебных ПЗУ-переменных (например, “Адрес подчиненного устройства Modbus”), хранимых в ПЗУ. Если целостность ПЗУ соблюдена, значения всех переменных копируются из ПЗУ в оперативную память, иначе — выполняется запись в ПЗУ значений по умолчанию всех переменных. Далее FBD-ядро выполняет основной цикл FBD-программы.
В течение работы контроллера FBD-программа периодически устанавливает признак, который проверяется между шагами выполнения FBD-схемы. Если он равен 1 — выполняется запись в ПЗУ значений всех ПЗУ-переменных из оперативной памяти.
Внимание! Копирование значений из ПЗУ в оперативную память ПЗУ-переменных в основном цикле программы не выполняется.
Для установки этого признака служит блок Запись переменных , который должен быть создан пользователем. Другой вариант — установка опций автоматического выполнения записи при определенных событиях (см. раздел FBD-программа).
- Блок Запись переменных (EEPROM)
Этот блок имеет 1 логический вход, выходов не имеет. Если на вход подан 0, блок ничего не выполняет. Если подана 1 — он устанавливает признак, по которому после выполнения всех блоков в текущем шаге выполнения программы, т.е. между шагами, будет выполнена запись всех ПЗУ-переменных .
2. Блоки произвольного доступа в ПЗУ
Блоки произвольного доступа в ПЗУ предназначены для чтения-записи произвольных (динамических) адресов ПЗУ, записи-чтения динамических массивов, например журналов событий. Такие данные не могут быть только с большим трудом записаны с использованием ПЗУ-переменных, т.к. количество ПЗУ-переменных и их адреса не могут изменяться в течение работы FBD-программы. Пользователь самостоятельно создает схему, математически вычисляющую адрес чтения записи, и схему для разрешения чтения-записи. Для доступа доступны все адреса ПЗУ, поэтому пользователь сам должен обеспечивать целостность данных, в том числе чтобы этими командами не испортить значения ПЗУ-переменных.
- Блок Чтение из ПЗУ (EEPROMRead)
- Блок Запись в ПЗУ (EEPROMWrite)
Блок Запись переменных (EEPROM)¶
Описание: Блок Запись переменных дает команду записи переменных в ПЗУ при приходе 1 на вход en . Записываются только те переменные, у которых установлены соответствующие параметры работы с ПЗУ.
Блок Запись переменных в проекте может быть задействован произвольное количество раз, но не меньше 1. Тогда они производят команду записи в ПЗУ, общую для всех переменных, причем по принципу ИЛИ.
Примечание: запись переменных в энергонезависимую память должна осуществляться с небольшой частотой из-за ограниченного количества циклов перезаписи ППЗУ, особенно если переменная в ОЗУ изменяется с высокой частотой, т.е. ППЗУ будет испорчено через некоторое время работы. Таким образом пользователь должен задать признак записи в ПЗУ либо по таймеру (в большинстве случаев), либо по событию изменения переменной (только при редком изменения значения переменной).
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Блок Чтение из ПЗУ (EEPROMRead)¶
Описание: Блок Чтение из ПЗУ выдает значение искомой переменной на выход val согласно ее адресу в ПЗУ, а адрес этой искомой переменной приходит на вход addr . В случае подачи некорректного адреса на выход val подается 0, а на выход err — 1.
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Тип данных: в данном пункте предоставляется выбрать любой из предложенных типов данных для выхода val . Тип данных следует указывать таким же, что и тип данных переменных, значения которых собираетесь считывать.
Блок Запись в ПЗУ (EEPROMWrite)¶
Описание: Блок Запись в ПЗУ записывает значение, поданное на вход val , в определенную ячейку памяти ПЗУ, а адрес этой ячейки в свою очередь приходит на вход addr . Запись осуществляется только при условии 1 на входе en . В случае некорректного адреса на выход err подается 1 и значение не записывается.
Свойства блока:
Общие свойства: см. Редактирование свойств блока.
Тип данных: в данном пункте предоставляется выбрать любой из предложенных типов данных для выхода val . Тип данных следует указывать таким же, что и тип данных переменных, значения которых собираетесь записывать.
Математические блоки¶
Блок Сравнение¶
Описание: Блок функции Сравнение производит операцию сравнения значений на входах блока типа: Значение входа in1 “тип операции сравнения” Значения входа in2 , и в случае, если операция удовлетворяет условию сравнения, на выход выдается 1, причем единица устанавливается до тех пор, пока верна операция сравнения.
Тип операции сравнения (см. ниже “Свойства блока”):
- “==” — равно;
- ”!=” — не равно;
- “>” — больше;
- “>=” — больше или равно;
- “<” — меньше;
- “<=” — меньше или равно.
Пример: производится 2 операции сравнения типа: 10 > 20 и 20 > 10. Первая операция не является верной, поэтому на выходе устанавливается 0, в то время как вторая операция удовлетворяет условию сравнения, поэтому на выход подается 1:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: допускаются любые типы данных из предложенных.
Операция: в данной графе предоставляется возможность выбрать необходимый тип операции сравнения.
Блок Условие¶
Описание: Функция “Условие” анализирует значение на входе if . В случае установки 1**(true) на данном входе, на выход «out« передается значение со входа «true«, а при **0 — со входа false . На входы true и false может быть подан любой тип данных, но он будет одинаков для обоих входов, при этом тип данных выхода соответствует типу данных этих входов: (см. ниже “Свойства блока”)
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: допускаются любые типы данных из предложенных.
Блок Сложения¶
Описание: Блок функции “Сложение” производит арифметическую операцию сложения (вычитания) со значениями, поданными на входы. Тип операции задается для каждого входа отдельно, путем изменения свойств соответствующей входу ножки. Операция выглядит как: (знак операции)значение на входе 1 + (знак операции)значение на входе 2 + . + (знак операции)значение на входе n, где n — число входов блока (см. свойства блока).
Примечание: тип операции задается в свойствах “ножки” входа блока.
Пример: 1. (+)10 + (+)5 = 10+5 = 15; 2. (+)10 + (-)5 = 10-5 = 5; 3. (-)10 + (+)5 = -10+5 = -5; 4. (-)10 + (-)5 = -10-5 = -15:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: допускаются любые типы данных из предложенных.
Количество входов: в данном пункте предоставляется возможность изменения количества входов соответствующего блока.
Показывать выход переполнения: управляет наличием выхода of , который выдает логический признак возникновения переполнения. Это свойство не влияет на выполнение операций устройством. Выход of рекомендуется использовать для выполнения специально запрограммированных действий при переполнении.
Обработка переполнения: при выполнении операции выполняется проверка на переполнение выхода, т.е. результирующего значения за диапазон значений выбранного типа данных. В такой ситуации рассчитанное значение не может быть верным математически.
Существуют следующие способы обработки переполнения:
- «Игнорировать» — выход получает только младшие биты данных от полученного результата. Не рекомендуется использовать, за исключением реализации циклических счетчиков, когда переход счетчика через максимальное значение в 0 специально нужен, или когда старшие биты значения не нужны, достаточно младших битов.
- «Установить 0» — выход устанавливается в 0. Рекомендуется использовать при использовании значения 0 как признак аварии;
- «Выставить граничное значение» — выход получает значение, ближайшее к истинному значению, на границе диапазона значений выбранного типа данных. Это наиболее логически правильный и рекомендуемый способ, особенно для значений, суммируемых за некоторое время работы устройства;
- «Настройки проекта» — ссылка на один из первых трех способов, указанный в настройках проекта. Эта опция позволяет централизованно управлять этим свойством.
При наличии нескольких операций в одном блоке, т.е. более чем 2 входов – ситуация переполнения последовательно анализируется при выполнении операций:
- выход of равен 0, если переполнения нет при выполнении всех операций (на выходе математически правильное значение), иначе устанавливается 1;
- при 2 и 3 способе обработки при возникновении переполнения блок пропускает выполнение следующих операций, т.к. все биты, в т.ч. младшие, приняли математически неправильные значения. Поэтому при пропуске следующих операций в 3 способе обработки и возникновении ситуации переполнения несколько раз в разные стороны (например, сначала вверх, затем вниз) выдаваемое значение будет соответствовать первой по порядку ситуации переполнения;
- при 1 способе обработки при возникновении переполнения блок продолжает выполнение следующих операций. При выполнении вычитания первого входа значение вычитается из 0, блок выполняет на одну операцию больше в сравнении со сложением первого входа. При этом вычитании также обрабатывается переполнение.
Внимание: при 2 и 3 способе обработки переполнения, в случае возникновения переполнения, результат зависит от порядка выполнения операций, т.е. подключение входов в другом порядке приводит к изменению результата. В том числе, возможно, что при каком-то варианте подключения переполнение не происходит, а в другом – происходит, при одинаковых входных значениях. Этого можно избежать с помощью выбора в блоке типа данных с большей разрядностью, чем типы данных значений на входах. В таком случае переполнение практически не может случиться (для переполнения потребуется слишком большое количество входов). При использовании типов данных с плавающей запятой вероятность переполнения значительно уменьшается. Но имеются побочные эффекты, которые могут привести к неожиданным результатам.
Следует иметь ввиду:
- при увеличении порядка значения снижается его точность из-за увеличения дискретности, например 4-байтовое число порядка 17000000 имеет дискретность 2, т.е. сложение 1 к нему может не изменить результат!
- обработка младших разрядов, выходящих за предел разрядности, может зависеть от реализации в устройстве. В большинстве устройств вычисления реализуются по стандарту IEEE 754, но это не гарантировано.
Пример выполнения блока для 1-байтового беззнакового типа данных, значения ограничены диапазоном от 0 до 255:
Блок Умножения¶
Описание: Блок функции “Умножение” производит арифметическую операцию умножения (деления) со значениями, поданными на входы. Тип операции задается для каждого входа отдельно, путем изменения свойств соответствующей входу ножки. Операция выглядит как: числитель — “1” умножить на произведение всех значений на входах со знаком операции “*”, знаменатель — “1” умножить на произведение всех значений на входах со знаком операции “/”.
Примечание: тип операции задается в свойствах “ножки” входа блока.
Пример: 1. (1*10*2)/1 = 10*2 = 20; 2. (1*2)/(1*10) = 2/10 = 0,2; 3. (1*10)/(1*2) = 10/2 = 5; 4. 1/(1*10*2) = 1/20 = 0,05:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: допускаются любые типы данных из предложенных.
Количество входов: в данном пункте предоставляется возможность изменения количества входов соответствующего блока.
Показывать выход переполнения: управляет наличием выхода of , который выдает логический признак возникновения переполнения. Это свойство не влияет на выполнение операций устройством. Выход of рекомендуется использовать для выполнения специально запрограммированных действий при переполнении.
Обработка переполнения: при выполнении операции выполняется проверка на переполнение выхода, т.е. результирующего значения за диапазон значений выбранного типа данных. В такой ситуации рассчитанное значение не может быть верным математически.
Существуют следующие способы обработки переполнения:
- «Игнорировать» — выход получает только младшие биты данных от полученного результата. Не рекомендуется использовать, за исключением реализации циклических счетчиков, когда переход счетчика через максимальное значение в 0 специально нужен, или когда старшие биты значения не нужны, достаточно младших битов.
- «Установить 0» — выход устанавливается в 0. Рекомендуется использовать при использовании значения 0 как признак аварии;
- «Выставить граничное значение» — выход получает значение, ближайшее к истинному значению, на границе диапазона значений выбранного типа данных. Это наиболее логически правильный и рекомендуемый способ, особенно для значений, суммируемых за некоторое время работы устройства;
- «Настройки проекта» — ссылка на один из первых трех способов, указанный в настройках проекта. Эта опция позволяет централизованно управлять этим свойством.
При наличии нескольких операций в одном блоке, т.е. более чем 2 входов – ситуация переполнения последовательно анализируется при выполнении операций:
- выход of равен 0, если переполнения нет при выполнении всех операций (на выходе математически правильное значение), иначе устанавливается 1;
- при 2 и 3 способе обработки при возникновении переполнения блок пропускает выполнение следующих операций, т.к. все биты, в т.ч. младшие, приняли математически неправильные значения. Поэтому при пропуске следующих операций в 3 способе обработки и возникновении ситуации переполнения несколько раз в разные стороны (например, сначала вверх, затем вниз) выдаваемое значение будет соответствовать первой по порядку ситуации переполнения;
- при 1 способе обработки при возникновении переполнения блок продолжает выполнение следующих операций. При выполнении вычитания первого входа значение вычитается из 0, блок выполняет на одну операцию больше в сравнении со сложением первого входа. При этом вычитании также обрабатывается переполнение.
Внимание: при 2 и 3 способе обработки переполнения, в случае возникновения переполнения, результат зависит от порядка выполнения операций, т.е. подключение входов в другом порядке приводит к изменению результата. В том числе, возможно, что при каком-то варианте подключения переполнение не происходит, а в другом – происходит, при одинаковых входных значениях. Этого можно избежать с помощью выбора в блоке типа данных с большей разрядностью, чем типы данных значений на входах. В таком случае переполнение практически не может случиться (для переполнения потребуется слишком большое количество входов). При использовании типов данных с плавающей запятой вероятность переполнения значительно уменьшается. Но имеются побочные эффекты, которые могут привести к неожиданным результатам.
Следует иметь ввиду:
- при увеличении порядка значения снижается его точность из-за увеличения дискретности, например 4-байтовое число порядка 17000000 имеет дискретность 2, т.е. сложение 1 к нему может не изменить результат!
- обработка младших разрядов, выходящих за предел разрядности, может зависеть от реализации в устройстве. В большинстве устройств вычисления реализуются по стандарту IEEE 754, но это не гарантировано.
Пример выполнения блока для 1-байтового беззнакового типа данных, значения ограничены диапазоном от 0 до 255:
Блок Деление с остатком¶
Описание: Блок функции “Деление с остатком”) производит операцию деления значения входа A на значения входа B , при этом результат раскладывается на 2 составляющие: выход А/В — неполное частное от деления, выход mod — остаток от деления. Если B равен 0 (деление на 0), значение выхода mod равно значению на входе A .
Пример: Производится операция деления 9/5. Результат данной операции: число 9 содержит одну 5, а остаток равен 4:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: допускаются любые типы данных из предложенных.
Обработка переполнения: при выполнении операции выполняется проверка на переполнение выхода, т.е. результирующего значения за диапазон значений выбранного типа данных. В такой ситуации рассчитанное значение не может быть верным математически.
Существуют следующие способы обработки переполнения:
- «Игнорировать» — выход получает только младшие биты данных от полученного результата. Не рекомендуется использовать, за исключением реализации циклических счетчиков, когда переход счетчика через максимальное значение в 0 специально нужен, или когда старшие биты значения не нужны, достаточно младших битов.
- «Установить 0» — выход устанавливается в 0. Рекомендуется использовать при использовании значения 0 как признак аварии;
- «Выставить граничное значение» — выход получает значение, ближайшее к истинному значению, на границе диапазона значений выбранного типа данных. Это наиболее логически правильный и рекомендуемый способ, особенно для значений, суммируемых за некоторое время работы устройства;
- «Настройки проекта» — ссылка на один из первых трех способов, указанный в настройках проекта. Эта опция позволяет централизованно управлять этим свойством.
Пример выполнения блока для 1-байтового беззнакового типа данных, значения ограничены диапазоном от 0 до 255:
Блок Минимум¶
Описание: Блок функции “Минимум” производит операцию сравнения значений на входах блока ( in0 , in1 и т.д.) и передает на выход min наименьшее значение. Количество входов и тип данных изменяется (см. ниже “Свойства блока”).
Пример: производится операция сравнения значений 10 и 20. Т.к. 10<20, то на выход min наименьшее значение:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: допускаются любые типы данных из предложенных.
Количество входов: в данном пункте предоставляется возможность изменения количества входов соответствующего блока. Допускается изменение количества входов от 2 до 20.
Блок Максимум¶
Описание: Блок функции “Максимум” производит операцию сравнения значений на входах блока ( in0 , in1 и т.д.) и передает на выход max наибольшее значение. Количество входов и тип данных изменяется (см. ниже “Свойства блока”).
Пример: производится операция сравнения значений 10 и 20. Т.к. 20>10, то на выход max наибольшее значение:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: допускаются любые типы данных из предложенных.
Количество входов: в данном пункте предоставляется возможность изменения количества входов соответствующего блока. Допускается изменение количества входов от 2 до 20.
Блок Преобразование данных¶
Описание: Приводит тип данных входа к типу, указанному в настройках. Вход принимает тип данных связанного с ним выхода. Если выбран логический тип данных – значение выхода равно 1 при ненулевом значении входа. Если множество значений типа данных входа не является подмножеством выходного типа данных, блок выполняет обработку переполнения в соответствии с выбранной опцией. Обработка переполнения выполняется путем сравнения входного значения с диапазоном значений выбранного типа данных, аналогично блоку «Сложение».
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: допускаются любые типы данных из предложенных.
Показывать выход переполнения: управляет наличием выхода of , который выдает логический признак возникновения переполнения. Это свойство не влияет на выполнение операций устройством. Выход of рекомендуется использовать для выполнения специально запрограммированных действий при переполнении.
Обработка переполнения: при выполнении операции выполняется проверка на переполнение выхода, т.е. результирующего значения за диапазон значений выбранного типа данных. В такой ситуации рассчитанное значение не может быть верным математически.
Существуют следующие способы обработки переполнения:
- «Игнорировать» — выход получает только младшие биты данных от полученного результата. Не рекомендуется использовать, за исключением реализации циклических счетчиков, когда переход счетчика через максимальное значение в 0 специально нужен, или когда старшие биты значения не нужны, достаточно младших битов.
- «Установить 0» — выход устанавливается в 0. Рекомендуется использовать при использовании значения 0 как признак аварии;
- «Выставить граничное значение» — выход получает значение, ближайшее к истинному значению, на границе диапазона значений выбранного типа данных. Это наиболее логически правильный и рекомендуемый способ, особенно для значений, суммируемых за некоторое время работы устройства;
- «Настройки проекта» — ссылка на один из первых трех способов, указанный в настройках проекта. Эта опция позволяет централизованно управлять этим свойством.
Пример выполнения блока для 1-байтового беззнакового типа данных, значения ограничены диапазоном от 0 до 255:
Блок Округление¶
Описание: Блок функции “Округление” производит операцию округления дробного значения на входе до определенного знака после запятой. Номер знака задается в свойствах блока.
Пример: на вход блока подано значение 2.5893. В свойствах блока задано округление до 2 знака после запятой. Тогда результат операции равен 2.59:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Количество знаков: в данном пункте указывается до какого знака после запятой округляется значение на входе в блок.
Блок Модуль¶
Описание: Блок функции “Модуль” производит операцию взятия модуля от входного значения, т.е. в случае отрицательного значения на входе, на выход передается то же значение, но без знака “-”. Блок работает только со знаковыми целыми и дробными типами данных.
Пример: на вход блока подано значение -15. Модуль от данного значения равен 15:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: допускаются любые типы данных из предложенных.
Блок Линеаризация¶
Описание: Блок функции “Линеаризация” осуществляет преобразование значений на входе в соответствующие им новые значения на выходе, которые определяются таблицей линеаризации, задаваемой в свойствах блока. Причем промежуточные значения определяются зависимостью, задаваемой при создании таблицы линеаризации. Так значению 0,5 на входе соответствует значение 15 на выходе. Количество выходов может изменяться, соответственно добавляется соответствующий столбец в таблице линеаризации (см. ниже “Свойства блока”). Таким образом данная функция позволяет, к примеру, преобразовывать аналоговый сигнал с датчика температуры в значения температуры в градусах Цельсия.
Таблица линеаризации блока Линеаризация :
Пример: на вход блока подано значение 3. Согласно созданной таблице линеаризации, значению 3 соответствует значение 40 на выходе:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Редактирование таблицы: в данном пункте осуществляется создание таблицы линеаризации для соответствующего блока.
Тип данных: допускается использование любого типа данных.
Выходы: допускается изменение числа выходов от 1 до 8. Для каждого выхода свой столбик в таблице, имеющий то же наименование что и выход.
Блок Интервал¶
Описание: Блок Интервал производит проверку попадания значения, подаваемого на вход val , в интервал между двумя границами. Минимальное значение устанавливается на входе min , а максимальное — на входе max .
- При попадании значения val в заданный интервал, на выходе ok устанавливается значение 1 (True). На выход out передается значение val . На выходах hi и lo устанавливается 0 (False).
- В случае, если текущее значение val больше верхней границы max , то 1 (True) устанавливается на выходе hi . На выход out передается значение hi . На выходах ok и lo устанавливается 0 (False).
- Если текущее значение val меньше нижней границы min , то 1 (True) устанавливается на выходе lo . На выход out передается значение lo . На выходах hi и ok устанавливается 0 (False).
Таким образом, значение на выходе out никогда не выйдет из интервала [ min ; max ].
Пример: на вход блока подано значение 52. Минимальная и максимальная границы установлены 20 и 50 соответственно. Значение 52 не попадает в диапазон от 20 до 50, превышая его, поэтому на выходе получается максимальное значение данного диапазона — 50, а на выходе hi — 1 (True):
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: допускаются любые типы данных из предложенных.
Блок Масштабирование¶
Описание: Блок Масштабирование служит для пропорционального увеличения или уменьшения входного значения x . Если входное значение x лежит в диапазоне, границы которого поданы на входы x0 и x1 , ему сопоставляется пропорциональное значение y , границы которого поданы на входы y0 и y1 . При этом, на выход ok подается 1 (True). Если входное значение x не лежит в заданном диапазоне, тогда выходное значение y становится равным нулю, а 1 (True) устанавливается на выходе lo или hi , если значение x меньше x0 или больше x1 соответственно.
Принцип работы блока Масштабирование на графике:
Пример: на вход x блока подано значение, равное 3. Первая точка ( x0 ; y0 ) задана координатами (0; 0). Вторая точка ( x1 ; y1 ) задана координатами (4; 12). Значение 3 попадает в диапазон от 0 до 4, поэтому на выходе y значение стало равно 9, а на выходе ok — 1 (True):
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: допускаются любые типы данных из предложенных.
Блок Логарифм¶
Описание: Блок функции “Логарифм” производит операцию взятия натурального логарифма (логарифма по основанию “e”) от входного значения. Выходное значение округляется до шестого разряда после запятой. Блок работает только с дробными типами данных, выбор типа данных не доступен.
Пример: на вход блока подано значение 50. Логарифм по основанию “e” от данного значения, округленный до шести разрядов после запятой, равен 3,912023:
Внимание! Блок не поддерживается в устройствах: Z40x, M1xx!
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Блок Экспонента¶
Описание: Блок функции “Экспонента” производит операцию возведения числа “e” в степень входного числа. Выходное значение округляется до шестого разряда после запятой. Блок работает только с дробными типами данных, выбор типа данных не доступен.
Пример: на вход блока подано значение 3. Значение e 3 , округленное до шести разрядов после запятой, равно 20,085537:
Внимание! Блок не поддерживается в устройствах: Z40x, M1xx!
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Блок Синус¶
Описание: Блок функции “Синус” производит операцию нахождения синуса от значения угла, поданного на входе. Выходное значение округляется до шестого разряда после запятой. Блок работает только с дробными типами данных, выбор типа данных не доступен.
Пример: на вход блока подано значение 1,570596, что примерно равно π/2. Синус от него равен 1:
Внимание! Блок не поддерживается в устройствах: Z40x, M1xx!
Внимание! Блок принимает значение угла только в радианах.
Для преобразования угла из градусов в радианы необходимо угол в градусах разделить на 180 и умножить на π. Для этого можно воспользоваться блоком умножения:
- На первый вход можно подать значение угла и выбрать операцию умножения.
- На второй выход 3,141593 (число пи, округленное до шести знаков после запятой) и выбрать операцию умножения.
- На третий вход 180 и выбрать операцию деления.
На выходе блока будет значение исходного угла в радианах. Преобразование из градусов в радианы:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Блок Арксинус¶
Описание: Блок функции “Арксинус” производит операцию нахождения угла от значения синуса, поданного на входе. Значение угла берется из правой координатной плоскости (угол от -90 градусов до 90 градусов). Выходное значение округляется до шестого разряда после запятой. Блок работает только с дробными типами данных, выбор типа данных не доступен.
Пример: на вход блока подано значение 0,5. Арксинус от него равен 0,523599, что примерно равно π/6:
Внимание! Блок не поддерживается в устройствах: Z40x, M1xx!
Внимание! Передавать значение косинуса блоку имеет смысл только в диапазоне от от -1 до 1 (включительно), в противном случае, на его выходе будет 0. Блок выдает значение угла только в радианах.
Для преобразования угла из радианов в градусы необходимо угол в радианах разделить на π и умножить на 180. Для этого можно воспользоваться блоком умножения:
- На первый вход можно подать значение угла и выбрать операцию умножения.
- На второй выход 3,141593 (число пи, округленное до шести знаков после запятой) и выбрать операцию деления.
- На третий вход 180 и выбрать операцию умножения.
На выходе блока будет значение исходного угла в градусах. Преобразование из радиан в градусы:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Блок Косинус¶
Описание: Блок функции “Косинус” производит операцию нахождения косинуса от значения угла, поданного на входе. Выходное значение округляется до шестого разряда после запятой. Блок работает только с дробными типами данных, выбор типа данных не доступен.
Пример: на вход блока подано значение 3,141593, что примерно равно π. Косинус от него равен -1:
Внимание! Блок не поддерживается в устройствах: Z40x, M1xx!
Внимание! Блок принимает значение угла только в радианах.
Для преобразования угла из градусов в радианы необходимо угол в градусах разделить на 180 и умножить на π. Для этого можно воспользоваться блоком умножения:
- На первый вход можно подать значение угла и выбрать операцию умножения.
- На второй выход 3,141593 (число пи, округленное до шести знаков после запятой) и выбрать операцию умножения.
- На третий вход 180 и выбрать операцию деления.
На выходе блока будет значение исходного угла в радианах. Преобразование из градусов в радианы:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Блок Арккосинус¶
Описание: Блок функции “Арккосинус” производит операцию нахождения угла от значения косинуса, поданного на входе. Значение угла берется из верхней координатной плоскости (угол от 0 градусов до 180 градусов). Выходное значение округляется до шестого разряда после запятой. Блок работает только с дробными типами данных, выбор типа данных не доступен.
Пример: на вход блока подано значение 0. Арккосинус от него равен 1,570796, что примерно равно π/2:
Внимание! Блок не поддерживается в устройствах: Z40x, M1xx!
Внимание! Передавать значение косинуса блоку имеет смысл только в диапазоне от от -1 до 1 (включительно), в противном случае, на его выходе будет 0. Блок выдает значение угла только в радианах.
Для преобразования угла из радианов в градусы необходимо угол в радианах разделить на π и умножить на 180. Для этого можно воспользоваться блоком умножения:
- На первый вход можно подать значение угла и выбрать операцию умножения.
- На второй выход 3,141593 (число пи, округленное до шести знаков после запятой) и выбрать операцию деления.
- На третий вход 180 и выбрать операцию умножения.
На выходе блока будет значение исходного угла в градусах. Преобразование из радиан в градусы:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Блок Тангенс¶
Описание: Блок функции “Тангенс” производит операцию нахождения тангенса от значения угла, поданного на входе. Выходное значение округляется до шестого разряда после запятой. Блок работает только с дробными типами данных, выбор типа данных не доступен.
Пример: на вход блока подано значение 0,785398, что примерно равно π/4. Тангенс от него равен 1:
Внимание! Блок не поддерживается в устройствах: Z40x, M1xx!
Внимание! Блок принимает значение угла только в радианах.
Для преобразования угла из градусов в радианы необходимо угол в градусах разделить на 180 и умножить на π. Для этого можно воспользоваться блоком умножения:
- На первый вход можно подать значение угла и выбрать операцию умножения.
- На второй выход 3,141593 (число пи, округленное до шести знаков после запятой) и выбрать операцию умножения.
- На третий вход 180 и выбрать операцию деления.
На выходе блока будет значение исходного угла в радианах. Преобразование из градусов в радианы:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Блок Арктангенс¶
Описание: Блок функции “Арктангенс” производит операцию нахождения угла от значения тангенса, поданного на входе. Значение угла берется из правой координатной плоскости (угол от -90 градусов до 90 градусов). Выходное значение округляется до шестого разряда после запятой. Блок работает только с дробными типами данных, выбор типа данных не доступен.
Пример: на вход блока подано значение 1. Арктангенс от него равен 0,785398, что примерно равно π/4:
Внимание! Блок не поддерживается в устройствах: Z40x, M1xx!
Внимание! Блок выдает значение угла только в радианах.
Для преобразования угла из радианов в градусы необходимо угол в радианах разделить на π и умножить на 180. Для этого можно воспользоваться блоком умножения:
- На первый вход можно подать значение угла и выбрать операцию умножения.
- На второй выход 3,141593 (число пи, округленное до шести знаков после запятой) и выбрать операцию деления.
- На третий вход 180 и выбрать операцию умножения.
На выходе блока будет значение исходного угла в градусах. Преобразование из радиан в градусы:
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Пользовательский блок – макрос¶
Для упрощения процесса разработки управляющей программы и ее большей наглядности, необходимо использовать “структурно-ориентированный подход”. Суть подхода заключается в том, чтобы разбить проект на отдельные блоки, реализующие целевые функции, и организовать между ними необходимые связи.
Эти блоки могут быть созданы и отлажены как отдельные (стандартные) компоненты и затем многократно использоваться в разных проектах, что, безусловно, ускорит их разработку. Кроме того, такой блок может со временем совершенствоваться, при этом, изменения в отдельном блоке не повлияют на проект в целом.
Функция Макросы предназначена для создания отдельных подпрограмм с помощью стандартных FBD-блоков, сохранения их в виде макросов и, затем, использования в виде обычных FBD-блоков в основном проекте.
Для создания макроса необходимо в Обозревателе проекта вызвать контекстное меню у FBD-программы , в которую мы хотим добавить макрос (или в любую ее подпапку), и выбрать команду Добавить. . В появившемся окне выбрать объект FBD-макрос (.xml), указать его имя и нажать кнопку Добавить . После этого макросхема будет добавлена в выбранное место.
Работа с элементами происходит также как и в основной FBD-программе, но добавляется возможность создавать входы и выходы макроса, и при этом недопустимо создавать физические блоки.
Блоки Управления¶
Блок ПИ-регулятор¶
Описание: Блок ПИ-регулятор осуществляет регулирование значения на выходе U по закону “пропорционально-интегрального регулирования”.
На вход SET подается уставка регулируемого значения, к которому будет стремиться регулятор.
На вход Sensor приходит реальное значение регулируемой величины от датчика обратной связи.
На вход Tqut подается время квантования. dI — коэффициент интегральной составляющей.
dP — коэффициент пропорциональной составляющей.
Umax — максимальное значение управляющего сигнала.
Umin — минимальное значение управляющего сигнала.
Сформированный управляющий сигнал U осуществляет управление оборудованием, которое влияет на регулируемую величину.
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Блок Стек¶
Описание: Блок функции “Стек” сохраняет массив переменных заданного типа данных. Максимальное количество значений в стеке (размер массива) указывается в свойстве «Размер» блока (см. ниже “Свойства блока”). Значения записываются и считываются по принципу «первый вошел – последний вышел».
На вход val подается значение, записываемое в стек.
На вход push (команда «втолкнуть») для записи значения со входа val нужно подать значение 1 в течение 1 шага работы схемы. Записываемое значение становится «вершиной стека», ранее записанные значения сдвигаются вниз, а количество значений в стеке, отображаемое на выходе depth , увеличивается на 1.
Вход pop (команда «вытолкнуть») используется для возврата к предыдущему записанному значению (оно становится «вершиной стека»), при этом текущее значение «вершины стека» стирается, а количество значений в стеке, отображаемое на выходе depth , уменьшается на 1.
Внимание! Если выход, подключенный ко входу push (также, как и ко входу pop ), выдает неизменные 1 в течение некоторого интервала времени, блок будет выполнять команду каждый шаг. Если нужно выполнять команду по фронту подаваемого сигнала, нужно установить соответствующим образом свойство входа “Тип входа”.
Выход top выдает значение “вершины стека”, если стек пустой – значение 0. Выход depth выдает количество значений в стеке, оно не может быть больше указанной «максимальной глубины» стека.
Выход err выдает признак ошибки — если подана команда push при полностью заполненном стеке ( push = 1 и depth = «макс. глубина»), или если подана команда pop при пустом стеке ( pop = 1 и depth = 0). При выдаче err = 1 состояние стека не меняется.
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: допускаются любые типы данных из предложенных.
Макс. глубина: в данном пункте устанавливается предельное количество значений в массиве, которые могут быть записаны в стек.
Блок Очередь¶
Описание: Блок функции “Очередь” cохраняет массив переменных заданного типа данных и фиксированной длины. Количество значений в очереди (размер массива) указывается в свойстве «Длина очереди» (см. ниже “Свойства блока”). Значения записываются и считываются по принципу FIFO — «первый вошел – первый вышел».
Вход val используется для подачи значения, записываемого в очередь.
Для записи в очередь значения со входа val , на вход push (команда «втолкнуть») нужно подать значение 1 в течение 1 шага работы схемы. Записываемое значение становится в первую позицию очереди, ранее записанные значения сдвигаются в следующую позицию. Внимание! Если выход, подключенный ко входу push, выдает неизменные 1 в течение некоторого интервала времени, блок будет выполнять команду каждый шаг. Если нужно выполнять команду по фронту подаваемого сигнала, нужно установить соответствующим образом свойство входа “Тип входа”.
Выход last выдает значение первого записанного элемента в очередь, при условии, что за ним еще 9 значений во очереди. Если количество записанных элементов в очереди меньше длины очереди – на выход last выдается 0. Значения, позиция в очереди которых больше длины очереди, не сохраняются.
Таким образом, данный блок выполняет “задержку” значения, подаваемого на вход, на указанное количество шагов. Например, для задержки на 10 секунд нужно на вход push подать сигнал таймера с периодом 1000 мсек, а в свойстве “Размер” указать 10. Блок будет хранить 10 последних значений и выдавать на выход самое старое из них.
Свойства блока: (ПКМ по блоку — Свойства ( Alt + P ))
Общие свойства: см. Редактирование свойств блока.
Тип данных: допускаются любые типы данных из предложенных.
Размер очереди: в данном пункте устанавливается предельное количество значений в массиве, которые могут быть записаны в очередь.
Прочие блоки¶
Индикатор¶
Блок Индикатор для панели Z031
Описание: Этот блок позволяет управлять выводом информации на индикатор контроллера Z031. Описание всех входов приведено в таблице ниже. Этот блок может располагаться только на главной FBD-схеме. Для того, что-бы его поместить туда, необходимо перетащить элемент Индикатор из дерева проекта на FBD сцену:
Шаблонные FBD-блоки¶
Шаблонные блоки предназначены для ускорения создания различных алгоритмов для FBD-программы. Создание программы для такого блока не сопровождается написанием программы с использованием языка FBD, вместо этого применяются различные редакторы в виде форм, таблиц, мастеров и т.д.
Имеются следующие шаблоны:
Таблица ПЗУ¶
Этот шаблон организует таблицу с заданным количеством строк и столбцов, которая хранится в ПЗУ контроллера.
Параметр Начальный адрес задает стартовый адрес расположения таблицы в ПЗУ.
Параметр Конечный адрес вычисляется автоматически на основании размера таблицы и содержащихся в нем типов данных.
Внимание! Используемый диапазон ПЗУ не проверяется на пересечение с адресами ПЗУ локальных переменных FBD-схемы и должен контролироваться пользователем самостоятельно.
Размерность таблицы задается параметрами Количество строк таблицы и Количество полей таблицы .
Каждое поле имеет название, которое будет идентифицировать это поле в FBD-программе, и тип данных. Порядок следования полей можно менять с помощью кнопки Вверх , которая перемещает выбранное поле на одну позицию вверх по списку.
Параметр Способ выбора строки позволяет установить способ выборки из таблицы.
Существуют три варианта этого параметра:
- Массив – по индексу строки
- Журнал событий – по порядковому номеру события
- Поиск строки по значению 1-го поля
Более подробно режимы выборки будут рассмотрены далее.
Шаблонный блок таблицы ПЗУ
Для добавления шаблона в FBD-программу необходимо перетащить его из дерева Навигатора проекта на FBD-схему. В зависимости от выбранного параметра Способ выбора строки блок будет выглядеть по-разному. Кроме того, состав входов и выходов блока меняется в зависимости от параметра Тип блока , который устанавливается в его свойствах. Этот параметр может принимать три значения: Чтение , Запись , Сброс .
Массив – по индексу строки¶
Запись:
Чтение:
Этот способ использует произвольную выборку и запись строк по индексу (номеру строки). Индексы начинаются с 0.
В режиме чтения блок имеет один вход – row , на который подается номер нужной строки. Тип входа – беззнаковый целый 2-х байтовый . Значение, подаваемое на вход, должно быть меньше количества строк, указанного в настройке шаблона, т.е. в диапазоне от 0 до <кол-во строк> — 1. На логический выход err выдается сигнал в том случае, если значение, поданное на вход row , выходит за допустимый предел. На остальных выходах, названия которых соответствует названиям полей, заданных в шаблоне, устанавливаются значения, взятые из соответствующей строки таблицы. Тип данных для этих выходов так же соответствует типу данных, заданному в полях шаблона.
В режиме записи блоки также имеет вход row , указывающий номер строки. Вход en активирует запись параметров в строку таблицы. Остальные входы служат для установки значений в соответствующие поля таблицы. Выход err сигнализирует об ошибке, аналогично блоку чтения.
Журнал событий – по порядковому номеру события¶
Чтение:¶
Запись:¶
Сброс:¶
В этом режиме таблица организована в виде журнала, который хранит некоторое количество последних записей. Это количество задается параметром шаблона Количество строк таблицы . Кроме того, шаблон хранит номер последнего записываемого события.
На рисунке схематично представлен способ хранения информации. В данном примере таблица состоит из 4 строк, то есть хранит последние 4 записи журнала, от записи 4 до записи 7.
Режим чтения журнала блока имеет один вход event , который в отличие от входа предыдущего режима, задает номер события для выборки. На выходах from и to устанавливаются номера событий начала и конца журнала, которые хранятся в ПЗУ в данный момент. Выход err сообщает об ошибке выборки события, поданного на вход event . На остальных выходах, название которых соответствует названию полей, заданных в шаблоне, устанавливаются значения, взятые из соответствующего события журнала.
У блока записи отсутствует вход, указывающий записываемый номер события, так как блок нумерует автоматически. Выходы from и to , аналогично блоку чтения, отображают диапазон событий, хранящихся в журнале. Режим сброса используется в том случае, если нужно очистить журнал. При подачи сигнала на вход en внутренний счетчик событий сбрасывается в 0 и журнал можно заново заполнять значениями.
Поиск строки по значению 1-го поля¶
Этот способ работы аналогичен журналу событий, за исключением работы блока в режиме чтения.
При выборе этого способа вход event заменяется на вход value . Этот вход соответствует первому полю таблицы и имеет такой же тип данных. При установке значения на этот вход блок чтения журнала выдаст на выход данные с первой найденной строкой, у которой первое поле равно этому значению. Если таковых строк не найдено, то на выходе err будет выдан сигнал ошибки.
Связи¶
Связи используются для подключения входов и выходов блоков.
В программе существует 2 вида связей:
обычная связь — обозначается линией между элементами:
именованная связь – обозначается флажками с именем связи напротив выхода и входов:
На ножку выхода можно добавить неограниченное количество связей. Связи, выходящие из одного выхода, имеют одинаковое имя. Ответвления линий этих связей друг от друга обозначаются точками. Ко входу можно подключить только одну связь. Связь не может существовать без соединения с блоками (т.е. не может висеть в воздухе).
Создание обычной связи¶
Для создания обычной связи выделите левой кнопкой мыши вход(выход) и, не отпуская кнопку, переместите указатель мыши на другой выход(вход). В процессе перемещения указателя мыши связь будет прорисовываться пунктирной линией. После отпускания кнопки над выходом(входом) связь будет зафиксирована в виде сплошной линии.
Создание именованной связи¶
Для создания именованной связи кликните левой кнопкой мыши на выход, одновременно удерживая кнопку Shift на клавиатуре. Программа перейдет в режим создания именованной связи, на что будет указывать специфический вид курсора. После этого можно можно, кликая на входы, создавать последовательно несколько именованных связей, идущих из одного выхода. Для отмены режима создания именованной связи нажмите кнопку Esc или кликните правой кнопкой мыши в любом месте схемы. Начать построение именованной связи можно только с выхода.
Редактирование связи¶
Переключение вида связей производится командами “Простая связь” и “Именованная связь”. Для быстрого поиска начала и конца связи, в случае когда они удалены на большое расстояние друг от друга, можно использовать команды В конец и В начало . Команда В начало выделяет выход, от которого начинается связь и помещает его, по возможности, в центр экрана. Команда В конец выделяет вход, к которому подключена связь, и помещает его так-же в центр экрана. Если на схеме выделены несколько связей, начинающиеся от одного выхода, то команда В конец будет по циклу перебирать все входы, к которым подключены эти связи.
Расположение линий обычной связи можно изменять с помощью мыши. Для этого подведите указатель мыши к горизонтальной или вертикальной линии связи и, когда он примет характерный вид, можно перемещать участки линий по горизонтали или вертикали. Линии, прилегающие непосредственно ко входу и выходу не перемещаются. В обычной связи можно добавлять сегменты (дополнительные изгибы) путем выбора команды Добавить сегмент в контекстном меню связи. Имя связи можно изменить в редакторе свойств. Эта команда действует для всех связей, подключенных к одному выходу. Для закрепления/снятия закрепления связи надо вызвать контекстное меню связи (правой кнопкой мыши) и нажать закрепить/освободить
На панели управления “Связи” можно включить и выключить трассировку именованных связей, для этого выделить связь и нажать на кнопку показать трассировку.
Для перемещения связи на другой вход или выход вызываем контекстное меню ножки со связью (правой кнопкой мыши) и нажимаем перенос связей. Возле курсора появится характерный значок. Затем нажимаем левой кнопкой мыши на ножку, на которую мы хотим переместить связь. Для переноса всех связей блока на другой блок надо выделить блок и выбрать команду Перенос связей . Все существующие связи будут перенесены на новый блок по порядку следования. Если количество входов или выходов у целевого блока меньше, то лишние связи останутся на старом месте.
Переменные¶
В любую схему можно добавить локальные переменные (или глобальные). Область видимости этих переменных ограничена текущей схемой. На рисунке показан внешний вид окна локальных переменных. В верхней части находится панель для управления и редактирования переменных:
Для создания переменной нажать на кнопку + . Переменная будет добавлена в список и откроется Редактор свойств переменной:
В данном пункте устанавливаются требуемые параметры переменной — название, тип данных, константность, значение по умолчанию, доступность по modbus (права доступа, адрес) сохранение в ПЗУ (адрес в ПЗУ). Название переменной – текстовый идентификатор переменной, который отображается на схеме в блоках чтения и записей переменных. Рекомендуется использовать в именах только латинские символы или цифры.
Тип данных – тип данных переменной. Выбирается из следующего списка:
- Логический;
- Беззнаковый целый 1-байт;
- Беззнаковый целый 2-байт;
- Беззнаковый целый 4-байт;
- Знаковый целый 1-байт;
- Знаковый целый 2-байт;
- Знаковый целый 4-байт;
- Дробный 4-байт.
Начальное значение – начальное значение переменной.
Константа – этот флаг означает, что переменная является константой.
Запись в ПЗУ – этот флаг указывает, что переменная должна сохранять свое значение в ПЗУ и восстанавливать его после включения контроллера. Адрес ячейки ПЗУ, по которому сохраняется переменная, устанавливаются в соответствующем списке.
Сетевой доступ – настройка доступа к переменной по сети. Доступны три варианта этого параметра:
- Нет: Переменная не доступна по сети;
- Чтение: Переменная доступна только для чтения по сети;
- Чтение/Запись: Переменная доступна для чтения и записи по сети.
Параметры доступа по сети устанавливаются в соответствующем списке сетевых переменных, который можно открыть для редактирования и просмотра командой в верхней панели окна редактирования переменных.
Для фильтрации переменных по параметру нужно выделить ячейку таблицы, и нажать на кнопку. На таблицу будет наложен фильтр с текущим значением, которое было в выделенной ячейки. Например, если выбрать ячейку таблицы Modbus, в которой стоит отмеченный флажок, то при фильтрации будут отображаться только те переменные, у которых стоит флаг доступа по Modbus.
Фильтр может использоваться многократно (с наложением). Для удаления фильтров необходимо нажать кнопку “Удалить фильтр”
Для удаления переменной используется кнопка delete на клавиатуре или команда Удалить .
Для использования переменной в проекте нужно на схеме поместить блок работы с переменной. Для этого нужно перетащить переменную левой кнопкой мыши в окно схемы.
Блок чтения переменной:
Блок записи переменной:
Блок условной записи переменной:
Блок записи переменной по Modbus:
По умолчанию создается блок Чтения переменной. В любой момент можно изменить привязку блока на другую переменную, выбрав нужную из списка. Существует четыре вида блоков переменной:
- Чтение – значение переменной считывается;
- Запись – значение, поданное на вход блока, записывается в переменную;
- Условная запись — значение, поданное на вход блока, записывается в переменную, если на входе en установлена 1;
- Запись по Modbus — этот блок позволяет, в режиме подчиненного устройства Modbus, обработать команду записи, полученную от главного. На выходе val появляется (на время одного цикла) значение, полученное в команде записи, а на выходе rdy — признак получения команды записи. При отсутствии команды на этих выходах всегда присутствует 0. Значения выходов блока зависят только от главного устройства! Для записи пришедшего значения необходимо осуществить преобразования как на рисунке внизу. Т.е. по сути, это та же условная запись переменной.
Блок записи по Modbus:
Примечание: блок Запись Modbus выполняет сначала обработку выходов, затем, в конце шага схемы – обработку входов, т. е. производит обработку своих входов с задержкой на один цикл.
По сути, это та же условная запись переменной. Но! Данный блок объединяет в себе три операции: блок чтения (если выход VAL получает значение в режиме подчиненного устройства Modbus, то на выходе RDY устанавливается логическое значение 1, признак получения команды записи), блок условной записи (на вход VAL записывается обработанное значение, при условии, что вход EN получил логическое значение 1) и блок вывода ошибки ER.
Обработка значения переменной выполняется согласно поставленной задаче.
Пример: записать в переменную VAR4 значение X, если на выход VAL получено X < 20. Во-первых, сравниваем X с числом 20 (блок сравнения), во-вторых, чтобы запись значения произошла, нужно, чтобы на входе EN была установлена 1. Для этого выход блока сравнения и выход RDY объединим блоком AND, а выход блока AND соединим со входом EN, значение на выходе VAL соединим со входом VAL.
Итак, если два условия истинны, то в переменную VAR4 будет записано значение, полученное на выходе VAL. Но есть еще блок вывода ошибки ER. Если значение, поданное на выход VAL не удовлетворяет условию блока сравнения, то на выходе блока AND установится 0, и вход EN получит 0, а вход ER должен выдать номер ошибки, почему не произведена запись в переменную. Ошибка 03 – неверные данные запроса.
При получении на вход IF 1 блок Условие подаст на вход ER 0, в противном случае вход ER получит номер ошибки3.
Внимание! Не следует путать значение, полученное в команде записи, со значением переменной! Выход «val» не выдает значение переменной.
Изменить тип блока, если к нему подключена хоть одна связь невозможно. Если переменную перетащить на ножку блока или макроса, то связь образуется автоматически и блок принимает нужны тип, в зависимости от того, на вход или выход перетаскивали переменную.
Еще одной важной особенностью блоков записи в переменную является приоритет записи, устанавливаемый в свойствах блока. Данное свойство позволяет писать значения в одну и ту же переменную при разных условиях и из разных мест в программе. Чем выше значение, тем выше приоритет, т.е. блок записи с приоритетом 100 имеет больший приоритет записи в переменную чем блок записи со значением 10. Это значит, что если одновременно придет сигнал записи новых значений в данные блоки, то в переменную запишется значение из блока записи с приоритетом 100.
Переменные контроллера¶
В каждом контроллере, который содержит FBD-программу содержится определенный набор переменных, который зависит от типа контроллера. Эти переменные делятся на группы:
- Аналоговые входы
- Аналоговые выходы
- Дискретные входы
- Дискретные выходы
- Универсальные входы
- Состояние устройства
- Параметры порта
- Диагностика порта
Все переменные устройства можно использовать в главной схеме FBD-программы, так-же, как и локальные переменные. Вставлять переменные контроллера в макросхемы запрещено.
Входы и выходы
Переменные, описывающие входы и выходы устройства. Их количество и тип данных, для аналоговых переменных, зависит от типа контроллера. Блоки, создаваемые для чтение или записи этих переменных имеют следующий вид:
Аналоговый вход:
Дискретный вход:
Аналоговый выход:
Дискретный выход:
Универсальный входы:
В свойствах блоков входов/выходов на сцене можно включить симуляцию. Этот параметр позволяет отключать физические входы и выходы контроллера и управлять ими через панель симулятора.
Параметры порта
Переменные для управления параметрами порта контроллера, а так же адресом контроллера.
Адрес контроллера — эта переменная содержит текущий адрес контроллера, по которому к нему может обращаться мастер. Так же как и локальная переменная, эта переменная имеет настройку сетевого доступа и флаг сохранения в ПЗУ. В случае, если необходимо запретить изменение этого параметра извне, необходимо установить значение сетевого доступа “нет” или “чтение”. По умолчанию сетевой доступ равен “чтение/запись”, флаг записи в ПЗУ установлен. Использование этой переменной на схеме происходит так же, как и использование локальных переменных.
Параметры порта — эта переменная определяет параметры порта устройства. Для Modbus RTU это скорость и четность порта. Тип данных переменной — Беззнаковый целый 1-байт .
старшая тетрада — четность порта
- 0 — нет/none
- 1 — нечет/odd
- 2 — чет/even
- 3 — метка/mark
- 4 — пробел/space
младшая тетрада — скорость порта
- 0 — 9600
- 1 — 2400
- 2 — 4800
- 3 — 9600
- 4 — 19200
- 5 — 38400
- 6 — 57600
- 7 — 115200
Например, если переменная имеет значение 0x23, то параметры порта следующие 9600-чет.
Список поддерживаемых скоростей и четностей может отличаться у различных устройств.
Так же как и для адреса, для этих переменных можно установить свойства, запрещающие изменять параметры порта. По умолчанию сетевой доступ равен “чтение/запись”, флаг записи в ПЗУ установлен.
Состояние устройства
Код ошибки — беззнаковая целая 1-байт. переменная, в которой хранится код внутренней ошибки контроллера.
- 1 — Ошибка чтения ПЗУ. Сбой процедуры чтения из ПЗУ контроллера. Возможно аппаратная неисправность.
- 2 — Ошибка записи ПЗУ. Сбой процедуры записи в ПЗУ контроллера.Возможно аппаратная неисправность.
- 3 — Слишком часто изменяется состояние дискретных выходов. Допускается изменение выходов не чаще чем 1 раз в секунду.
- 4 — Слишком часто происходит запись в ПЗУ. Допускается запись не чаще чем 1 раз в секунду. Запись происходит только в том случае,если значение изменяется.
- 7 — Слишком маленький интервал базового таймера, не успевает выполняться интерпретатор.
- 8 — Не реализованная функция Modbus.
- 10 — Ошибка очистки ПЗУ.
- 11 — Ошибка инициализации переменных адреса и параметров порта, значения загружены по умолчанию.
При возникновении ошибки FBD программа продолжает выполняться, однако в случае ошибок 3 и 4, которые критичны к безопасности контроллера, происходит блокировка этих действий. То есть соответственно блокируется запись в ПЗУ или в дискретные выходы. Эту переменную рекомендуется использовать в схеме для анализа ошибок. При отсутсвии этой переменной программа при проверке будет выдавать предупреждение. По умолчанию сетевой доступ к переменной установлен в “чтение/запись”.
Аналоговые входы¶
Блок чтения переменной аналогового входа контроллера. Имеет один выход с типом данных беззнаковое 2-байт. целое. В качестве дополнительной настройки можно указать параметр “Время фильтра”. Этот параметр задает время в мсек., в течении которого контроллер осредняет значение, поступающее на аналоговый вход. По умолчанию значение времени фильтра равно 0. В этом случае фильтрации не происходит. Максимальное значение — 2047 мсек.
Внимание: В программах с версией меньше 1.0.111 этот параметра располагался в свойствах блока, с версии 1.0.111 этот параметр находится в свойствах соответствующей переменной устройства. При открытии или импорте файлов более старых версий, необходимо вручную установить нужное значение в переменную устройства, так как значение, хранящееся в блоке, будет утеряно.
Аналоговые выходы¶
Блок записи для переменной аналогового выхода контроллера. Имеет один вход с типом данных беззнаковое 2-байт. целое. Подаваемое значение должно находится в диапазоне от 0 до 1023. Значение 0 соответствует 0 вольт на выходе, значение 1023 — 10 вольт. В качестве дополнительной настройки можно указать параметр “Пользовательский ШИМ”. При установке этого флага у блока появляется дополнительный вход T PWM — период ШИМ модуляции в мсек. На первый вход, в этом случае, должно подаваться значение в мсек., в течении которого выход выдает полное значение напряжения.
Блок аналогового выхода с установленным параметром “Пользовательский ШИМ”:
Внимание: В программах с версией меньше 1.0.111 параметр “Пользовательский ШИМ” располагался в свойствах блока. с версии 1.0.111 этот параметр находится в свойствах соответствующей переменной устройств, и устанавливать его необходимо до вытаскивания блока на схему. После вытаскивания блока этот параметр для редактирования не доступен. Для его изменения нужно удалить блок со схемы, изменить параметр в свойствах переменной устройства и снова вытащить его на схему. Автоматический перенос свойств при импорте или открытии файла старой версии не происходит. Если при открытии или импорте будет выдано предупреждение в список событий, то необходимо удалить текущий блок со схемы и заново его создать с нужными свойствами.
Дискретные входы¶
Блок чтения для переменной дискретного входа контроллера. Имеет один выход с логическим типом данных. Дополнительные настройки отсутствуют.
Дискретные выходы¶
Блок записи для переменной дискретного выхода контроллера. Имеет один вход с логическим типом данных. Дополнительные настройки отсутствуют.
Универсальные входы¶
Универсальные входы могут работать в четырех режимах: дискретный, аналоговый, аналоговый высокоомный и счетный. Режим работы дискретного и аналогового входов такой же как и у простых входов. Высокоомный вход отличается тем, что у него другой номинал шунтирующего резистора, поэтому у него используется другая формула для расчета сопротивления. Счетный вход — это особый режим работы. Значение на его выходе равно количеству импульсов, которые пришли на вход за время одного цикла работы FBD-программы. Поэтому для работы с ним необходимо использовать блок суммирования для накапливания значения в локальной переменной.
Использование счетного входа:
При вытаскивания на схему этих переменных создаются блоки, описанные в Аналоговые входы и Дискретные входы, а название внутри блока определяет его назначение.
Блоки универсальных входов:
Внимание: В программах с версией меньше 1.0.111 при вытаскивании универсальных входов на схему создавался специальный блок. В новых версиях этот блок считается устаревшим.
Устаревшие блоки универсальных входов:
При открытии или импорте старого файла необходимо заменить их на новые, путем удаления и повторного вытаскивания на схему.
Внимание: В программах с версией меньше 1.0.111 назначение входа изменялось в свойствах блока. Начиная с версии 1.0.111 установка назначения входа производится в свойствах переменной устройства. После того, как блок для переменной создан, изменить его назначение нельзя. Для смены типа блока нужно удалить его со схемы, изменить свойство переменной устройства и снова вытащить блок на схему.
Диагностика порта¶
В этой группе находятся переменные для диагностики ошибок работы с портом.
Более подробно они описаны в разделе “Переменные устройства для обработки ошибок MODBUS”.
Глобальные переменные¶
Глобальные переменные работают почти так же, как и обычные переменные контроллера. Одно из отличий заключается в том, что глобальные переменные являются общими для всех макросов контроллера. Список глобальных переменных находится в Обозревателе проекта внутри шаблона контроллера и называется Глобальные переменные . По двойному нажатию на этот элемент откроется окно (или вкладка) Глобальные переменные :
В окне присутствует верхнее меню для редактирования списка. В него включены следующие кнопки:
- Добавить — добавление новой переменной (если выделена группа, новая переменная будет добавлена в нее);
- Добавить группу — добавление группы переменных для удобства представления или хранения данных в виде структуры:
- Удалить — удаляет переменную, если выбрана переменная, или группу со всеми переменными, входящими в нее;
- Кнопка со стрелками — служит для быстрого сворачивания/разворачивания групп.
Двойным щелчком мыши по строке с переменной (или группой) открывается окно Свойств переменной , где можно задать ее название, тип и т.д.:
Все свойства соответствуют таковым в обычной переменной, за одним исключением — поле Размер массива . Переменная может быть массивом, если указать размер больше единицы. И тогда к ней можно будет обращаться по индексу в блоках чтения и записи. Также, размер массива можно устанавливать и для групп.
Для добавления глобальной переменной на сцену FBD-программы необходимо выделить элемент проекта Глобальные переменные , затем перетащить нужную переменную из области в нижней части Обозревателя проекта в нужное место на сцене:
Сверху изображена глобальная переменная, с Размером массива 1, которая ведет себя подобно обычной переменной. Снизу находится глобальная переменная со свойством Размер массива больше единицы. На вход этот блок принимает индекс, по которому будет осуществляться чтение из данного массива.
Массивы и группы нужны для упрощения создания переменных для однотипных объектов. Возьмем, к примеру, несколько одинаковых контроллеров, у которых есть набор переменных: температура, влажность, содержание CO2. Контроллер, который является мастером для них должен собирать эту информацию и затем отображать на индикаторе или хранить для дальнейшего использования. С помощью групп и массивов это можно сделать следующим образом:
- Создаем группу глобальных переменных;
- Устанавливаем группе размер массива (например, 5):
- Создаем схему для чтения данных из устройства и записи значений в глобальные переменные:
Переменная Address содержит адрес устройства. Этот адрес подается на блок чтения Modbus и на индексный вход блока записи переменной.
- Теперь можно читать данные из этих переменных с помощью блока чтения, подавая на вход индекса константу или динамическое значение:
Переменные MODBUS¶
Элемент «Переменные modbus» в шаблоне контроллера, работающего в режиме главного устройства, позволяет упрощенно обращаться к переменным подчиненного контроллера.
Для каждого экземпляра подчиненного контроллера нужно добавить отдельный пункт «Переменные modbus»:
Редактирование списка переменных доступно вручную. Возможен импорт переменных из файла с расширением mbm. Этот файл можно получить, экспортируя сетевые переменные из любого шаблона программы.
Кроме того, при перетаскивании мышью шаблона подчиненного устройства в окно списка в список добавляются все сетевые переменные подчиненного устройства. Предполагается, что для каждого подчиненного контроллера в главном будет создаваться отдельно один или несколько списков переменных, поэтому настройки адреса подчиненного и другие его опции относятся к списку в целом.
Список переменных MODBUS:
Переменные, содержащиеся в списке, могут использоваться в FBD-программе так же, как и глобальные переменные. Отличие заключается в том, что переменные modbus автоматически синхронизируются с подчиненным устройством. Если требуется хранение переменной при выключенном питании, то это должен реализовать подчиненный контроллер.
Кроме основных свойств, аналогичных глобальным переменным, у переменных Modbus есть параметр “Задержка”. Этот параметр задается в миллисекундах и определяет частоту, с которой будет опрашиваться переменная.
Синхронизация выполняется по алгоритму:
- После начала работы контроллера он выполняет первоначальное чтение — читает значения из подчиненного (имеется логическая переменная, имеющая в начале значение 1, сбрасываемая при получении правильного ответа на команду чтения);
- Если значение переменной изменяется программой главного контроллера, и в этот момент не было ответа от подчиненного с прочитанным значением, включается запись нового значения в подчиненный (имеется логическая переменная, имеющая в начале значение 0, устанавливаемая при указанном условии и сбрасываемая при получении правильного ответа на команду записи);
- Периодически чтение значения из подчиненного повторяется (имеется логическая переменная, имеющая в начале значение 0, устанавливаемая по таймеру и сбрасываемая при получении правильного ответа на команду чтения).
Команды чтения-записи в случае ошибки повторяются бесконечно.
Кроме того, в случае ошибки устанавливается переменная первоначального чтения. То есть, при неудаче записи попытки записи и чтения будут повторяться, пока значения в главном и подчиненном не сравняются.
Переменные при создании команд чтения-записи автоматически группируются при наличии такой возможности, а именно, при совпадении кодов команд и при последовательном расположении регистров/коилов. При группировке учитывается максимальный размер буфера приема-передачи в главном и подчиненном устройствах. Таким образом, при последовательном расположении регистров и небольшом количестве переменных может быть единственная команда чтения и единственная команда записи (в текущей версии такую группировку полностью отменить невозможно, а можно только разделить один элемент «Переменные modbus» на несколько, при этом объединение переменных выполняется отдельно в каждом списке).
Функции modbus в командах выбираются автоматически. Для чтения используются функции modbus 1 и 3, в зависимости от типа данных, для записи – функции 5, 6, 15, 16, в зависимости от типа данных и количества записываемых регистров/коилов.
Добавление блока «Переменные modbus» на сцену FBD-программы:
Состояние синхронизации можно получить в FBD-программе, вытащив мышкой элемент «Переменные modbus». Создается блок с выходами err , reading , writing . Выход err – код ошибки команд записи или чтения, полученных в данный момент, собирается с соответствующих выходов err блоков чтения-записи.
Выход reading – признак выполнения первоначального чтения (или его повтора после ошибки чтения-записи).
Выход writing – признак выполнения записи в подчиненный контроллер.
В блоке невозможно определить, какая команда выдала ошибку, и какая команда выполняется в данный момент. При необходимости более точно определить статус синхронизации некоторых переменных отдельно от других, их нужно выделить в отдельный список.
Навигатор по проекту¶
Навигатор по проекту служит для быстрого поиска элементов, используемых в проекте.
Навигатор состоит из:
- списка элементов проекта;
- строки и кнопки поиска;
- кнопки фильтра;
- кнопок управления списком.
Для фильтрования отображаемых элементов нажать на кнопку фильтр и выбрать элементы для отображения в списке элементов навигатора. В навигаторе отображаются только те блоки и элементы, которые включены в основную схему непосредственно или косвенно через макросы.
Макросхемы, которые присутствуют в проекте, но не включены в главную схему напрямую или косвенно не отображаются.
Навигатор по проекту и фильтр поиска:
Для поиска элементов необходимо ввести название элемента в строку поиска и нажать на кнопку Найти . Также, найденные элементы подсвечиваются светло-желтым цветом непосредственно во время набора. Если несколько элементов соответствующих критерию поиска, то переключение между ними осуществляется с нажатием кнопки поиска. При этом в окне искомый объект будет подсвечиваться желтым цветом. Поэтому рекомендуется присваивать названия блокам осознанно, дабы упростить поиск искомых объектов в последствии.
Проверка и компиляция проекта¶
Это мощный интерактивный инструмент, обеспечивающий 100% корректности создаваемой программы. Другими словами, можно написать любую программную абстракцию, но благодаря этому инструменту она гарантированно и корректно будет исполняться на контроллере или в симуляторе. Проверку на ошибки можно запускать вручную (кнопка Проверка ). Так же проверка всегда производится перед симуляцией/компиляцией/загрузкой программы в контроллер.
В ручном режиме проверка выполняется для активной сцены/окна (например, если будет активно окно макросхемы, то проверка будет производиться только для этой схемы). Если будет активно окно главной схемы, то проверка будет производиться для всего проекта.
В случае ошибок будет выдано соответствующее предупреждение. Ошибочный элемент (блок, связь, переменная) будет помечен красным цветом . Также в окне Сообщения будут выделены проблемные участки. При двойном клике на красной строке в фокусе появится место ошибки.
Компилятор останавливает работу при первой найденной ошибке, поэтому после исправления этой ошибки, необходимо повторно запускать компиляцию, пока компиляция не пройдет успешно.
Отладка в режиме симуляции¶
Возможности симуляции и отладки FBD программы:
- проверка программы на содержание ошибок с выдачей результатов проверки в окно “Сообщения”;
- симуляция на ПК без подключенного контроллера;
- отладка в симуляторе по шагам;
- отладка в симуляторе в режиме реального времени.
Для перехода в режим симуляции контроллер должен находиться на карте сети и ему должен быть присвоен шаблон программы (подробнее: Загрузка программ в контроллер и создание сети, режим моста).
Переход в режим симуляции:
Это интерактивный инструмент, позволяющий быстро и наглядно отлаживать программу на имитированном контроллере, на входы которого можно подавать соответствующие значения. Для запуска симуляции необходимо иметь скомпилированную корректную программу, поэтому при запуске симуляции первым делом запускается компиляция. А в случае успешной компиляции вы переходите в режим симуляции.
Имитация работы реального контроллера:
В режиме симуляции вы можете перейти в окно отладки, где можете в режиме реального времени подавать значения на входы, имитирующие входы реального контроллера, и снимать результат работы программы на выходах, таким образом Вы можете наблюдать работу своей программы, что позволит на раннем этапе отладить ее максимально точно, что существенно сократит время и силы при пуско-наладочных работах. Важной особенностью инструмента, которая упрощает отладку программы, является возможность отлаживать программу как по шагам, так и в режиме реального времени, выбирая тот или иной тип.
При этом, в свойствах устройства необходимо задать соответствующие параметры для отладки.
На этой вкладке производится настройка параметров загрузки и отладки:
Установка точек отладки на все выходы — опция оптимизации отладочных программ. Во время отладки, при установленном признаке на все выходы по всей схеме устанавливаются отладочные точки — специализированные сетевые переменные. В связи с этим резко возрастает объем памяти программ контроллера в режиме отладки.
Некоторые контроллеры Zentec обладают небольшим объемом памяти. Может случиться так, что объем памяти, занимаемый отладочной программой будет превышен. В этом случае можно снять признак Установка точек отладки на все выходы и расставить отладочные точки вручную на необходимые для отладки блоки в схеме. Для этого выбираем требуемый выход, который мы хотим наблюдать в отладке и нажимаем F9 . В этом случае отладка пройдет в несколько этапов, но тем не менее данный подход дает возможность использовать почти 100% памяти программ и ОЗУ.
Включение и отключение симуляции входов и выходов производится в свойствах блока входа или выхода на сцене. Этим управляет параметр Симуляция . Это свойство позволяет отключать физические входы или выходы контроллера и управлять ими через панель симулятора:
Все созданные вручную точки отладки появляются в специальной панели Точки отладки .
Чтобы показать панель Точки отладки , необходимо нажать правой кнопкой мыши на заголовок панели Обозреватель проекта и отметить пункт Точки отладки . При этом, активным окном должно быть окно FBD-программы:
Двойным кликом мыши по строке с точкой отладки можно открыть ее свойства. Там можно задать условие, при выполнении которого симуляция будет приостановлена. Для этого надо поставить отметить пункт Останов по условию и выбрать условие для остановки.
Точки отладки можно удалить, временно деактивировать или перейти в выходу на схеме, который соответствует данной точке, нажав на соответствующие кнопки в панели Точки отладки .
Работа с сетью MODBUS¶
Принципы построения¶
Контроллеры соединяются, используя технологию мастер-подчиненный, при которой только одно устройство (мастер) может инициировать передачу (сделать запрос). Другие устройства (подчиненные) передают запрашиваемые главным устройством данные, или производят запрашиваемые действия. Типичное мастер — устройство включает в себя ведущий (HOST) процессор и панели программирования. Типичное подчиненный — устройство — программируемый контроллер, система ввода вывода, датчик и т.д. Мастер может адресоваться к индивидуальному подчиненному или может инициировать широкую передачу сообщения на все подчиненные устройства. Подчиненный — устройство возвращает сообщение в ответ на запрос, адресуемый именно ему. Ответы не возвращаются при широковещательном запросе от главного. Контроллер использует протокол Modbus/RTU для связи с другими устройствами, поддерживающими этот же протокол. Программа позволяет создавать проекты, обеспечивающие работу контроллера, как в качестве ” подчиненного”, так и “мастера”.
Основные понятия¶
Чтобы настроить работу контроллера по протоколу Modbus необходимо знать основные термины и понятия.
- Адрес подчиненного — адрес подчинённого устройства, к которому адресован запрос. Ведомые устройства отвечают только на запросы, поступившие в их адрес. Ответ также начинается с адреса отвечающего ведомого устройства, который может изменяться от 1 до 247. Адрес 0 используется для широковещательной передачи, его распознаёт каждое устройство, адреса в диапазоне 248…255 — зарезервированы;
- Скорость обмена — Диапазон скоростей, на которых осуществляется обмен данными, лежит в пределах от 2400 бит/сек до 115 200 бит/сек.
- Направление передачи — Мастер при обращении к подчиненному может считывать переменную (направление read) или одновременно записывать и ее же считывать (направление read/write).
- Запрос, ответ — Каждое обращение к подчиненному называется запросом. Запрос — это пакет, формируемый мастером, который содержит в себе как служебную информацию (адрес подчиненного, адрес переменой и т.п.), так и значение самой переменной. Запрос может содержать в себе обращение к массиву адресов памяти подчиненного, таким образом, мастер записывает или считывает целый набор переменных одного типа. Этим обеспечивается экономичность использования сети. Запрос не может содержать в себе: — одновременно команды на запись и чтение; — одновременное обращение к битовой и регистровой переменным; — одновременное обращение к 2 или более массивам адресов переменных Ответ: Если подчиненный дает нормальный ответ, код функции в ответе повторяет код функции в запросе. В байтах данных содержится затребованная информация. Если имеет место ошибка, то код функции модифицируется, и в байтах данных передается причина ошибки.
- Карта памяти — При обращении к подчиненному “мастер” должен “знать”, в какой его области памяти находится переменная, которую необходимо прочитать или записать. Поэтому, при настройке, мастеру необходимо сообщить, по какому адресу в подчиненном данная переменная находится. Источником таких данных в Modbus является карта памяти, документ, который в текстовом виде описывает адреса переменных подчиненного
- Адрес переменной — Адрес — номера ячейки памяти подчиненного, откуда надо читать или куда записывать переменную. В картах памяти может быть представлена в hex или десятичном форматах.
- Параметры порта – Каждое из подчиненных устройств имеет свои собственные настройки порта, которые необходимо учитывать при настройке мастера. Для изменения параметров портов необходимо вызвать диалог свойств контроллера и на вкладке устройство установить нужные параметры:
В этом диалоге можно установить следующие параметры портов:
- Протокол – мастер или подчиненный (см. описание Modbus):
Для более подробной настройки портов необходимо перейти на Карту сети, выбрать нужный порт нужного контроллера и открыть его свойства:
В порту можно установить следующие параметры:
- Режим работы порта – мастер или подчиненный (здесь этот параметр используется только для выбора режима программирования шаблона);
- Скорость – скорость порта (2400, 4800, 9600,19200, 38400);
- Четность – четность порта(Нет, Нечет, Чет, Метка, Пробел);
- Таймаут – время ожидания ответа от устройства;
- Диапазон адресов для поиска – диапазон Modbus-адресов, в пределах которого будет осуществляться поиск контроллеров на этом порту.
Режим подчиненного¶
Чтобы обмениваться данными с подчиненным, мастер (например, ОРС-сервер) должен обращаться к его карте памяти. Карта памяти создается автоматически, во время компиляции проекта. Компилятор берет данные для карты из локальных переменных, расположенных в схемах проекта.
Для того, чтобы переменная попала в карту памяти, необходимо установить ей соответствующую опцию, указать тип доступа и адрес:
Если установлены права Чтение , то эта переменная может только читаться функциями, зависящими от типа данных переменных.
Если установлены права Чтение/Запись , то переменная может и писаться и читаться.
В Таблице приведены функции, Modbus по которым происходит доступ к переменным в зависимости от их типа:
Установка адресов для переменных производится в окне редактирования списка сетевых переменных. Этот список генерируется автоматически для контроллера. В него входят все локальные переменные основной FBD-программы и и входящих в неё макросхем у которых установлено свойство “Сетевой доступ”:
В этом окне можно установить следующие параметры:
- Адрес — Modbus-адрес переменной. Адрес можно устанавливать как вручную, так и с помощью команды автонумерации. Если адреса переменных конфликтуют, то эти переменные будут выделены красным цветом;
- Тип данных — тип данных используемой переменной;
- Доступ — уровень доступа. Этот параметр можно изменить, то есть уровень доступа можно понизить, по отношению уровню, заданного в исходной переменной;
- Блокировка — флаг, который блокирует автонумерацию адресов;
- Комментарий — описание переменной.
При нажатии на кнопку Автонумерация производится автоматическая раздача адресов. Переменные, у которых установлен флаг блокировки, пропускаются. Раздача адресов производится с учетом типов данных переменных. Например 4-х байтовые переменные занимаю 2 регистра, соответственно адресация будет меняться с шагом 2.
В случае, если при редактировании программы некоторые макроблоки, содержащие сетевые переменные, будут удалены, ссылки на них в списке не пропадут, а будут помечены как невалидные (будут выделены желтым цветом). При проверки программы, при симуляции и программировании в устройство эти переменные не будут учитываться. Для удаления таких переменных необходимо нажать кнопку Очистить :
Режим мастера¶
Для работы порта в режиме мастера необходимо установить соответствующую настройку порта контроллера. После этого на схему можно устанавливать блоки, предназначенные для чтения и записи переменных подчиненных устройств, подключенных к соответствующему каналу связи.
Блок Чтение (Slave)¶
Описание. Производит чтение значений по протоколу Modbus из подчиненного устройства. Запись выполняется асинхронно, т.е. каждый блок, в зависимости от состояния порта, либо ожидает освобождения порта, либо обрабатывает команду. Порт поочередно передается между блоками. Последовательность передачи порта между блоками не определена, но гарантировано, что активные блоки будут выполняться с приблизительно одинаковой частотой. Обработка команды выполняется за несколько шагов выполнения схемы. Она состоит из следующих этапов (упрощенно, полная диаграмма перехода состояний выполняется согласно “Modbus over serial line”, см. Modbus.org для уточнения):
- Ожидание освобождения порта (т.е. из блоков, использующих одинаковый порт, выполнять команды будет только один из них)
- Если en = 0 — передача порта другому блоку, возврат на этап 1. Если en = 1 — составление пакета запроса в буфере для передачи в зависимости от значений на входах, начало передачи, выдача 1 на выход sent .
- Отправка байтов пакета.
- Ожидание начала ответа в течение определенного времени таймаута, если ответ подчиненного устройства не начался в течение таймаута и количество попыток не превышает 3 – вернуться на шаг 2, если количество попыток превышает 3 и en = 1 – перейти на этап 7 с ошибкой 16.
- Ожидание продолжения и окончания ответа.
- Проверка целостности ответа (CRC), правильности его длины и содержимого. Если en = 0 — передача порта другому блоку и переход на этап 1. Если есть ошибка, при количестве попыток не больше 3 – переход на шаг 2, иначе – переход на шаг 6 с соотв. ошибкой. Если ошибок нет – успешное завершение обработки: выдача 1 на выход rdy , 0 на выход err , обнуление счетчика ошибок, передача порта для использования другому блоку.
- Выдача 0 на выход rdy, кода ошибки — на выход err, обнуление счетчика ошибок, передача порта для использования другому блоку.
Этапы 2 и 6 выполняются за 1 шаг выполнения схемы. Этапы 1, 3-5 могут длиться продолжительное время, в это время значения всех входов игнорируются, значения всех выходов, за исключением выходов valX , равны 0. Этап 7 всегда выполняется в одном шаге вместе с предыдущим этапом.
Вход port — номер порта контроллера, через который будет производится запрос. На этом входе должна быть установлена константа. Этот вход может быть подключен к какому-либо выходу, но при условии, что значение этого выхода должно быть неизменным, что определяется при оптимизации схемы во время программирования устройства или начала симуляции. Тип данных — беззнаковое однобайтовое целое. Нумерация портов начинается с нуля.
Вход en задает активность блока: если установлено 1, команда будет выполняться, иначе – порт будет передан другому блоку на ближайшем шаге 2 или 6. Если свойство блока Удерживать en не установлено, вход должен удерживаться в 1 в течение многих шагов выполнения схемы, чтобы было достаточно времени для выполнения всех этапов, т.е. до появления 1 на rdy или ненулевого err . Для ускорения срабатывания активных блоков рекомендуется устанавливать 0 на входы en блоков, которые выполнять не требуется.
Вход dev – адрес подчиненного устройства, в которое будет производиться запись.
Вход reg указывает адрес регистра или дискретного входа, начиная с которого будет производиться чтение.
Количество считываемых значений задается свойством блока «Количество выходов» (по умолчанию 1).
Т.к. обработка блока выполняется в течение нескольких шагов выполнения схемы, на этапе 6 блок не имеет данных, которые были на входах на этапе 1. Поэтому значения входов рекомендуется удерживать в неизменном виде. Выход sent устанавливается в 1 в момент составления запроса на этапе 1. Он позволяет определить, какие именно данные, в случае их изменения во времени, были отправлены. Если между выдачей 1 на выходе sent и выдачей 1 на rdy значения входов были изменены, прочитаны будут данные, соответствующие входам в момент, когда sent = 1.
Выход rdy устанавливается в 1 в случае успешного выполнения операции записи. В случае сбоя записи на выходе err выставляется код ошибки. Значения на выходах rdy и err устанавливаются только на один шаг программы (одиночное значение), поэтому для их фиксации необходимо использовать локальные переменные. В большинстве шагов выходы rdy и err равны 0 – это значит, что либо порт устройства занят другим блоком или порт находится находится в процессе выполнения запроса (на этапе 1-4). Считанные значения выдаются на выходы valX . Тип данных устанавливается для каждого выхода индивидуально. Они действительны только, если выход rdy равен 1. В других случаях, в зависимости от реализации устройства, они могут принимать либо значение 0, либо случайное значение.
Свойство блока Порядок байтов в регистре управляет следованием байтов в регистре. Протокол Modbus рекомендует, чтобы устройства должны передавать сначала старший байт, затем младший: при отображении числа в буфере приема-передачи оно удобно для чтения человеком, число 0x1234 передается как 0x12, затем 0x34. Но некоторые устройства передают числа так, как они хранятся в памяти устройства. Если устройство хранит числа в формате «little endian» (младший адрес ячейки хранит младший байт), в буфере приема-передачи также байты могут быть в порядке от младшего к старшему: число 0x1234 передается как 0x34, затем 0x12.
Свойство блока Порядок регистров управляет следованием регистров при передаче 4-байтовых величин. Смысл свойства аналогичен свойству Порядок байт в регистре , однако для этого свойства в спецификации протокола Modbus нет рекомендаций, каждое устройство либо настраивается на определенный порядок, либо имеет строго определенный порядок.
На выходы valX (где X указывает на номер величины, нумерация с 0) блок выдает считанные значения на этапе 6, одновременно с rdy = 1. Если свойство блока Фиксировать значения выключено, когда rdy = 0, значения этих выходов также равны 0, что позволяет экономить память и ускорять работу блока. Но в таком случае схема обычно должна содержать переменные и блоки для сохранения считанных значений. Если свойство блока Фиксировать значения включено (по умолчанию для новых блоков) — эти выходы сохраняют значения до следующего этапа 6, для чего блок дополнительно использует внутренние переменные. Тип данных для каждого выхода valX может быть настроен произвольно и независимо от других выходов. Однако, в связи с особенностями протокола Modbus, дискретный (логический) тип данных имеет отдельные коды команд чтения-записи и отдельную адресацию, поэтому все выходы одного блока должны иметь либо логический тип, либо любые другие. Код функции Modbus выбирается автоматически, в зависимости от установленного типа данных выхода val . Остальные выходы должны иметь соответствующий тип данных, иначе при проверке схемы блок выдаст ошибку.
Список возможных кодов ошибок, выдаваемых на выход err :
- 1 – устройство ответило, что запрашиваемая функция не поддерживается;
- 2 – устройство ответило, что отсутствует запрашиваемый адрес регистра;
- 3 – устройство ответило, что неправильный пакет запроса: ошибочная длина пакета, ошибочное значение или другая проблема, специфичная для устройства;
- 4-15 – устройство ответило указанным кодом ошибки;
- 16 – нет ответа от устройства в течение установленного таймаута;
- 17 – неправильная контрольная сумма ответа;
- 18 – адрес устройства в ответе не соответствует запросу;
- 19 – код функции в ответе не соответствует запросу;
- 20 – неправильная длина ответа.
Пример 1 использования блока:
Простая схема реализации чтения одной переменной представлена на рисунке. Для работы схемы нужно создать две переменные. Переменная enable – логическая, значение по умолчанию 1. Переменная Var имеет тот же тип данных, что и блок. В неё производится сохранение считанного значения. В начальный момент времени на входе en блока установлена 1, следовательно, производится операция чтения. В случае успешного чтения на выходе rdy устанавливается логическая единица. При этом происходит запись значения с выхода val в переменную Var и запись нуля в переменную enable. Так как переменная enable устанавливается в 0, чтение прекращается. Таким образом, указанная схема позволяет производить однократное чтение данных из подчиненного устройства, выполняя эту команду после включения питания устройства до первого успешного выполнения.
Пример 2 использования блока:
Другой вариант схемы использует RS-триггер, что позволяет производить чтение регистра произвольное число раз. Для начала чтения необходимо подать 1 на вход S RS-триггера. При этом триггер переключится в единичное состояние и установит значение переменной enable в единицу, чем активирует процесс чтения. В случае успешного чтения выход rdy установится в единицу, что приведет к записи значения с выхода в переменную Var и сбросу триггера в нулевое состояние. При этом переменная enable станет равна нулю и чтение прекратится. Для следующего цикла чтения необходимо изменить переменную “read” с 0 в 1.
Блок чтения использует следующие функции Modbus:
- 1 (0х01) – Чтение коилов (Read Coil)
- 2 (0х02) – Чтение дискретных входов (Read Discrete Inputs)
- 3 (0х03) – Чтение хранимых регистров (Read Holding Registers)
- 4 (0х04) – Чтение входных регистров (Read Input Registers) Выбор функции осуществляется в зависимости от свойства блока Тип функции и типа данных выхода val :
В FBD-программах подчиненных устройств оба “Типа функций” работают одинаково, т.е. функции 1 и 2 выдают одни и те же значения, как и функции 3 и 4.
При чтении нескольких регистров необходимо учитывать, что адреса зависят от разрядности выбранного типа данных. Для типов данных, разрядность которых не превышает 2 байтов, адресация будет увеличиваться на единицу для каждой следующей величины. Для типов данных, умещающихся в 4 байта (4-байтовые целые и дробные), адресация будет увеличиваться на 2. Например, если на входе reg установлено значение 10, количество выходов установлено 5, а тип данных всех выходов 4-байтовое целое, то у подчиненного устройства будут запрашиваться 10 регистров — с адреса 10 по 19.
Блок Чтение переменных¶
Описание: Блок выполняет команду чтения, полностью аналогично блоку Чтение (slave) . Отличие заключается в том, что для удобства использования состав считываемых величин (выходов) и их свойства определяются автоматически, исходя из имеющейся в проекте программы подчиненного устройства. Это автоматическое определение выполняется так:
- в свойстве блока Программа подчиненного указывается ссылка на программу подчиненного устройства.
- в свойстве блока Начальная переменная указывается ссылка на переменную подчиненного устройства, начиная с которой будет выполняться чтение.
- в свойстве блока Кол-во переменных указывается количество переменных в команде.
После изменения свойств блока или после изменения программы подчиненного устройства нужно обновить блок, чтобы выходы блока автоматически настроились. Блок будет выполнять чтение указанного количества переменных, расположенных последовательно по адресам, непосредственно после начальной переменной. Если таких переменных нет, или нет указанного количества, количество выходов блока будет меньше указанного в свойстве Кол-во переменных . Названия выходов, вместо valX , будут соответствовать названиям переменных подчиненного устройства.
Вход reg , в отличие от блока Чтение (slave) , не требуется подключать. Если он не подключен, используется неизменное значение адреса начальной переменной. Поэтому подключать константу ко входу reg не имеет смысла. Подключение входа reg рекомендуется использовать для динамического переключения между одинаковыми по структуре группами переменных.
Блок Запись (Slave)¶
Описание: Производит запись величин, поданных на входы valX , в подчиненное устройство. Запись выполняется асинхронно, т.е. этот блок, в зависимости от состояния порта либо ожидает освобождения порта, либо обрабатывает команду. Обработка команды выполняется за несколько шагов выполнения схемы. Обработка выполняется последовательно, аналогично блоку Чтение (slave) . Логика работы выходов и входов, кроме входов значений valX , также аналогична блоку Чтение (slave)` .
Вход en задает активность блока: если установлено 1, команда будет выполняться, иначе – порт будет передан другому блоку на ближайшем шаге 2 или 6. Если свойство блока Удерживать en установлено, на вход en можно подавать кратковременные (или одинарные) импульсы, блок будет устанавливать внутренний признак en по такому импульсу и снимать его одновременно с выдачей 1 на rdy или ненулевого err .
Если свойство блока Удерживать en не установлено, вход должен удерживаться в 1 в течение многих шагов выполнения схемы, чтобы было достаточно времени для выполнения всех этапов, т.е. до появления 1 на rdy или ненулевого err .
Вход dev – адрес подчиненного устройства, в которое будет производиться запись. Вход reg указывает начальный адрес регистра или дискретного входа, в который будет производиться запись. Количество записываемых параметров задается свойством блока Входы«(по умолчанию 1). Значения для записи подаются на входы «val , val1 , val2 и т.д. Тип данных можно указать для каждого блока в отдельности. Нельзя использовать совместно логический тип данных с другими, так как для записи лог. данных используются другие функции.
На входы valX (где X указывает на номер величины, нумерация с 0) подаются значения для записи. Тип данных для каждого входа valX может быть настроен произвольно и независимо от других выходов. Однако, в связи с особенностями протокола Modbus, дискретный (логический) тип данных имеет отдельные коды команд чтения-записи и отдельную адресацию, поэтому все выходы одного блока должны иметь либо логический тип, либо любые другие. Код функции Modbus выбирается автоматически, в зависимости от установленного типа данных выхода val . Остальные выходы должны иметь соответствующий тип данных, иначе при проверке схемы блок выдаст ошибку.
Т.к. обработка блока выполняется в течение нескольких шагов выполнения схемы, на этапе 5 блок не имеет данных, которые были на входах на этапе 1. Выход sent устанавливается в 1 в момент составления запроса на этапе.
Он позволяет определить, какие именно данные, в случае их изменения во времени, были отправлены. Если между выдачей 1 на выходе sent и выдачей 1 на rdy значения входов были изменены, записаны будут значения, которые были на входах в момент 1 на выходе sent . Если схема анализирует необходимость выполнения команды на основе сравнения ранее записанных и новых данных, такое сравнение нужно делать с последними отправленными значениями, когда sent = 1. Например, если отправленные значения нужно сохранить в переменные для последующего сравнения, такое сохранение нужно выполнять с помощью блока условной записи, подключив на его вход en выход sent . Выход rdy устанавливается в 1 в случае успешного выполнения операции записи. В случае сбоя записи на выходе err выставляется код ошибки. Значения на выходах rdy и err устанавливаются только на один такт программы (одиночное значение), поэтому для их фиксации необходимо использовать локальные переменные. В большинстве шагов выходы rdy и err равны 0 – это значит, что либо порт устройства занят другим блоком, либо порт находится находится в процессе выполнения запроса (на этапе 3-6).
Список кодов ошибок см. в блоке чтения. Если адрес подчиненного устройства равен 0 – выполняется «широковещательный запрос», который все подчиненные устройства выполняют без ответа. При широковещательном запросе этапы 4–7 не выполняются, вместо этого через некоторое время «turnaround delay» после передачи последнего байта запроса команда считается выполненной успешно. Хотя результат ее выполнения неизвестен, на выход rdy выдается 1.
Блок записи использует следующие функции Modbus:
- 05 (0x05) — Запись одного коила (Write Single Coil)
- 15 (0x0F) — Запись нескольких коилов (Write Multiple Coils)
- 06 (0x06) — Запись одного регистра (Write Single Register)
- 16 (0x10) — Запись нескольких регистров (Write Multiple registers)
Выбор функции осуществляется в зависимости от свойств блока.
Тип функции Одиночная запись действует только в том случае, когда количество входов блока равно 1 и разрядность записываемого значения не превышает разрядности 1 регистра (2 байтов). Иначе используется групповая запись. Порядок адресов определяется так же, как в блоке чтения.
Блок Запись переменных¶
Описание: Блок выполняет команду записи, полностью аналогично блоку Запись (slave) . Отличие заключается в том, что для удобства использования состав записываемых величин (входов) и их свойства определяются автоматически, исходя из имеющейся в проекте программы подчиненного устройства. Это автоматическое определение выполняется так:
- в свойстве блока Программа подчиненного указывается ссылка на FBD-программу подчиненного устройства.
- в свойстве блока Начальная переменная указывается ссылка на переменную подчиненного устройства, начиная с которой будет выполняться запись.
- в свойстве блока Кол-во переменных указывается количество переменных в команде.
После изменения свойств блока или после изменения программы подчиненного устройства нужно обновить блок, чтобы входы блока автоматически настроились. Блок будет выполнять запись указанного количества переменных, расположенных последовательно по адресам, непосредственно после начальной переменной. Если таких переменных нет, или нет указанного количества, количество входов блока будет меньше указанного в свойстве Кол-во переменных . Названия входов, вместо valX , будут соответствовать названиям переменных подчиненного устройства.
Вход reg , в отличие от блока Запись (slave) , не требуется подключать. Если он не подключен, используется неизменное значение адреса начальной переменной. Поэтому подключать константу ко входу reg не имеет смысла. Подключение входа reg рекомендуется использовать для динамического переключения между одинаковыми по структуре группами переменных.
Переменные устройства для Modbus¶
Для работы с сетями Modbus в контроллере имеется несколько специализированных переменных.
Они разбиты на две группы:
- для работы в режиме мастера и
- работы в режиме подчиненного.
Работа порта в режиме мастера¶
Для диагностики ошибок в главном устройстве, кроме выходов соответствующих блоков чтения-записи, имеются переменные устройства, отдельные для каждого порта. Эти переменные автоматически получают значения с блоков чтения-записи порта, находящегося в режиме главного. Если порт находится в режиме подчиненного, эти переменные равны 0.
- Ошибка modbus — логический признак получения ошибки в предыдущем шаге FBD-программы. В этом шаге начинается отправка следующей команды, если она имеется. В процессе отправки, ожидания и получения ответа эта переменная равна 0, т.е. эта переменная имеет «игольчатые» 1;
- Частые ошибки — логический признак наличия многочисленных ошибок, по которому определенно требуется выполнение какой-либо обработки. Признак равен 1 при наличии более пяти ошибок с частотой более чем одна за 10 секунд. Для реализации этого признака создается счетчик ошибок, увеличиваемый при ошибке и уменьшаемый по таймеру. Таким образом, значение этой переменной меняется не чаще одного раза в секунду;
- Код ошибки — последний полученный код ошибки с блока чтения-записи. Если 0 – с момента включения контроллера не было ни одной ошибки;
- Адрес подчиненного — адрес подчиненного устройства в последней команде, завершившейся ошибкой;
- Регистр подчиненного — адрес регистра в последней команде, завершившейся ошибкой.
Последние 3 переменные записываются при наличии ошибки, и не изменяются ни в процессе выполнения команд, ни при удачном их завершении. При отсутствии ошибок с момента включения контроллера все эти переменные равны 0.
Переменные диагностики на сцене:
Работа порта в режиме подчиненного¶
- Выполняющий команду порт — определяет номер порта на который поступил запрос. Диапазон значений строго регламентирован и соответствует следующим значениям. Значения 16 — 31 — номера физических СОМ портов с номерами от 0 до 15. Количество и номера портов определяется схемотехникой устройства и этот параметр можно увидеть после добавления необходимого контроллера в программу ZWB, вызвав свойство контроллера и перейдя во вкладку «Устройства». В качестве примера приведены свойства контроллера N100:
В этом контроллере определены два порта СОМ0 и СОМ1 и значение переменной будет принимать или 16 или 17. Дальнейшие значения относятся к Ethernet запросам. Значение переменной 32 означает, что устройство получило пакет по ModbusTCP. Значение переменной 64 — MQTT. Ethernet порт устройства отображается в панели свойств как ETH. * Функция запроса — код функции чтения или записи в запросе, полученном от главного устройства. * Начальный регистр — номер регистра с которого происходит чтение или запись в запросе, полученном от главного устройства. * Количество регистров — количество регистров запрашиваемых или записываемых в запросе, полученном от главного устройства.
Все вышеперечисленные переменные выставляют свое значение на один шаг программы, поэтому для фиксации их нужно использовать дополнительные переменные.
Пример использования переменной Выполняющий команду порт для определения опроса по порту COM0.
При установке переменной в значение 16 (это означает что пришел пакет от главного в порт СОМ0) происходит сброс счетчика. Если счетчик не сбросится в течении одной секунды, в переменную error будет записано значение 1.
Работа с ПЗУ¶
В zWorkbench реализована возможность распеределенной работы с ПЗУ. Во-первых, это возможность работы с ПЗУ шаблона программы, которая используется только в процессе симуляции, имитируя таким образом работу ПЗУ контроллера. Во-вторых, представлена возможность работы с ПЗУ сетевых контроллеров в режиме отладки в устройстве, которые уже непосредственно будут записаны в ПЗУ контроллера.
- Переменные ПЗУ шаблона контроллера
- Переменные ПЗУ сетевых контроллеров
Запись-чтение ПЗУ осуществляется при помощи специализированных блоков (см. “Блоки чтения-записи ПЗУ”).
При работе с ПЗУ следует помнить, что в контроллере используется EEPROM, поэтому количество циклов перезаписи в ячейку памяти ограниченно. В связи с этим, будьте внимательны и не привязывайте к ПЗУ контроллера переменную, запись в которую осуществляется слишком часто.
Переменные ПЗУ шаблона контроллера¶
Чтобы значения переменной сохранялись в ПЗУ, необходимо в свойствах переменной установить “галочку” напротив Запись в ПЗУ (Переменные). После этого переменная появится в таблице Переменные ПЗУ , переход к которой осуществляется нажатием по соответствующей кнопке в меню ZWB:
В диалоге управления переменными ПЗУ есть колонка, в которой отражены значения переменных. При запуске симуляции программы именно этими значениями инициализируются переменные, хранимые в ПЗУ. Эти значения можно менять вручную или установить равными значению по умолчанию (как в настройке локальной переменной), нажав на соответствующую кнопку диалога. Эти значения используются только для процесса симуляции, имитируя таким образом ПЗУ контроллера:
Во время симуляции значения этих переменных можно менять вручную, таким образом подбирая оптимальное значение. И последнее записанное значение сохранится в таблице ПЗУ:
Плавающая панель «ПЗУ» отображает состояние ПЗУ шаблона при симуляции в двоичном виде и не поддерживает редактирование. Таким образом, она носит больше информативный характер:
Чтобы открыть карту ПЗУ, необходимо ПКМ щелкнуть по рабочей панели и выбрать ПЗУ:
Переменные ПЗУ сетевых контроллеров¶
Для каждого экземпляра контроллера, находящегося в линии связи, тоже существует своя таблица переменных, хранимых в ПЗУ.
Чтобы отрыть таблицу переменных ПЗУ контроллера, необходимо:
- В дереве проекта выбрать сеть, к которой принадлежит требуемый контроллер:
- На карте сети выбрать требуемый контроллер и, нажав ПКМ, выбрать Настройка :
- Перейти на вкладку ПЗУ , где и располагается таблица переменных контроллера, хранимых в ПЗУ:
При создании сетевого контроллера эта таблица пуста. При запуске отладки в устройстве в эту таблицу добавляются только переменные ПЗУ, чье значение изменилось в ходе отладки. Это будут все те же переменные из ПЗУ шаблона, который привязан к данному контроллеру (см. “Переменные ПЗУ шаблона контроллера”).
При повторном запуске отладки в устройстве все значения переменных, хранимых в ПЗУ, устанавливается в соответствии с этой таблицей.
Таким образом при отладке устройства, все значения ПЗУ, измененных в процессе отладки сохраняются в проекте. В последующем, при запуске отладки или загрузки проекта эти значения попадают в контроллер. Поэтому будьте внимательны и проверяйте перед загрузкой программы в контроллер данную таблицу.
Так же, как и для шаблона программы, эти значения можно изменять вручную или установить по умолчанию, нажав соответствующую кнопку.
Function Block Diagram (FBD) PLC Programming Tutorial for Beginners
One of the official and widely used PLC programming languages is the Function Block Diagram (FBD). It is a simple and graphical way to program any functions together in a PLC program. Function Block Diagram is easy to learn and provides a lot of possibilities.
As one of the official PLC programming languages described in IEC 61131-3, FBD is fundamental for all PLC programmers. It is a great way to implement everything from logic to timers, PID controllers, and even a SCADA system in your solution, etc.
Most engineers love FBD because it is graphically a very common way to describe a system. Engineers like to put things in boxes. And that is exactly what the concept of function block diagrams is. FBD is very useful when batch control concepts from ISA-88 are applied.
In this tutorial I will introduce you to some of the basic principles of FBD programming and the function blocks.
Content of FBD Tutorial
- Function Blocks in FBD
What is Function Block Diagram?
From systems engineering you might already know something also called function block diagrams. PLC function block diagram is not that different from it. What FBD offers is a way to put functions written with many lines of code into boxes.
Thereby we can easily connect them, to make a bigger PLC program.
As with ladder logic and structured text, function block diagrams or FBD is described in the standard IEC 61131-3 by PLCOpen. Most PLC programs are written with some amount of FBD. Because, even though you might write your functions in structured text. You still, most of the times, have to connect those functions.
Function Blocks
In FBD all functions are put into function blocks. They all have one or more inputs and outputs. The function of the block is the relation between the state of its inputs and outputs.
Here’s how a simple function block could look like:
Function block illustration in FBD
The function block is illustrated with a box. In the middle of the box is often a symbol or a text. This symbol represents the actual functionality of the function block.
Depending on the function there can be any number of inputs and outputs on the function block. You can connect the output of one function block to the input of another. Thereby creating a Function Block Diagram.
Combining function blocks to make a basic function block diagram
There are many standard function blocks provided in FBD.But you can also make your own function blocks. Often, you will have to use the same piece of code in your PLC program multiple times. It could be a function for controlling a valve, a motor etc. With function blocks, you can make a function block specific for a motor and use it several times.
Let’s begin by having a look at some of the standard function blocks as described in the IEC standard for PLC programming languages. They provide a variety of functions from very basic to advanced.
Standard Function Blocks
In the standard from IEC, a lot of function blocks are described. Here’s an overview of the most important blocks in the official FBD description.
Bit Logic Function Blocks
The most basic functionality of a PLC program is logic. Combined called combinatorial logic. Logic is the simplest form of algorithm that, via the states of its inputs can set some outputs. Basically, there are two different bit logic functions or operations in FBD. With just these two you can derive a whole bunch of other logic functions.
But let’s start with the first one:
OR Logic Operation
At first I would like to introduce you to the OR function block. It takes 2 inputs and has 1 output, and works just like an OR gate.
If one of the inputs is true the output will also become true.
In FBD the block will typically look like this:
Function block representing the OR logic operation in FBD
As you probably have seen the symbol for an OR operation is >=1. It is basically the condition for the output. If the sum of the two inputs are greater than or equal to 1, the output becomes true.
The functionality of the OR block is equivalent to a parallel connection of two contacts in ladder logic. If either one of the contacts are closed, the output is set.
When I say output here I mean the output of the function block. We can only connect the output pin to another function block. But what if we want to set an actual output or a bit with the block output?
This leads us to the next function block.
Assignment Operation
In most cases, you will connect the output of a function block to the input of another. But sometimes you will want to use that output to control one or more bits. This could for example be setting an output or a value for a variable.
To do this you need to use the assignment function block. And yes… This is a function block itself. Meaning that you cannot just set a memory address at the output of your block.
Assignment blocks work by assigning its input to a place in the PLC memory.
The function block also has an output you can use to connect to other function blocks. This is very useful because you can assign values anywhere in your function block diagram. Not just at the output of the last block.
The assignment function has the same functionality as a coil in ladder logic.
Function block of an assignment operation in FBD
AND Logic Operation
The next function block I would like to introduce you too is the AND function block. Just like the OR-block this is one of the most fundamental function blocks in PLC programming.
It has two inputs and one output. It is very similar to the OR function but works a little different. Instead of one of the two inputs, this block requires both inputs to be a true set the output.
If both the inputs are true the output will also become true.
Function block representing the AND logic operation in FBD
If you know a bit of ladder logic, the AND function block is equivalent to a serial connection of two contacts in ladder logic. Both of them has to be true before the block evaluates its output to be true.
Negation Operation
Sometimes you will want to invert either the input or output of a block. To do that you have to use negation. It comes in different shapes, depending on the software you use.
In some cases it is a whole blocks itself. And sometimes it is just the small circle you can put on any pins of the function blocks.
NOT, invert RLO or negate assignment practically works by changing the signal to the opposite.
Negated function block/NOT function block
When a signal is inverted or negated it means that, if it is true it becomes false and vice versa. The small circle in the pin of the block represents exactly that function.
Not only is it the outputs that can be inverted. The inputs can also be inverted. Simply by putting the circle on the input pin. You’ll see later that inverting either all inputs or the output has the same effect on the function of a block.
Exclusive OR Operation
This block is a special case of the OR block. The input values on the OR block has to be greater than or equal to 1. But as you can see below, the Exclusive OR or just XOR block requires the two inputs to be equal to 1.
If for example both inputs are true, the output of the XOR will be false, since the sum of the inputs are greater than 1.
Exclusive OR function block XOR in FBD
Although it can be built with two AND and one OR function block, the XOR block is also provided as a function block itself in Siemens TIA Portal, Codesys and many more.
It is widely used to check if one and only one of two inputs are true.
NAND, NOR etc.
The next two function blocks are also build using the basic blocks. They are negated blocks. It actually just means that the output of the block is negated.
Take for example the NAND block as illustrated below. As you can see, the NAND function block is really just the AND block with a negated output. NAND stands for NOT AND or Negated AND.
NAND function block from negated AND block
As mentioned before the functionality of the NAND function block can also be obtained by negating the inputs. Negating the inputs has the same effect as negating the output. Therefore a NAND block could also look like this:
NAND function made with negated inputs on AND block
Bistable Function Blocks
The next types of function blocks I will introduce you too are the bistable. I like to think of them as the simplest form of memory. You can either set or reset the output. The output (Q) remembers the last state of the set input (S1).
Give S1 a pulse, and Q1 will be set. Even though S1 then changes state to false, the output will still be true. You can say that Q1 remembers if anything happened at S1. That’s why I like to think of the bistable functions or flip-flops as memory.
Set/Reset
The function block is called SR or set/reset and this is how it looks like:
Set/reset function block (set dominant)
In order to get a better understanding how this function works, let’s look inside the function block. The function block body of the SR block shows that it is made up of 2 bit logic blocks. One AND function and one OR function.
The output of the AND function is connected to the input of the OR function. As one of the inputs on the AND function is Q1 which also acts the output for the whole block.
Many call this a flip-flop function. Q1 will remember that at some point S1 was true. This is until R or reset will be sat to true. Thereafter Q1 will be reset. The output (Q1) remembers and therefore I like to think of the block as a simple memory block.
Set/reset function block body
This type of block always has a priority. If both inputs are true what will happen?
SR-blocks has set priority. So in the case where both inputs are true, the output will be set.
But that’s not always what you want. And that will lead us to the next block.
Reset/Set
In some cases you might want to output to be reset when both inputs (S1 and R) are true. That is why we have to RS block.
It basically works in the same way as the SR block, but with reset as priority instead of set.
Reset/set function block (reset dominant)
Again, this block can be derived from two basic logic blocks. But since the SR/RS flip flops are so fundamental in PLC programming, they have their own function block.
Reset/set function block body
There are of course several ways to remember things. And although the flip flops are a very simple way to remember, the next types of blocks might be an even simpler form of memory.
Edge Detection
Detecting edges is very useful in both PLC programming and electronics. Of course I’m not talking about the edge of your kitchen table, but rather the edge of signals.
Let’s say you have an input with a push button connected to it. You want to be able to count how many times you press that button.
Normally you would just connect the input to a counter function block (more on those later). But if you remember the basic workings of a PLC you will know that the PLC has a scan time or a cycle time.
This time is usually very short (20-50 ms). When you press a push button (even though you press and release fast), the input will be on for way longer time (typically 100-200 ms). The input will be on for several scan cycles.
Each time the PLC reaches the counter block it will count one up since the input is true. For each time the push button is pressed the counter will count not only one up but 2, 3, 5 or even more.
To avoid this we are going to use edge detection blocks.
R_TRIG Function Block
The one edge we can look at in a digital signal is the rising edge. Sometimes also referred to as positive edge.
It happens when the signal goes from false (0) to true (1). In digital electronics when the voltage goes from 0 to 5V. The rising edge is what happens right when we push the button.
R_TRIG function block for detecting rising edge signals
When the input (CLK) detects a rising edge the output will be set. But only for a brief moment, since the rising edge happens so fast. Even though the input might be true for next scan cycles, the output will not be set more than one time. The output generates a pulse when a positive or rising edge is detected.
Here’s a diagram of the function block to make it easier to understand:
Function Diagram for R_TRIG Block
It takes a new rising edge to generate another pulse at the output. The block remembers, so to speak, if a positive edge was at the input. So in order to set the output again the input needs to go to false and then true again. Or as in our push button example; you need to release the button and press it again.
F_TRIG Function Block
Just like the rising edges you can of course also detect falling edges. When the signal goes from true (1) to false (0) is the falling edge.
F_TRIG function block for detecting falling edge signals
Sometimes the falling edge is also called negative edge. It also works by generating a pulse at the output but with a falling edge at the input.
Function Diagram for F_TRIG Block
A typical use for this block is to make something happen when another thing stops.
Let’s say you want a yellow lamp to be turned on when a motor stops. But you only want this to happen when the motor has already been started. So that the yellow lamp is only turned on the moment the motor stops.
Solution: Put and F_TRIG to detect a falling edge on the motor output. This can then generate a pulse to set the output for the yellow lamp.
Timer Function Blocks
With the previous blocks we wanted to make sure a signal was not longer than the scan time. But sometimes you will want to control the length of a signal, or when it happens.
This is where timer function blocks comes into the picture. Timers are some of the most used functions in PLC programming. They are divided into three different types of timers.
If you want to know more about timers and watch how they work in a PLC simulation you can read the article about PLC timers. You will find video tutorials on both the on delay timer, off delay timer and pulse timer.
Some argue that you will only need to use one of them, because with that you can derive all timer functions. But since all three are described in IEC 61131-3 and are provided in most software, I would like to introduce you to them all.
Pulse Timer (TP)
The first timer is called the pulse timer, because it is used to generate a pulse of a specific length.
It takes two inputs and has two outputs. So far, we have only seen function blocks where the inputs and outputs where boolean. This is still true for the IN and Q of the TP block. But it is a little different with the PT and ET. They both take variables of the data type TIME.
PT stands for Preset Time and is an input to the block. This is where you put the time you want to pulse at Q to be. As soon as the input IN is true, the output Q will be set for PT time.
Timer Pulse (TP) Function Block
ET stands for Elapsed Time. This is the time Q has been active.
Say you want a ventilation fan to be on for 10 minutes. You will then have to enter 10m at the PT and set the ventilation fan to the output Q. In many cases it is then useful to see how long the fan has been running. That is what ET is used for.
Pulse Timer Diagram
You can see the functionality of the pulse timer a little more detailed in the time diagram above.
On Delay Timer (TON)
The next type of timer is the On Delay Timer or just referred to as TON. But instead of setting the time for the pulse, it is used to set a delay for the pulse.
When the input is on the timer will start counting. After the time PT has elapsed the output Q will be set. This is also the reason for its name.
It turns on the output after a delay
On-Delay Timer (TON) Function Block
The on delay timer has the same input and output pins as the pulse timer. And again, it still has the ET to see how much time has elapsed.
In the diagram for the on delay timer below the functionality is illustrated:
On Delay Timer Diagram
It is exactly this timer that some people claim is the only one you need. But before explaining why, let me introduce you to the third and last type of timer.
Off Delay Timer (TOF)
The functionality of the off delay timer (TOF) is very similar to the TON. But with one big difference.
It turns off the output after a delay
In the moment the input is set to true, the output will be set. As long as the input stays true the output will stay on until the PT time has elapsed. After that time the output will be turned off.
Off-Delay Timer (TOF) Function Block
At first, this off delay timer may seem very similar to the pulse timer (PT). They also are, but with one crucial difference.
The output of the pulse timer will be on for PT time even though the input turns to false in the middle of the timing. This is because the timer looks for a rising edge at the input. With the off delay timer though the time will stop counting if the input comes back.
Off Delay Timer Diagram
These three timers are the official ones described in IEC 61131-3. Technically you can build all of them by using only the on-delay timer. This is done with a little bit of ladder logic.
Counter Function Blocks
The next type of function blocks have not only an input and an output more. They also take another data type. It’s time to look at the PLC counters.
Counting is very fundamental to PLC programming. How many products has the machine produced? In which step of the sequence is the tool? There are many reasons to use counters in a PLC program.
IEC provides three different standard counter blocks. One for counting up, one for counting down, and one for counting either up or down.
Let’s look at the first one, and start counting up!
Up Counter (CTU)
This counter block has three inputs and two outputs. Although this seems like a lot, they are all necessary to be able to count. But before looking at the details of each input and output, let me just briefly explain how the up counter block works.
Each pulse on CU will count CV up by 1. When CV >= PV then Q is set.
The input CU looks for a rising edge. When that happens the output CV is increased by 1. To be able to do that, the output CV needs to take another data type: integer.
As the integer is a 16-bit number (with the first one used for signed/unsigned) you can count up to 32767. Both the input PV and the output CV are of the data type integer. PV is the limit for when the boolean output Q is set.
Up Counter (CTU) Function Block
The reset (R) input is used to set the value CV to 0. We usually start counting up from 0 because, in that way, the output CV will always represent the number of pulses that occurred on CU.
For you that like textual coding languages here’s the function block body in structured text:
Down Counter (CTD)
It is not only a useful thing to count up. Sometimes you will also need to count down. Often you will want you PLC program to do an operation a certain amount of times. Here, the down counter comes in very handy.
Each pulse on CD will count CV down by 1. When CV <= 0 then Q is set.
It works exactly like the up counter, but instead of counting one up, it counts 1 down.This brings me to another difference between the up and down counter. Where to count from?
When counting up we usually just count from 0. But when counting up we need to set some value we can count down from. That is why we have to input LD. When LD is set to true the output CV is set to PV.
Down Counter (CTD) Function Block
The function block body looks like this in structured text:
Now that you’ve learned both how to count up and down it’s time to take a look at the last counter block.
Up Down Counters (CTUD)
It can sometimes be practical to be able to count both up and down. That is why the IEC also provides an official block for counting both up and down.
The counter has 5 inputs and 3 outputs. All of them has the same names as the inputs and outputs on the previous counter blocks. This block is a combination of the two previous blocks. All the inputs/outputs has the same function.
Up Down Counter CTUD Function Block
To really get to know how this function block works, let me show you the function block body:
This code can look a bit complicated at first. But it really just is a combination of the up and the down counter. CU counts CV up by 1 and CD counts CV down by 1. Each of the outputs QU and QD are set with the same conditions as with the two previous counter blocks.
Comparison Function Blocks
I like to think of the next type of function blocks as asking questions. Is A equal to B? Is CV greater than PV? It is time to compare some numbers!
Comparing is actually something that already happened in many of the blocks we’ve already looked at. Take for example the OR block that compared two boolean inputs. If the total of them were equal to 1, the output would be set.
Now, it is not only boolean data types we can compare in FBD. In fact, we can compare all real numbers (sorry mathematicians, no imaginary yet) and most data types. This is not only handy, I will also promise you that it is something that you will use a lot.
Basic for all the comparison blocks is that they all have two or more inputs and one output. The inputs can take up any elementary data type and the output is boolean. You have to be careful when comparing data types, because it can be a bit tricky.
Let’s begin with the first basic comparator block:
Equality (=)
The equality function block is used to see if two variables are equal to each other. If so, the output will be set. I like to think of the block as asking this question:
Although this block might seem simple, you have to be a bit careful with what data types you compare here. Comparing integers with this block is probably the data type you will use the most. Let’s say you want an output to be set when the machine is in step 12. IN1 would then be the step variable and IN2 would be 12.
The three dots between the two inputs are there to illustrate that this block can take more than two inputs. For the output to be set, all of the inputs has to be equal. This function is described like this using structured text:
Equality Function Block
Comparing other data types with equality can cause some problems though. If you try to use equality to compare an analog value (real data type) to another real data type, you will see that it is very unlikely that they will ever equal each other.
For this block to set the output requires the two inputs to be exactly equal to each other. Remember that real data types are floating-point numbers. You may want something to happen when the temperature reaches 80 degrees. But if you use real numbers here the temperature has to equal 80.0 degrees exactly. For this type of comparison, it is better to use a combination of compare blocks. In that way, you can compare it to a range of numbers and not just one.
But when talking about integers and sometimes also words, the equality block is very useful.
Inequality (<>)
But what if you want to check if some numbers aren’t equal to each other? Of course you could just negate the output of the equality block. But that would be rather confusing. And why do that when there’s a block for doing exactly that.
The block works in the same way as the previous but checking for inequality instead of equality. The question to remember the functionality of this block could be:
If so, the output will be set. But only as long as they are not equal. As soon as the inputs are equal the output will be turned off.
Inequality Function Block
To you who are already familiar with structured text you will know the symbol for inequality. It is similar to what in many programming languages is noted like this: !=. But in PLC programming inequality is noted this way <>.
Be aware that this block only takes two inputs.
Less Than (<)
If you remember before we had a problem with comparing real data types with equality. This and the next block might be the solution to that. Because with this block we can check if a variable is within a range of numbers.
Officially this block is called increasing sequence. But less than is a way more simple name to remember it by. Think of it as asking this question:
It is basically checking if the value of the first input is less (smaller) than the value of the second input. The block works very well with real numbers since you can easily check if e.g. a temperature is less than 80.5 degrees.
Less Than (Increasing Sequence) Function Block
There’s a reason the official name for this block is increasing sequence. Just like the equality block you can extend this block with more than two inputs. When doing that the official name makes a whole lot more sense.
Because with multiple inputs the values of those has to make up an increasing sequence of values. In1 has to be less than IN2, that has to be less than IN3 and so on. The function can be described textually like this:
Greater Than (>)
When you can make an increasing sequence you can of course also make a decreasing sequence. Or put in more simple words. You can also check if some value is greater than another value. The question this block asks is this:
But just like the previous block, this block can also take more than two inputs. That’s why this block also has to take a sequence of numbers, but this time a decreasing sequence in order to set the output.
Greater Than (Decreasing Sequence) Function Block
Each text input has to be smaller than the previous, thereby creating a decreasing sequence. Written in a textual language like structured text, the function of the greater than block looks like this:
The combination of the greater than and less than blocks can also be very useful. When talking analog values you will often want to check if they are within a certain range. E.g. if a temperature is between 90 and 100 degrees. Here you could check if the temperature is greater than 90, and thereafter check if it is less than 100.
- Less than OR equal to
- Greater than OR equal to
Selection Function Blocks
Comparing two or more values is useful. But sometimes, instead of comparing, you will have to choose between values. The selection function blocks give you that opportunity.
What they all have in common is that they give you the option of selecting a value. With or without conditions. The essence of these blocks is really just an assignment. You will select one of the inputs and assign it to the output of these blocks.
The first and most simple selection block is the move function block. In fact, you have already seen this block before. Or at least a block with the same functionality. The assignment function block.
What this block does is that it assigns the input value to its output. And guess what. This block does exactly the same thing. You might wonder why FBD provides two blocks with the same function. They are also similar, but with one crucial difference.
While this block can be used with any data types, the assignment block can only be used with boolean data types. With the move block you can move any data type to any data type.
For you that like structured text, the representation of the block looks as simple as this:
Provided in function block diagram the moving block looks like this:
Move Function Block
As you can see this block only has one input and one output. The concept of selection doesn’t really apply to this block, since you only have one value to select. Many times though you will be able to add more outputs to the move block. A moving block can thereby be used to move a value to different places.
When I said this block works with any data type, I really meant it. You can move values from any data type to any data type. You don’t even have to put the same data type in the output as the input. You’re free to move e.g. an integer to a real, a TIME to a double word and so on.
This makes the moving block a bit tricky. You have to be really careful when moving from one data type to another. For beginners, I highly recommend that you only move values to the same data type as the input. As a matter of fact, I would rarely recommend mixing data types even for professionals. It just makes your PLC program complicated.
Binary Selection (SEL)
Binary selection drags us a little closer to the concept of selection. It gives you the opportunity to select between two values to then assign to an output.
The name indicates that you with a binary (boolean) input can select one of two input values. Therefore this block has three inputs. One condition (G) and two values (IN0, IN1). The condition takes a boolean data type and is used to select between the two values.
Binary Selection (SEL) Function Block
You will most likely have noticed that the input names are a bit different than with the other function blocks. That is only to make the block easier to understand. Since the condition (G) can take two different values 0 and 1, it makes sense to call the inputs IN0 and IN1.
If G is 0 the input IN0 will be selected. And if G is 1 the input IN1 will be selected. The value of the selected input will then be assigned to the output (OUT).
Again, this functionality can be represented in structured text:
Extensible Multiplexer
In some cases, you may even have more than two values you want to select from. This is where the extensible multiplexer comes into the picture. You might even find the word multiplexer familiar if you know a few digital electronics. And this block has the same functionality – to choose one out of many inputs.
Like the previous block, this block has two types of inputs. A condition (selector) and some input values. The block selects one of N inputs depending on the value of the selector.
Extensible Multiplexer (MUX) Function Block
Unlike the binary selector the condition input, named K in this block, can not only take a boolean data type. In fact, it can take up any elementary data type. Although the only data type that really makes sense to use here is an integer.
As you have to choose between inputs from IN0 to INn it only makes sense to give the condition K a whole number. Actually it is only valid to give K a number between 0 and n. The concept of the function may look like this:
Where K has to be within the range 0 – n, where n is the number of inputs.
Extensible Minimum Function (MIN)
So far you have seen how to select values using a condition input. That input could be either binary or an integer depending on how many inputs you have to choose between
But sometimes you will want to select a value depending on the values themself. It could be that you want to select the highest or the lowest value among different variables.
With the next two function blocks, you can do exactly that.
Extensible Minimum (MIN) Function Block
Choosing the variable with the smallest value is something that I can guarantee, that you will use at some point. The official name for this function block is extensible minimum, but often just called minimum or MIN. It is called extensible because you can add any number of inputs on the block. All the inputs can take any elementary data type, and they can even be of different data types on the same block.
What will be assigned to the output of the block is always the value of the smallest input. Or put in other words – the input with the minimum value will be selected.
Extensible Maximum Function (MAX)
When you have a block for finding the minimum value, you will of course also have a block for finding the maximum value. FBD also provides a standard function block for doing that.
It works exactly the same way as the minimum function, but selects the variable with the maximum value and assigns that value to its output.
Also this block takes any elementary data type as input and output.
Extensible Maximum (MAX) Function Block
With both these blocks, you should be aware which data type you use at the output. If you are trying to find the maximum value of two real data types e.g. 80.46 and 206.95 and you use integer as output, the output will simply be 206.
A smart feature with these two blocks is that you can also compare time and date data types. Say you have a lot of date stamps in your PLC program and you want to find the latest. With the maximum function, you can always find the most recent date.
Limiter (LIMIT)
By combining the two previous function blocks we can create a whole new function. This function is not so much about selection, but rather about limitation. That is why this function block is called a limiter. More than often you will want to set limits to a range of values in a PLC program.
Limiter (LIMIT) Function Block
The limiter function is really just made up by the minimum and maximum functions. This can be seen if we take a look at the function block body:
What really happens here is that you set a minimum and a maximum limit for whatever variable you put at the input (IN). The min and max values are set at the inputs (MIN and MAX) and all three inputs can take any elementary data type.
Make your own function blocks
- Arithmetic Function Blocks
- Bit Shift Function Blocks
- Character String Function Blocks
- Conversion Function Blocks
- Communication Function Blocks
I highly recommend that you just start out by playing around in your Automation IDE like TIA Portal or Codesys. Try creating simple PLC programs using function block diagram programming. I find that is the best way to learn about new function blocks.
The point here is that every function block represents a function. Inside the function block body, you will find that the function is described in either structured text, ladder logic, or another PLC programming language. There are many standard blocks providing you with a lot of different functions. But sometimes it’s just not enough.
This is why you will need to build your own function blocks. This is in fact one of the cornerstones in structured PLC programming. Stay tuned on PLC Academy to learn more about that