Штабелер – устройство, расположенное после гильотины. Для отражения своего состояния он может иметь один или два датчика. Таких состояний обычно два - закрытое и открытое. Находясь в исходном состоянии - закрытом, штабелер принимает лист металла и затем - в открытом состоянии сбрасывает его в накопительное устройство. После этого возвращается в исходное состояние. Мы рассмотрим штабелер, содержащий один датчик. Для правильной трактовки текущего состояния штабелера нужно в ручном режиме установить его в исходное состояние и далее вести отсчет состояний уже от него.
Запуск и режимы работы штабелера
Система управления линией профилирования металла поддерживает три базовых режима - ручной, полуавтоматический и автоматический. В программе им соответствуют реле - M9, M10, M11. Штабелер имеет всего два режима работы, названных далее ручным и автоматическим. В ручном режиме работы системы он работает соответственно в ручном режиме, а в остальных - в автоматическом.
В ручном режиме штабелер управляется только кнопкой "Штабелер", при каждом нажатии которой он отрабатывает половину своего цикла работы, поочередно переходя при каждом нажатии кнопки из одного состояния в другое. В автоматическом режиме штабелер отрабатывает полный цикл. В этом случае он принимает лист, находясь в исходном состоянии, затем сбрасывает его на приемный стол и после этого возвращается в исходное состояние, где ожидает поступление очередного листа.
На рис.1 представлен код, который запускает в работу штабелер, устанавливая единичное значение флагу bПускШтабелера. При этом текущий режим ему задается флагом bРежимШтабелера, нулевое значение которого определяет ручной режим работы, единичное - автоматический.
В режиме системы управления «Автомат» запуск штабелера должен осуществляться автоматически после срабатывания гильотины. Реализует такую последовательность код на рис. 2, где флаг M44 отражает текущее состояние гильотины: когда он равен единице, гильотина находится в рабочем состоянии. Функциональный блок ЗапускШтабелера определяет выполняется ли прокат и если это так, то, дожидавшись единичного состояния флага M44 (гильотина начала работу), а после этого - нулевого (гильотина завершила работу), выдает сигнал штабелеру, установив единичное значение флагу bПускОтГильотины (см. также рис. 1). Но, заметим, разрешение на формирование этого сигнала выдает флаг bРаботаОтГильотины.
На рис. 3 представлена схема, которая содержит функциональные блоки управления непосредственно штабелером. Функциональный блок «Датчик» работает напрямую с датчиком штабелера, реализуя простейший фильтр ложных срабатываний датчика (тот же дребезг контактов). Алгоритм работы данного ФБ в форме автоматного графа показан на рис. 5. Текущее состояние автомата, равное 0, соответствует нулевому значению датчика, а равное 1 - единичному (см. также формирование сигнала состояния датчика штабелера - bSensor на рис. 4). Состояние 2 – промежуточное. В нем ожидается подтверждение того или иного значения датчика. Время этого ожидания (задержки ответа датчика) определяется настройками.
Функциональный блок Штабелер1ДБУ реализует алгоритм управления. Он в форме автоматного графа представлен на рис. 6. Номера состояний автомата можно наблюдать на выходе ФБ и тем самым судить о работе системы управления штабелером.
Рис. 5. Алгоритм работы с датчиком
Рис. 6. Алгоритм управления штабелером
Выводы
Выше мы рассмотрели лишь малую часть реального проекта на ПЛК (в проекте подобных подобных автоматных ФБ почти 40 штук). Более того, данное описание можно рассматривать и как подход к документированию автоматных программных проектов. И не только на базе ПЛК – любых. Предложенный метод программной реализации автоматов позволяет в полной мере ощутить преимущества параллельного программирования. Все упомянутые выше ФБ это параллельные процессы. Параллельно отслеживается датчик штабелера – это ФБ «Датчик», параллельно анализируются процессы в профилегибочной линии – ФБ «ЗапускШтабелера», параллельно организуется управление штабелером – ФБ «Штабелер1ДБУ». В наши задачи входит создание автоматных алгоритмов ФБ и определить взаимодействие между ними. За корректность взаимной работы программных автоматов будет отвечать реализованная модель параллельных вычислений.
Конечно, не устанем повторять, созданные параллельные процессы существуют в рамках определенной модели параллельного программирования. При этом мерой аппроксимации реальных процессов на вычислительные процессы, реализуемые даже на простейших ПЛК, будет служить длительность дискретного такта сетевой автоматной модели. Это аналогично, например, частотной характеристике какого-нибудь цифрового прибора. Того же осциллографа. Чем меньше длительность дискретного такта модели (в ПЛК это длительность его дискретного такта), тем с большей достоверностью мы сможем судить о модели реальных параллельных процессов, тем более точную можем создать модель. По аналогии, чем выше частота осциллографа, тем точнее он отражает протекание реальных процессов.
PS. Засады ПЛК
Статья была бы закончена много раньше, если бы не возникшая неожиданно проблема. Она, может быть, специфична и характерна, скорее всего, только для ПЛК. Но, на мой взгляд, о ней должны знать программисты. В том числе и те, которые на ПЛК не работают.
Итак. Вдруг, ни с того ни с сего, перестала работать часть проекта, отвечающая за реализацию проката линии. Пришлось отложить все дела и заняться выяснением ее причин. На первый взгляд ошибался ФБ, который успешно работает в составе других проектов. Перестала работать функция паузы, отключающая двигатели линии на какое-то время. Ей соответствовало реле, значение которого поступало на отдельный вход подозреваемого ФБ. И, как убедила отладка, на входе этого блока реле исправно меняло свое значение, отражая состояние паузы, а локальная переменная внутри ФБ, поставленная ей в соответствие, – нет.
Для обычного программиста такая ситуация – нонсенс. Что может повлиять на значение локальной переменной, которая должна и просто обязана отражать значение входного параметра ФБ? Ни что! Но это в обычном программировании. В ПЛК эта аксиома, оказывается, не действует. Почему? – объясню далее…
Начнем немного издалека. По крайней мере, в той среде программирования, которую я использую (ISP Soft), не существует понятия подпрограммы. Поначалу это вызвало недоумение, но с этим пришлось смириться. Нет и нет. Вместо подпрограмм можно использовать процессы - постоянно работающие ФБ, которым, когда это нужно, посылается сигнал запуска. А программный блок, выдавший подобный сигнал, просто ожидает завершение его работы. Автоматы в этом помогают прекрасно: выполнение процесса (после сигнала) – состояние ФБ не равное нулю, завершение работы – исходное состояние равное нулю. Все это прекрасно отработано и даже не на одном проекте.
Но тут другая беда - локальная переменная не отражает состояние входа?! Локальная, ведь?! Отладчика помог выяснить это достаточно быстро. Но как понять, что влияет на ее значение столь фатально? Кто на ее значение может повлиять, если не только сам ФБ? Так думал бы обычный программист, так думал и я. Но, ведь, отладчик явно демонстрирует: входной параметр и локальная переменная живут каждый своей жизнью.
Путем «научного тыка», т.е. постепенным исключения всего, что только можно было исключить, удалось установить, что флаг изменяется еще в одном месте. Это было поправлено и все заработало. Уф!!! Но как обнаруженное изменение (пусть и в другом месте) влияет на локальную переменную внутри некоторого ФБ? Ведь, это нарушает принцип локальности?
Безусловно, можно было бы дальше продолжить «вскрытие» и разобраться окончательно в проблеме, но смысла в этом особого нет. Просто потому, что причина, казалось бы, понятна. В ПЛК нет подпрограмм, но и того, что с ними достаточно тесно связано – локальных переменных. Но, если в отношении первых это ясно из контекста, т.к. о подпрограммах в описании на язык не говорится ни слова, то понятие локальных переменных используется сплошь и рядом. Вот уж, действительно: «Если на клетке слона прочтешь надпись: буйвол – не верь глазам своим».
Но, что интересно, в рамках другой среды программирования – WPL Soft понятие подпрограммы есть. Но у этих подпрограмм нет параметров. Отсюда можно сделать вывод: подпрограммы есть, но стека нет, т.к. именно через него организуется механизм передачи параметров подпрограммам. Другого столь же простого механизма, я просто не знаю.
Итак, итог. Ну, нет подпрограмм и нет. С этим можно смириться. Параллелизм ФБ позволяем это обойти достаточно легко. Кроме того, понятие подпрограмм оно не из реальной жизни. Все, что находится вокруг нас – натуральное и природное обходится без них. Теперь, похоже, я так же, как к подпрограммам, будут относиться и к локальным переменным. Правда, буду все же их использовать. Просто потому, что они в языке есть и они удобны. Хотя случившееся будет уроком. Но, конечно же, пока я работаю на ПЛК и на языке релейных схем. Может, правда, на ПЛК других фирм ситуация иная? Просветите, если не сложно.
Воистину, «Век живи – век учись». Но … что-то мне, вдруг (опять это вдруг?), подсказало, что проблема совсем не в локальных переменных, хотя и они вносят здесь свою «копейку», а в параллельных процессах. Ну, а как же отладчик? А он, вольно или нет, но запутывает или даже, как в нашем случае, искажает реальную картину. Как плохой осциллограф. А потому проблема больше в нас самих и в правильном понимании происходящего. Особенно, когда речь идет о параллельных процессах. Но об этом, если такое случится, в следующий раз.