Блог

CODESYS 3.5: Конечные автоматы для станков и линий - шаблоны и антипаттерны

Конечный автомат для станка или линии - это не «красивая картинка в Visio», а договорённость, кто в какой момент имеет право двигать привод, открывать клапан или запускать цикл. В CODESYS 3.5 его удобно держать как явный набор состояний и переходов, а не как размазанную логику по десятку битов «что-то включилось». Ниже - рабочие шаблоны, типичные ловушки и то, как автомат стыкуется с сервисом, аварией и safety без ухода в расчёт SIL.

Зачем вообще выносить логику в состояния

Станок живёт циклами: остановлен, готовится к пуску, в работе, ждёт оператора, в ошибке, в обслуживании. Если это не оформлено как состояние, в проекте появляются двадцать взаимных блокировок, которые никто не может объяснить одной фразой. Явный автомат даёт одну переменную (или ENUM), которая отвечает на вопрос «где мы сейчас», и переходы, которые можно проверить на стенде сценарием за сценарием.

Минимальный каркас: idle, running, fault, maintenance

Четыре состояния - не догма, но удобный скелет для многих узлов. Idle - можно разрешить подготовку. Running - нормальный цикл. Fault - зафиксированная авария до квитирования и условий безопасного сброса. Maintenance - сервисный доступ, когда нормальный цикл намеренно запрещён. Переходы между ними должны быть именованными в коде и в документации, а не «если вот этот бит, то как-то туда».
Пример связи состояний (упрощённо, без всех сторожевых таймеров):
В CODESYS такой каркас обычно выражают через ENUM состояния и один CASE (или через SFC, если задача естественно «шаговая» и команда договорилась о едином стиле). Важно не спорить о «красоте», а закрепить кто имеет право менять состояние и где это делается - в одном POU или в иерархии с чёткой границей.

Шаблоны, которые реально экономят время

Первый шаблон - один «владелец» состояния»: один FB или PROGRAM, где в начале цикла читаются входы, затем вычисляется следующее состояние по правилам, затем выходы. Второй - таблица переходов в комментарии или отдельном документе, совпадающая с именами в ENUM - тогда ревью не превращается в «угадайку». Третий - сервис и авария всегда «режут» нормальный цикл сверху: пришёл запрет от safety или отключён ключ автомата - вы не «дотягиваете» running до конца цепочкой AND, а жёстко переводите в разрешённое безопасное состояние по правилам проекта.
Сервисный режим имеет смысл трактовать не как «ещё один бит», а как отдельная ветка жизни: другие разрешённые действия, другие HMI-экраны, другие таймауты. Иначе оператор в maintenance случайно получит то же поведение, что в running.

После аварии: сброс ≠ пуск

В fault полезно различать квитирование («я видел сообщение») и восстановление готовности (проверили причину, датчик в норме, условия пуска выполнены). Если смешать в один импульс, на объекте начнут «дребезжать» по кнопке сброса, пока машина не уйдёт в опасную зону неопределённости. В коде это обычно два разных перехода или два разных флага с явной последовательностью в документации.

Тестирование автомата

Проверка state machine на стенде почти всегда дешевле, чем на движущемся станке. Сценарии строятся вокруг графа: нормальный цикл idle→running→idle, каждый тип аварии в fault и обратно, вход и выход из maintenance, «что если пришёл сигнал одновременно из двух мест». Логирование смены состояния с меткой времени в CODESYS (через доступный механизм журналирования) сильно ускоряет разбор полевых «оно само».

Safety на стыке с автоматом

Отдельный safety-контур или SIL-функции здесь не считаются и не заменяются автоматом управления. Практическая связка простая: safety даёт разрешения и запреты, а прикладной автомат не имеет права их обходить ни одним переходом «для скорости». Если в проекте это не проговорено, появляется соблазн «в maintenance чуть-чуть подвинем привод» - и дальше уже вопрос к культуре, а не к CODESYS.

Антипаттерны, из-за которых потом страдают все

Спрятанное состояние в виде пяти BOOL, которые нигде не сводятся в один ENUM, - классика: никто не может перечислить допустимые комбинации. Второй антипаттерн - дублирующие условия «fault если…» в десяти местах: одно забыли, и машина врёт. Третий - переходы без таймаутов там, где ждём датчик или давление: без сторожевого состояния зависнете навечно. Четвёртый - размытая ответственность между двумя FB, которые оба пишут в «текущий режим».

Где уместен СТАБУР

На линейке СТАБУР под CODESYS те же принципы автомата переносятся без смены смысла: важно заранее договориться о библиотеке шаблонов FB, едином стиле ENUM и о том, как версия проекта фиксируется при сдаче. Тогда смена интегратора не превращает граф состояний в археологию.

Заключение

Конечный автомат в CODESYS 3.5 окупается, когда он единственный источник правды о режиме узла и когда переходы узкие, именованные и проверяемые. Остальное - инженерная дисциплина: сервис отдельно, авария отдельно, сброс отдельно от пуска, safety - над слоем управления, а не «вперемешку».

FAQ

Обязательно ли SFC? Нет. Для многих станков достаточно ENUM + CASE или аккуратного разбиения на FB. SFC уместен, когда процесс естественно шаговый и команда готова поддерживать его дисциплиной.
Как не раздуть ENUM на тридцать состояний? Иерархия: верхний автомат линии и вложенные автоматы агрегатов с узкими наборами состояний.
Куда девать ручной режим? Либо отдельные состояния, либо явный подграф с запретами на автоматические переходы - главное, чтобы на HMI это читалось однозначно.
Нужен ли отдельный «initializing»? Часто да, если при старте ПЛК нужна последовательность проверок до готовности к пуску.

Внутренняя перелинковка

Обсуждение