Введение в язык функциональных диаграмм (FBD)
Одним из официальных и широко используемых языков программирования ПЛК является язык функциональных блоков (FBD). Это простой и графический способ программирования любых функций в программе ПЛК. Функциональная блок-схема проста в освоении и предоставляет широкие возможности.
Будучи одним из официальных языков программирования ПЛК, описанных в стандарте IEC 61131-3, FBD является основополагающим для всех программистов ПЛК. Это отличный способ реализовать в своем решении все: от логики до таймеров, ПИД-регуляторов, даже SCADA-системы и т. д.
Большинство инженеров любят FBD, потому что это очень распространенный способ графического описания системы. Инженеры любят складывать вещи в коробки. И именно в этом заключается концепция диаграмм функциональных блоков. FBD очень полезны, когда применяются концепции пакетного управления из ISA-88.
В этом уроке я познакомлю вас с некоторыми основными принципами программирования FBD и функциональными блоками.
Что такое функциональная блок-схема?
Из области системной инженерии вы, возможно, уже знакомы с тем, что называется функциональными блок-схемами. Функциональная блок-схема ПЛК не так уж сильно отличается от нее. Что предлагает FBD, так это способ поместить функции, написанные многими строками кода, в ячейки.
Таким образом, мы можем легко соединить их, чтобы создать большую программу ПЛК.
Как и лестничная логика и структурированный текст, диаграммы функциональных блоков или FBD описаны в стандарте IEC 61131-3 от PLCOpen. Большинство программ ПЛК написаны с использованием FBD. Потому что, даже если вы можете написать свои функции в структурированном тексте. В большинстве случаев вам все равно придется соединять эти функции.
Функциональные блоки
В FBD все функции помещаются в функциональные блоки. Все они имеют один или несколько входов и выходов. Функция блока – это связь между состоянием его входов и выходов.
Вот как может выглядеть простой функциональный блок:
Функциональный блок изображается в виде рамки. В центре блока часто находится символ или текст. Этот символ представляет собой фактическую функциональность функционального блока.
В зависимости от функции у функционального блока может быть любое количество входов и выходов. Вы можете соединить выход одного функционального блока с входом другого. Таким образом, создается диаграмма функциональных блоков.
В FBD существует множество стандартных функциональных блоков, но вы также можете создавать свои собственные функциональные блоки. Часто в программе ПЛК приходится использовать один и тот же фрагмент кода несколько раз. Это может быть функция управления клапаном, двигателем и т. д. С помощью функциональных блоков вы можете создать функциональный блок, предназначенный только для двигателя, и использовать его несколько раз.
Для начала давайте рассмотрим некоторые стандартные функциональные блоки, описанные в стандарте IEC для языков программирования ПЛК. Они предоставляют множество функций – от самых простых до продвинутых.
Стандартные функциональные блоки
В стандарте IEC описано множество функциональных блоков. Вот обзор наиболее важных блоков в официальном описании FBD.
Функциональные блоки битовой логики
Самая основная функциональность программы ПЛК – это логика. В совокупности это называется комбинаторной логикой. Логика – это простейшая форма алгоритма, который через состояния своих входов может задавать некоторые выходы. По сути, в FBD есть две различные битовые логические функции или операции. На их основе можно получить множество других логических функций.
Но начнем с первого:
Логическая операция ИЛИ
Сначала я хотел бы познакомить вас с функциональным блоком ИЛИ. Он принимает 2 входа и имеет 1 выход, и работает точно так же, как ворота ИЛИ.
Если один из входов истинен, то и выход станет истинным.
В FBD блок обычно выглядит следующим образом:
Как вы, наверное, уже поняли, символ операции ИЛИ – >=1. По сути, это условие для выхода. Если сумма двух входов больше или равна 1, выход становится истинным.
Как и в других битовых логических операциях, false обозначается 0, а true – 1. Это можно проиллюстрировать с помощью таблицы истинности для операции ИЛИ:
>=1 | IN1 | ||
0 | 1 | ||
IN2 | 0 | 0 | 1 |
1 | 1 | 1 |
Функциональность блока ИЛИ эквивалентна параллельному соединению двух контактов в лестничной логике. Если один из контактов замкнут, выход устанавливается.
Когда я говорю “выход”, я имею в виду выход функционального блока. Мы можем подключить выходной контакт только к другому функциональному блоку. Но что, если мы хотим установить фактический выход или бит с помощью выхода блока?
Это приводит нас к следующему функциональному блоку.
Назначение Операция
В большинстве случаев вы подключаете выход функционального блока к входу другого. Но иногда вы захотите использовать этот выход для управления одним или несколькими битами. Это может быть, например, установка выхода или значения переменной.
Для этого нужно использовать функциональный блок присваивания. И да… Это функциональный блок. Это означает, что вы не можете просто установить адрес памяти на выходе вашего блока.
Блоки присваивания работают путем назначения своего входа месту в памяти ПЛК.
Функциональный блок также имеет выход, который можно использовать для подключения к другим функциональным блокам. Это очень полезно, поскольку вы можете назначать значения в любом месте диаграммы функциональных блоков. А не только на выходе последнего блока.
Функция присвоения имеет ту же функциональность, что и катушка в лестничной логике.
Логическая операция AND
Следующий функциональный блок, с которым я хотел бы вас познакомить, – это функциональный блок AND. Как и блок ИЛИ, это один из самых фундаментальных функциональных блоков в программировании ПЛК.
Он имеет два входа и один выход. Он очень похож на функцию ИЛИ, но работает немного по-другому. Вместо одного из двух входов этот блок требует, чтобы оба входа были истинными и задавали выход.
Если оба входа истинны, то и выход будет истинным.
Вот как выглядит таблица истинности для блока AND:
& | IN1 | ||
0 | 1 | ||
IN2 | 0 | 0 | 0 |
1 | 0 | 1 |
Если вы немного знакомы с лестничной логикой, то функциональный блок AND эквивалентен последовательному соединению двух контактов в лестничной логике. Оба контакта должны быть истинными, прежде чем блок оценит свой выход как истинный.
Операция отрицания
Иногда требуется инвертировать вход или выход блока. Для этого нужно использовать отрицание. Оно бывает разной формы, в зависимости от используемого программного обеспечения.
В некоторых случаях это целые блоки. А иногда это просто маленький кружок, который можно поставить на любой пин функционального блока.
NOT, invert RLO или negate assignment практически работают, меняя сигнал на противоположный.
Инверсия или отрицание сигнала означает, что если сигнал истинный, то он становится ложным, и наоборот. Маленький кружок на выводе блока представляет собой именно эту функцию.
Инвертированными могут быть не только выходы. Входы также могут быть инвертированы. Просто поместив кружок на входной контакт. Позже вы увидите, что инвертирование либо всех входов, либо выхода оказывает одинаковое влияние на функцию блока.
Операция исключающего ИЛИ
Этот блок является частным случаем блока ИЛИ. Входные значения блока ИЛИ должны быть больше или равны 1. Но, как вы можете видеть ниже, блок Исключающее ИЛИ или просто XOR требует, чтобы два входа были равны 1.
Если, например, оба входа истинны, то на выходе XOR будет ложь, так как сумма входов больше 1.
Хотя он может быть построен с помощью двух функциональных блоков AND и одного OR, блок XOR также предоставляется в качестве функционального блока в Siemens TIA Portal, Codesys и многих других.
Он широко используется для проверки истинности одного и только одного из двух входов.
NAND, NOR и т.д.
Следующие два функциональных блока также построены с использованием базовых блоков. Это блоки с отрицанием. На самом деле это означает, что выход блока отрицается.
Возьмем, к примеру, блок NAND, как показано ниже. Как видите, функциональный блок NAND – это просто блок AND с отрицательным выходом. NAND означает NOT AND или Negated AND.
Таблица истинности для этого блока прямо противоположна таблице истинности для блока AND.
NAND | IN1 | ||
0 | 1 | ||
IN2 | 0 | 1 | 1 |
1 | 1 | 0 |
Как уже говорилось, функциональность функционального блока NAND может быть также получена путем отрицания входов. Отрицание входов имеет тот же эффект, что и отрицание выхода. Поэтому блок NAND может выглядеть следующим образом:
Функциональные блоки с бистабильной функцией
Следующий тип функциональных блоков, с которым я вас познакомлю, – это бистабильные. Мне нравится думать о них как о простейшей форме памяти. Вы можете либо установить, либо сбросить выход. Выход (Q) запоминает последнее состояние установленного входа (S1).
Подайте на S1 импульс, и Q1 будет установлен. Даже если после этого S1 изменит состояние на false, на выходе все равно будет true. Можно сказать, что Q1 помнит, произошло ли что-нибудь на S1. Вот почему мне нравится думать о бистабильных функциях или флип-флопах как о памяти.
Set/Reset
Функциональный блок называется SR или set/reset, и вот как он выглядит:
Чтобы лучше понять, как работает эта функция, давайте заглянем внутрь функционального блока. На теле функционального блока SR видно, что он состоит из двух битовых логических блоков. Одна функция И и одна функция ИЛИ.
Выход функции AND подключен к входу функции OR. Одним из входов функции И является Q1, который также служит выходом для всего блока.
Многие называют эту функцию флип-флопом. Q1 будет помнить, что в какой-то момент S1 было истинным. Так будет до тех пор, пока R или сброс не перейдут в состояние true. После этого Q1 будет сброшен. Выход (Q1) помнит, и поэтому мне нравится думать об этом блоке как о простом блоке памяти.
Этот тип блока всегда имеет приоритет. Если оба входа истинны, что произойдет?
SR-блоки имеют установленный приоритет. Поэтому в случае, когда оба входа истинны, выход будет установлен.
Но это не всегда то, что вы хотите. И это приведет нас к следующему блоку.
Reset/Set
В некоторых случаях вы можете захотеть, чтобы выход сбрасывался, когда оба входа (S1 и R) истинны. Для этого и существует блок RS.
По сути, он работает так же, как и блок SR, но приоритетом является сброс, а не установка.
Опять же, этот блок может быть получен из двух базовых логических блоков. Но поскольку флип-флопы SR/RS играют столь важную роль в программировании ПЛК, они имеют свой собственный функциональный блок.
Конечно, существует несколько способов запоминания. И хотя флип-флопы – это очень простой способ запоминания, следующие типы блоков могут быть еще более простой формой памяти.
Обнаружение краев
Обнаружение краев очень полезно как в программировании ПЛК, так и в электронике. Конечно, я имею в виду не край вашего кухонного стола, а край сигналов.
Допустим, у вас есть вход с подключенной к нему кнопкой. Вы хотите иметь возможность подсчитывать, сколько раз вы нажимаете на эту кнопку.
Обычно вы просто подключаете вход к функциональному блоку счетчика (подробнее об этом позже). Но если вы помните основные принципы работы ПЛК, то знаете, что у ПЛК есть время сканирования или время цикла.
Это время обычно очень мало (20-50 мс). Когда вы нажимаете кнопку (даже если вы нажимаете и отпускаете ее быстро), вход будет включен гораздо дольше (обычно 100-200 мс). Вход будет включен в течение нескольких циклов сканирования.
Каждый раз, когда ПЛК достигает блока счетчика, он будет считать на единицу вверх, поскольку вход истинный. При каждом нажатии кнопки счетчик будет считать не только один раз, но и 2, 3, 5 или даже больше.
Чтобы избежать этого, мы будем использовать блоки обнаружения края.
R_TRIG Функциональный блок
Единственный фронт, на который мы можем обратить внимание в цифровом сигнале, – это нарастающий фронт. Иногда его также называют положительным фронтом.
Это происходит, когда сигнал переходит от ложного (0) к истинному (1). В цифровой электронике, когда напряжение переходит от 0 до 5 В. Восходящий фронт – это то, что происходит в тот момент, когда мы нажимаем на кнопку.
Когда вход (CLK) обнаружит нарастающий фронт импульса, выход будет установлен. Но только на короткое время, поскольку нарастающий фронт происходит очень быстро. Даже если вход будет истинным в течение следующих циклов сканирования, выход не будет установлен более одного раза. Выход генерирует импульс при обнаружении положительного или нарастающего фронта.
Для облегчения понимания приводим схему функционального блока:
Для генерации очередного импульса на выходе требуется новый нарастающий фронт. Блок, так сказать, запоминает, был ли положительный фронт на входе. Поэтому, чтобы снова установить выход, вход должен стать ложным, а затем снова истинным. Или, как в нашем примере с кнопкой, вам нужно отпустить кнопку и нажать ее снова.
Функциональный блок F_TRIG
Как и в случае с нарастающими фронтами, вы, конечно, можете обнаружить и спадающие фронты. Когда сигнал переходит из состояния true (1) в false (0), это и есть спадающий фронт.
Иногда падающий фронт также называют отрицательным фронтом. Он также работает, генерируя импульс на выходе, но с падающим фронтом на входе.
Обычно этот блок используется для того, чтобы заставить что-то происходить, когда другое что-то останавливается.
Допустим, вы хотите, чтобы при остановке двигателя включалась желтая лампа. Но вы хотите, чтобы это происходило только тогда, когда двигатель уже запущен. Таким образом, желтая лампа включается только в тот момент, когда двигатель останавливается.
Решение: Поставьте и F_TRIG для обнаружения спадающего фронта импульса на выходе двигателя. Затем можно сгенерировать импульс, чтобы установить выход для желтой лампы.
Функциональные блоки таймеров
В предыдущих блоках мы хотели убедиться, что сигнал не превышает время сканирования. Но иногда требуется контролировать длительность сигнала или время его появления.
Именно здесь на помощь приходят функциональные блоки таймеров. Таймеры – одни из самых используемых функций в программировании ПЛК. Они делятся на три различных типа таймеров.
Если вы хотите узнать больше о таймерах и посмотреть, как они работают при моделировании ПЛК, вы можете прочитать статью о таймерах ПЛК. Вы найдете видеоуроки по таймеру задержки включения, таймеру задержки выключения и импульсному таймеру.
Некоторые утверждают, что вам нужно использовать только один из них, потому что с его помощью можно вывести все функции таймера. Но поскольку все три описаны в IEC 61131-3 и предусмотрены в большинстве программ, я хотел бы познакомить вас с ними.
Импульсный таймер (TP)
Первый таймер называется импульсным, поскольку он используется для генерации импульсов определенной длины.
Он принимает два входа и имеет два выхода. До сих пор мы рассматривали только функциональные блоки, в которых входы и выходы были булевыми. Это по-прежнему верно для IN и Q блока TP. Но с PT и ET дело обстоит немного иначе. Они оба принимают переменные типа данных TIME.
PT означает Preset Time и является входом блока. Сюда вы помещаете время, в течение которого вы хотите получить импульс на Q. Как только вход IN станет истинным, выход Q будет установлен на время PT.
ET означает прошедшее время. Это время, в течение которого Q был активен.
Допустим, вы хотите, чтобы вентилятор был включен в течение 10 минут. Тогда вам нужно ввести 10m в PT и установить вентилятор на выход Q. Во многих случаях полезно посмотреть, как долго работал вентилятор. Именно для этого используется ET.
Более подробно функциональность импульсного таймера можно рассмотреть на временной диаграмме выше.
Таймер задержки включения (TON)
Следующий тип таймера – таймер задержки включения или просто TON. Но вместо того, чтобы задавать время импульса, он используется для установки задержки импульса.
При подаче сигнала на вход таймер начинает отсчет. По истечении времени PT будет установлен выход Q. Это также является причиной его названия.
Включает выход после задержки
Таймер задержки включения имеет те же входные и выходные контакты, что и импульсный таймер. И опять же, у него есть ET, чтобы видеть, сколько времени прошло.
На схеме таймера задержки включения ниже показана его функциональность:
Именно этот таймер, как утверждают некоторые, является единственным, который вам нужен. Но прежде чем объяснить, почему, позвольте мне познакомить вас с третьим и последним типом таймера.
Таймер задержки выключения (TOF)
Функциональность таймера задержки выключения (TOF) очень похожа на TON. Но с одним большим отличием.
Отключает выход после задержки
В момент, когда на входе установится значение true, будет установлен выход. Пока вход остается истинным, выход будет включен до истечения времени PT. По истечении этого времени выход будет выключен.
Сначала может показаться, что этот таймер задержки выключения очень похож на импульсный таймер (PT). Так оно и есть, но с одним существенным отличием.
Выход импульсного таймера будет включен в течение времени PT, даже если в середине отсчета времени вход станет ложным. Это происходит потому, что таймер ищет нарастающий фронт импульса на входе. А вот таймер с задержкой выключения прекратит отсчет времени, если на вход поступит сигнал.
Эти три таймера являются официальными, описанными в стандарте IEC 61131-3. Технически вы можете построить все из них, используя только таймер задержки включения. Это делается с помощью небольшой лестничной логики.
Функциональные блоки счетчика
Следующий тип функциональных блоков имеет не только вход и выход. Они также принимают другой тип данных. Пришло время рассмотреть счетчики ПЛК.
Подсчеты очень важны для программирования ПЛК. Сколько изделий произвел станок? На каком этапе последовательности находится инструмент? Существует множество причин для использования счетчиков в программе ПЛК.
IEC предоставляет три различных стандартных блока счетчиков. Один для отсчета вверх, один для отсчета вниз, и один для отсчета либо вверх, либо вниз.
Давайте посмотрим на первую из них и начнем считать!
Счетчик подъема (CTU)
Этот блок счетчика имеет три входа и два выхода. Хотя это кажется много, все они необходимы для того, чтобы уметь считать. Но прежде чем рассмотреть детали каждого входа и выхода, позвольте мне вкратце объяснить, как работает блок счетчика.
Каждый импульс на CU будет отсчитывать CV на 1. Когда CV >= PV, устанавливается Q.
Входной CU ищет нарастающий фронт импульса. Когда это происходит, выходной ЦУ увеличивается на 1. Для этого выходной ЦУ должен принимать другой тип данных: integer.
Так как целое число – это 16-битное число (с первым знаком для знаковых/беззналичных), вы можете считать до 32767. И входной PV, и выходной CV имеют тип данных integer. PV – это предел, когда устанавливается булевский выход Q.
Вход сброса (R) используется для установки значения CV в 0. Обычно мы начинаем отсчет с 0, потому что таким образом выходное значение CV всегда будет представлять количество импульсов, произошедших на CU.
Для тех, кто любит текстовые языки кодирования, приводим тело функционального блока в виде структурированного текста:
IF R THEN
CV := 0;
ELSIF CU AND (CV < PVmax) THEN
CV := CV + 1;
END_IF;
Q := (CV >= PV);
Счетчик падения (CTD)
Считать не только вверх – это полезная вещь. Иногда требуется и обратный отсчет. Часто требуется, чтобы программа ПЛК выполняла определенную операцию определенное количество раз. Здесь очень пригодится счетчик обратного хода.
Каждый импульс на CD будет отсчитывать CV вниз на 1. Когда CV <= 0, устанавливается Q.
Он работает точно так же, как и счетчик вверх, но вместо того, чтобы считать по одному вверх, он считает по одному вниз. Это подводит меня к еще одному различию между счетчиком вверх и вниз. Откуда считать?
При счете вверх мы обычно просто считаем от 0. Но при счете вверх нам нужно задать некоторое значение, от которого мы можем считать вниз. Поэтому нам нужно ввести LD. Когда LD установлен в true, выход CV устанавливается в PV.
В структурированном тексте тело функционального блока выглядит следующим образом:
ЕСЛИ LD ТО
CV := PV;
ELSIF CD AND (CV > PVmin) THEN
CV := CV - 1;
END_IF;
Q := (CV <= 0);
Теперь, когда вы научились считать как вверх, так и вниз, пришло время взглянуть на последний блок счетчика.
Счетчики движения вверх-вниз (CTUD)
Иногда бывает практично иметь возможность считать как вверх, так и вниз. Поэтому IEC также предоставляет официальный блок для подсчета как вверх, так и вниз.
Счетчик имеет 5 входов и 3 выхода. Все они имеют те же названия, что и входы и выходы предыдущих блоков счетчика. Этот блок представляет собой комбинацию двух предыдущих блоков. Все входы/выходы имеют одинаковые функции.
Чтобы лучше понять, как работает этот функциональный блок, позвольте мне показать вам его корпус:
ЕСЛИ R ТО
CV := 0;
ЕСЛИ LD ТО
CV := PV;
ELSE
ЕСЛИ НЕ (CU И CD), ТО
IF CU AND (CV < PVmax) THEN
CV := CV + 1;
ELSIF CD AND (CV > PVmin) THEN
CV := CV - 1;
END_IF;
END_IF;
END_IF;
QU := (CV >= PV);
QD := (CV <= 0);
Сначала этот код может показаться немного сложным. Но на самом деле это просто комбинация счетчика увеличения и уменьшения. CU считает CV вверх на 1, а CD считает CV вниз на 1. Каждый из выходов QU и QD устанавливается с теми же условиями, что и в двух предыдущих блоках счетчика.
Функциональные блоки сравнения
Мне нравится думать о следующем типе функциональных блоков как о задающих вопросы. Равно ли A равно B? CV больше PV? Пришло время сравнить несколько чисел!
На самом деле сравнение – это то, что уже происходило во многих блоках, которые мы уже рассматривали. Возьмем, к примеру, блок OR, который сравнивает два логических входа. Если их сумма равнялась 1, то на выходе устанавливалось значение.
Теперь в FBD можно сравнивать не только булевы типы данных. На самом деле мы можем сравнивать все вещественные числа (извините, математики, воображаемых пока нет) и большинство типов данных. Это не только удобно, но и, уверяю вас, будет часто использоваться.
Основным для всех блоков сравнения является то, что все они имеют два или более входов и один выход. На входе может быть любой элементарный тип данных, а на выходе – булево. При сравнении типов данных нужно быть осторожным, потому что это может быть немного сложно.
Давайте начнем с первого базового блока компаратора:
Равенство (=)
Функциональный блок равенства используется для проверки того, равны ли две переменные друг другу. Если да, то вывод будет установлен. Мне нравится думать, что этот блок задает такой вопрос:
Равна ли величина IN1 величине IN2?
Хотя этот блок может показаться простым, нужно быть немного осторожным с тем, какие типы данных вы здесь сравниваете. Сравнение целых чисел в этом блоке – это, вероятно, тот тип данных, который вы будете использовать чаще всего. Допустим, вы хотите, чтобы выход был установлен, когда машина находится на шаге 12. Тогда IN1 будет переменной шага, а IN2 – 12.
Три точки между двумя входами – это иллюстрация того, что этот блок может принимать более двух входов. Чтобы выход был установлен, все входы должны быть равны. Эта функция описывается так с помощью структурированного текста:
OUT := IN1 = IN2 = ... = INn
Сравнение других типов данных с помощью равенства может вызвать некоторые проблемы. Если вы попытаетесь использовать равенство для сравнения аналогового значения (реальный тип данных) с другим реальным типом данных, вы увидите, что они вряд ли когда-либо будут равны друг другу.
Для того чтобы этот блок установил выход, необходимо, чтобы два входа были точно равны друг другу. Помните, что вещественные типы данных – это числа с плавающей точкой. Вы можете захотеть, чтобы что-то произошло, когда температура достигнет 80 градусов. Но если вы используете вещественные числа, температура должна быть точно равна 80.0 градусов. Для такого типа сравнения лучше использовать комбинацию блоков сравнения. Так вы сможете сравнивать с диапазоном чисел, а не только с одним.
Но когда речь идет о целых числах, а иногда и о словах, очень полезен блок равенства.
Неравенство (<>)
Но что, если вы хотите проверить, не равны ли некоторые числа друг другу? Конечно, можно просто отменить вывод блока равенства. Но это было бы довольно запутанно. Да и зачем это делать, если есть блок, позволяющий сделать именно это.
Этот блок работает так же, как и предыдущий, но проверяет неравенство вместо равенства. Вопрос для запоминания функциональности этого блока может быть таким:
Является ли IN1 НЕ равным IN2?
Если да, то выход будет установлен. Но только до тех пор, пока они не равны. Как только входы станут равными, выход будет выключен.
Тем, кто уже знаком со структурированным текстом, знаком символ неравенства. Оно похоже на то, что во многих языках программирования обозначается так: !=. Но в программировании ПЛК неравенство обозначается так <>.
Имейте в виду, что этот блок принимает только два входа.
Меньше, чем (<)
Если вы помните, раньше у нас была проблема со сравнением реальных типов данных с помощью равенства. Этот и следующий блок могут стать решением этой проблемы. Потому что с помощью этого блока мы можем проверить, находится ли переменная в диапазоне чисел.
Официально этот блок называется возрастающей последовательностью. Но less than – гораздо более простое название для запоминания. Представьте, что вы задаете такой вопрос:
Является ли IN1 меньше, чем IN2?
По сути, он проверяет, меньше ли значение первого входа (меньше) значения второго входа. Этот блок очень хорошо работает с вещественными числами, так как вы можете легко проверить, например, что температура меньше 80,5 градусов.
Не зря официальное название этого блока – увеличивающаяся последовательность. Как и блок равенства, вы можете расширить этот блок, используя более двух входов. В этом случае официальное название приобретает гораздо больший смысл.
Потому что при наличии нескольких входов их значения должны составлять возрастающую последовательность значений. In1 должен быть меньше, чем IN2, тот должен быть меньше, чем IN3 и так далее. Текстово функцию можно описать следующим образом:
OUT := (IN1 < IN2) AND (IN2 < IN3) AND ... (INn-1 < INn)
Больше, чем (>)
Если вы можете составить возрастающую последовательность, то, конечно, можете составить и убывающую. Или, говоря более простыми словами. Вы также можете проверить, больше ли одно значение другого. В этом блоке задается следующий вопрос:
Является ли IN1 больше, чем IN2?
Но, как и предыдущий блок, этот блок тоже может принимать более двух входов. Поэтому этот блок также должен принимать последовательность чисел, но на этот раз убывающую, чтобы установить выход.
Каждый вводимый текст должен быть меньше предыдущего, создавая таким образом убывающую последовательность. Написанная на текстовом языке типа структурированного текста, функция блока “больше, чем” выглядит следующим образом:
OUT := (IN1 > IN2) AND (IN2 > IN3) AND ... (INn-1 > INn)
Комбинация блоков “больше, чем” и “меньше, чем” также может быть очень полезной. При работе с аналоговыми значениями часто требуется проверить, находятся ли они в определенном диапазоне. Например, если температура находится в диапазоне от 90 до 100 градусов. Здесь вы можете проверить, больше ли температура 90, а затем проверить, меньше ли она 100.
Широко используется комбинирование блоков сравнения. Часто можно увидеть блок равенства в сочетании с блоками less than или greater than. Хотя это всего лишь комбинация блоков, они часто имеют свои собственные функциональные блоки:
- Меньше или равно
- Больше ИЛИ равно
Функциональные блоки выбора
Сравнение двух или более значений полезно. Но иногда вместо сравнения необходимо выбрать одно из значений. Функциональные блоки выбора предоставляют такую возможность.
Их объединяет то, что они дают возможность выбрать значение. С условиями или без них. Суть этих блоков сводится к назначению. Вы выбираете один из входов и назначаете его на выход этих блоков.
Пристовить
Этот блок делает то, что присваивает входное значение своему выходу. И знаете что? Этот блок делает точно то же самое. Вы можете удивиться, почему FBD предоставляет два блока с одинаковой функцией. Они тоже похожи, но с одним существенным отличием.
Первый и самый простой блок выбора – это функциональный блок перемещения. На самом деле, вы уже видели этот блок раньше. Или, по крайней мере, блок с такой же функциональностью. Функциональный блок присваивания.
В то время как этот блок можно использовать с любыми типами данных, блок присваивания можно использовать только с булевыми типами данных. С помощью блока перемещения вы можете переместить любой тип данных в любой тип данных.
Для тех, кто любит структурированный текст, представление блока выглядит следующим образом:
OUT := IN
В функциональной блок-схеме блок перемещения выглядит следующим образом:
Как вы можете видеть, этот блок имеет только один вход и один выход. Концепция выбора не совсем применима к этому блоку, поскольку у вас есть только одно значение для выбора. Однако во многих случаях вы сможете добавить больше выходов к блоку перемещения. Таким образом, блок перемещения можно использовать для перемещения значения в разные места.
Когда я сказал, что этот блок работает с любым типом данных, я действительно имел это в виду. Вы можете перемещать значения из любого типа данных в любой тип данных. Вам даже не обязательно помещать на выходе тот же тип данных, что и на входе. Вы можете свободно перемещать, например, целое число в вещественное, TIME в двойное слово и так далее.
Это делает блок перемещения немного сложным. Вы должны быть очень осторожны при переходе от одного типа данных к другому. Новичкам я настоятельно рекомендую перемещать значения только в тот же тип данных, что и входной. На самом деле, я редко рекомендую смешивать типы данных даже профессионалам. Это только усложнит вашу программу ПЛК.
Двоичный выбор (SEL)
Бинарный выбор немного приближает нас к понятию выбора. Он дает возможность выбрать одно из двух значений для последующего назначения на выход.
Название указывает на то, что с помощью двоичного (булева) входа можно выбрать одно из двух входных значений. Поэтому у этого блока три входа. Один – условие (G) и два значения (IN0, IN1). Условие принимает тип данных boolean и используется для выбора между двумя значениями.
Скорее всего, вы заметили, что названия входов немного отличаются от названий других функциональных блоков. Это сделано только для того, чтобы облегчить понимание блока. Поскольку условие (G) может принимать два различных значения 0 и 1, имеет смысл назвать входы IN0 и IN1.
Если G равно 0, то будет выбран вход IN0. А если G равно 1, то будет выбран вход IN1. Значение выбранного входа будет присвоено выходу (OUT).
И снова эта функциональность может быть представлена в виде структурированного текста:
IF G = 0 THEN
OUT := IN0
ELSIF G = 1 THEN
OUT := IN1
END_IF;
Расширяемый мультиплексор
В некоторых случаях вам нужно выбрать более двух значений. В этом случае на помощь приходит расширяемый мультиплексор. Слово “мультиплексор” может показаться вам знакомым, если вы немного разбираетесь в цифровой электронике. И этот блок имеет ту же функциональность – выбор одного из многих входов.
Как и предыдущий блок, этот блок имеет два типа входов. Условие (селектор) и несколько входных значений. Блок выбирает один из N входов в зависимости от значения селектора.
В отличие от двоичного селектора вход условия, названный в этом блоке K, может принимать не только булевский тип данных. Фактически, он может принимать любой элементарный тип данных. Хотя единственный тип данных, который действительно имеет смысл использовать здесь, – это целое число.
Поскольку вам нужно выбрать между входами от IN0 до INn, имеет смысл задать условие K целым числом. На самом деле допустимо задавать K только в виде числа от 0 до n. Концепция функции может выглядеть следующим образом:
OUT := INK
Где K должно находиться в диапазоне 0 – n, где n – количество входов.
Расширяемая минимальная функция (MIN)
До сих пор вы видели, как выбирать значения с помощью входа условия. Этот вход может быть двоичным или целым числом, в зависимости от того, между сколькими входами вам нужно сделать выбор.
Но иногда вы хотите выбрать значение в зависимости от самих значений. Это может быть выбор наибольшего или наименьшего значения среди различных переменных.
С помощью следующих двух функциональных блоков вы можете сделать именно это.
Выбор переменной с наименьшим значением – это то, что, я могу гарантировать, вы будете использовать в какой-то момент. Официальное название этого функционального блока – расширяемый минимум, но часто его называют просто минимум или MIN. Он называется расширяемым, потому что вы можете добавить любое количество входов в этот блок. Все входы могут принимать любой элементарный тип данных, и они даже могут быть разных типов в одном блоке.
OUT := MIN (IN1, IN2)
На выход блока всегда будет назначено значение наименьшего входа. Или, другими словами, будет выбран вход с минимальным значением.
Расширяемая функция максимума (MAX)
Если у вас есть блок для нахождения минимального значения, то, конечно, есть и блок для нахождения максимального значения. Для этого в FBD предусмотрен стандартный функциональный блок.
Он работает точно так же, как и функция минимума, но выбирает переменную с максимальным значением и присваивает это значение своему выходу.
Также этот блок принимает на вход и на выход любой элементарный тип данных.
В обоих этих блоках вы должны знать, какой тип данных вы используете на выходе. Если вы пытаетесь найти максимальное значение двух реальных типов данных, например 80.46 и 206.95, а в качестве выходных данных используете integer, то на выходе получится просто 206.
OUT := MAX (IN1, IN2)
Особенностью этих двух блоков является то, что вы можете сравнивать типы данных времени и даты. Допустим, в вашей программе ПЛК много меток даты, и вы хотите найти самую последнюю. С помощью функции maximum вы всегда сможете найти самую последнюю дату.
Ограничитель (LIMIT)
Объединив два предыдущих функциональных блока, мы можем создать совершенно новую функцию. Эта функция связана не столько с выбором, сколько с ограничением. Именно поэтому этот функциональный блок называется ограничителем. Чаще всего в программе ПЛК требуется установить ограничения на диапазон значений.
Функция ограничителя на самом деле состоит из функций минимума и максимума. Это можно увидеть, если взглянуть на тело функционального блока:
OUT := MIN ( MAX (IN, MN), MX)
На самом деле здесь происходит следующее: вы устанавливаете минимальный и максимальный предел для любой переменной, которую вы помещаете на вход (IN). Минимальное и максимальное значения задаются на входах (MIN и MAX), и все три входа могут принимать любой элементарный тип данных.
Создавайте собственные функциональные блоки
Все эти функциональные блоки описаны в IEC 61131-3, официальном стандарте для языков программирования ПЛК. На схеме функциональных блоков представлено гораздо больше функциональных блоков. Фактически для каждой операции, которую вы можете выполнить в программировании ПЛК, существует почти функциональный блок. Среди них:
- Арифметические функциональные блоки
- Функциональные блоки сдвига битов
- Функциональные блоки символьных строк
- Функциональные блоки преобразования
- Функциональные блоки связи
И многое другое…
Я настоятельно рекомендую вам для начала просто поиграть с IDE для автоматизации, например TIA Portal или Codesys. Попробуйте создать простые программы для ПЛК, используя программирование функциональных блоков. Я считаю, что это лучший способ узнать о новых функциональных блоках.
Дело в том, что каждый функциональный блок представляет собой функцию. Внутри корпуса функционального блока вы найдете описание функции либо в виде структурированного текста, либо в виде лестничной логики, либо на другом языке программирования ПЛК. Существует множество стандартных блоков, предоставляющих множество различных функций. Но иногда этого просто недостаточно.
Поэтому вам придется создавать собственные функциональные блоки. На самом деле это один из краеугольных камней в структурированном программировании ПЛК. Оставайтесь с нами на PLC Academy, чтобы узнать об этом больше 🙂 .