Как стать автором
Обновить

Критические ошибки проектирования АСУ ТП и программирования ПЛК

Время на прочтение 5 мин
Количество просмотров 35K
Всего голосов 22: ↑19 и ↓3 +16
Комментарии 50

Комментарии 50

Что касается реле, то это такие азы промавтоматики, что только полностью некомпетентный человек способен совершить такую ошибку.
Но они встречаются и по сей день. Сам всегда диву даюсь. Конкретный пример такой ошибки был обнаружен меньше месяца назад, после изучения аварии на оборудовании.
Это говорят программисты, у которых goto fail не сработал, да?
Программисты в ошибках релейной схемы не виноваты. Да они несут ответственность за безотказную работу ПЛК.
Программисты несут ответственность? Не в этом мире.
Я знаю одну секретную схему. Она легко гуглится по запросу «схема кнопочной станции на магнитном пускателе». Это в ПТУ изучают по специальности «электрик чего-то там». А у «программистов» основная проблема называется безыдейное кодерство. Без надежды на out of the box thinking.
В АСУ ТП вы с этим «out of the box thinking» долго не продержитесь, матчасть знать приходится. По сравнению с десктопными кабинетными программерами это совершенно другой мир.
И что сделали с тем, кто допустил такую ошибку? Премировали?
У вас, наверное, опечатка в слове премировали, в первой же букве. Вставший ГОК это должно быть довольно дорого, не считая замены оборудования.

И вспомнился классический анекдот: «У вас админа штрафуют или увольняют при аварии?» — «Природу смотреть отправляют. В багажнике.»
Кто-то оказался столь обижен, что не поленился пробежать по всем моим комментариям, за которые ещё можно голосовать. Видимо, природу показали, а потом обратно привезли =)
НЛО прилетело и опубликовало эту надпись здесь
Благо, такая ошибка произошла не по нашей вине (мы проектируем и внедряем АСУ ТП ), не наш проект. Мы участвовали в комиссии по расследованию причин аварии. А допустили проектировщики данной АСУ ТП, кто они, мы не знаем, эксплуатационная организация, такую инфу нам не предоставляла.Так что врядли эта ошибка, дойдет до разработчиков.
Почему-то я совсем не удивлен
Хм… У меня в Codesys 3.5 «эависает» modbus. Между СПК и устройством вывода. И может это произойти когда подаю сигнал на включение ТЭНа. Соотвественно это приводит к аварии. Вот как с этим бороться, ума не приложу.
Посмотреть, какой умник проложил проводку шины недалеко от контактора ТЭНа или силовых кабелей. Ну и развести проводку подальше. Убрать металлорукава. Чисто «хозяйственные» вещи сделать, короче.
дело не в кодесиське, как вам написали выше, а в кривой прокладке кабелей. Не удивлюсь, если у вас монтажники где-нибудь экран убрали. 1 к 1 случай у меня на наладке несколько лет назад. При переключении одного контактора модбас отваливался и возвращался не скоро. Талантливые монтажники содрали экран с витой пары сразу на входе в шкаф и внутри шкафа пара осталась беззащитная. Экран приделали, но этим проблемы не ограничились.
Мне на одном объекте наши таджики говорили мол «мамой клянуся, нигде скрутка нет» на кабеле под rs485. Неделю искали, но таки нашли.

Аккуратно упрятанная в лотке недалеко от диспетчерской, витая пара была скручена, экран болтался. Недалеко проходил другой лоток, с питанием в том числе лифтов, что давало неплохую наводку при пуске/останове лифта. Но так как сбой сильно нерегулярный, то ловили долго.
:)))
Во времена, когда я запускал электростанции, у меня там хронически имелся модбас. Большинство мест некритичные, но одно… И всё это работало через AnyBus. Кабель брошен, как попало. Тут кожуру содрали вместе с экраном, там звездой кабель бросили. Хорошей такой звездой, каждый луч по несколько десятков метров. И начинается «ну ты настрой там как-нибудь, что нам, в минус (от 20 до 45) по улице лазить всё переделывать?» :)
Вот тогда я этот modbus возненавидел :)
Собственно, на первом же объекте эмпирическим путём было найдено решение. Вместо витухи для 485 надо бросить профибасовский кабель и AnyBus поставить вплотную к вражескому устройству. Но, в дальнейшем, это не учли и на каждом объекте пляски с бубном начинались по-новой :)
А ещё немало радости доставил KVM удлинитель Gefen. Из-за него каждая перезагрузка рабочей станции была событием…
Здесь программист производит линеаризацию аналогового входа на основе библиотечной функции FC105. В основном цикле по включению бита М0.1 происходит масштабирование аналогового сигнала. Все бы хорошо, но если в ПЛК не загрузить тот самый FC105, то при выполнении данной строчки, ПЛК вывалится в «СТОП SF» если не задать обработчик программных ошибок, так называемый OB121.
С сименсом не работал, но возникает естественный вопрос: по какой причине в контроллер может не залиться библиотечный модуль использованный в программе? Если инженеру требуется где-то руками повторно добавлять модуль, который он использовал, в список заливаемых на контроллер, то это вопиющая некомпетентность разработчиков среды программирования. Эдакое места гарантированных ошибок по человеческому фактору.
Да такая возможность в сименсе есть, загрузить блоки программы по отдельности, и забыть залить библиотечный модуль. Но в данном случае это показано для примера, показать поведение ПЛК, если программно не обработать ошибки ПЛК.
Также как и вы не работал с siemens'ом, но от прочтения такой новости глаза на лоб лезут. Это что же за чудо маркетологи у немцев, раз умудряются такое клиентам втюхивать?)
Описанная автором проблема выглядит мягко говоря надуманной. STEP7 очень мощная и продуманная среда. Ну а если специалист не знает как работать с библиотечными функциями, то это значит, что ему не надо программировать ПЛК.
Если специалист не знает, как работать с целевым ПЛК — то он не специалист. И место ему в подмастерьях у более опытного наставника.
На среду разработки часто обращают внимание в последнюю очередь. Больше обращают внимание на цену, бренд, надёжность, функционал, наличие совместимого оборудования и модулей расширения, наличие библиотек под прикладную область, обещания решить определенный спектр проблем, поддержку. Многое из перечисленного маркетологи могут продать лицам принимающим решение о выборе вендора. И обычно это отнюдь не инженер.
Оно и видно, что не работали. Не читал, но осуждаю…
Текущее (и почти уходящее) поколение контроллеров сименс (Степ 7-300/400) позволяет программисту взять нож и прострелить себе ногу в трёх местах. И это очень хорошо — многие вещи можно сделать проще, не выворачиваясь наизнанку через задницу.

Большой плюс такой поблочной работы в том, что несколько человек могут независимо работать с одним контроллером — например, делать каждый свою часть программы. Каждый может подключиться к контроллеру, внести изменения в один блок и загрузить его в контроллер. Остальная часть программы останется без изменений, контроллер продолжит работать без остановки.

Хотя, тенденция держать инженера за идиота есть. Сименс таких вольностей, пожалуй, больше других позволяет. Тем не менее, совсем отстрелить ногу не получится. Предыдущее поколение (Степ 5) позволяло вызвать Сатану при правильно составленном указателе :) А именно, собрать указатель на область памяти, в которой хранится программа. И, само собой, записать туда что-нибудь. Read-only в контроллерах почти нет. Только часы, слово состояния, входная периферия и ещё немного мелочей.
Новое поколение сименса (1500) вольностей позволяет уже меньше.

Надо понимать, что это совершенно другой мир, в отличие от настольного программирования. Мы тут до сих пор пишем почти что на ассемблере, оперируем отдельными битами, работаем в реальном времени, а большой считается программа уже в несколько килобайт :)
Это не всякие си шарпы, дотнеты и прочие явы, где «Hello, world!» будет занимать несколько (десятков) мегабайт, требовать кучи библиотек, содержать в себе хренову тучу классов (ради одного «Hello, world!») и исполняться за совершенно непредсказуемое время. А ещё, разработчик оной программы не то, что ногу прострелить себе не сможет — ему чтоб коленку почесать, придётся 10 раз сказать среде разработки и операционной системе «да, чёрт возьми, я уверен, что я хочу почесать свою коленку. Да, свою, мать вашу. Да, ни миллиметра вправо-влево» ;)

PS Сименс таки один из лучших. На мой взгляд — самый лучший.
Надо понимать, что это совершенно другой мир, в отличие от настольного программирования. Мы тут до сих пор пишем почти что на ассемблере, оперируем отдельными битами, работаем в реальном времени, а большой считается программа уже в несколько килобайт :)
Это не всякие си шарпы, дотнеты и прочие явы, где «Hello, world!» будет занимать несколько (десятков) мегабайт, требовать кучи библиотек, содержать в себе хренову тучу классов (ради одного «Hello, world!») и исполняться за совершенно непредсказуемое время. А ещё, разработчик оной программы не то, что ногу прострелить себе не сможет — ему чтоб коленку почесать, придётся 10 раз сказать среде разработки и операционной системе «да, чёрт возьми, я уверен, что я хочу почесать свою коленку. Да, свою, мать вашу. Да, ни миллиметра вправо-влево» ;)
Вы слишком акцентируете на этом внимание. Оно иногда ближе к системному программированию, чем к прикладному, но это далеко не всегда и не для всех ПЛК. И МЭКовские языки ощутимо дальше от железа, чем обычно ассемблер. Оперирование битами и подсчёт памяти ничем (кроме характерных масштабов) не отличается от того же на x86_64.

Не знаю, как на сименсе, но на многих контроллерах, хотя и реализуем hard rt (т. е. задержки обработки сигнала предсказуемы), но он имеет довольно большие задержки (десятки миллисекунд в лучшем случае), что не идёт ни в какое сравнение с тем, что происходит в случае микроконтроллеров. А все реальные развлечения у программистов сименса при написании виртуальной машины, под которой уже работает ваш софт.

И по большей части программирование ПЛК для меня выглядит скучно по сравнению с нормальным системным или прикладным программированием. Не стоит с таким пренебрежением относиться к .net и java, там программы бывают на порядки сложнее того, что используется в промавтоматизации. Хотя есть довольно массовый сегмент всякого формоклепания/сайтописания который по рутине сравним с прописыванием пожарных датчиков в АРМ для болидовской машинерии.
STL — это типа ассемблер и есть. Упрощённый, конечно.
Алгоритмы другие, не спорю. И подход другой. Задержки не реализуются через какой-нибудь delay() — из-за этого встанет вся программа. Только таймеры. Циклы тоже — в каждом скане одна итерация обычно. Фронты сигналов… У новичков (после настольного программирования) крыша едет от таких фокусов :) А мне настольное программирование скучно тем, что оно какое-то слишком виртуальное. Руками не пощупаешь, как сожжённую железку :)

Что касается десятков миллисекунд, то это нормальное время для одного скана.

PS DIHALT как-то верно заметил про МЭК языки: представьте, что у вас в программе все строки выполняются одновременно :)
Мне непонятен ваш термин «настольное программирование». Если это написание софта под desktop, то там вариативность тоже высокая. Есть софт для работы со звуком, видео, где уже мягкий realtime при захвате является болью; есть всякая математика, где нужно влезть в разумное количество памяти и процессорное время; есть ide, где куча развлечений с индексами для поиска, регулярных структурных изменений программы, да и просто работа с большими объемами структурированного текста с наличием ошибок в разметке.

Про фронты сигналов крыша скорее поедет на вещах типа verilog/vhdl +)

А то, что происходит при использовании fbd, ld и подобных вещей — ближе к dataflow, где есть явные зависимости по данным, выполнение блоком обработки как только данные придут и т. п. Сейчас довольно популярный подход и в разработке back-end, и в разработке front-end. Стоит только загуглить reactive programming/frp.

Задержки не реализуются через какой-нибудь delay() — из-за этого встанет вся программа.
Задержки через delay я видел, например, в firmware для некоторых контроллерах. При инициализации — вполне нормальный подход. Они вполне нормальны для всяких простых вещей на ардуине или rpi, но на нормальном embedded их не будут делать почти никогда, кроме всяких специальных задержек по несколько (десятков) тактов, где нужен busywait. А в большинстве случаев — прерывания, lock+condwait, блокирующиеся операции, освобождающие ресурсы для других потоков и разные примитивы синхронизации.
Они вполне нормальны для всяких простых вещей на ардуине

И просто в AVR — если делаешь какой-то мелкий однозадачный проект. Чаще всего — тестовый. Грубо говоря, с таким подходом одновременно почесать затылок и коленку не получится. А на ПЛК ещё и сторожевой таймер такого не потерпит :)
WDT на atmega есть, прерывания — тоже. Так что никто не мешает.

Кстати, segnetics smh2010 сделаны на atmega128. На чём сделаны pixel и smh2g — не знаю. Но smh2g, похоже, на arm9 или выше.

Младшие danfoss'ы внутри на простом 16-битном freescale (ныне nxp) mc9s12dg256.
DIHALT как-то верно заметил про МЭК языки: представьте, что у вас в программе все строки выполняются одновременно
И что же здесь верного, если это совершенная ложь?
программирую на allen-bradley.Возможности не подгрузить библиотеку — нет, указателей — нет, редактирование кода без останова — есть, многопользовательский режим — есть. Может всё-таки siemens дрянь?
В сименсе нет библиотек, которые надо подгружать. Всё блоки. Все библиотечные функции реализованы этими блоками. Некоторые из них автоматически подтягиваются в проект при первом использовании. В новом портале, кстати, таких вольностей нет. Там много чего хорошего нет и много чего паршивого добавили. Далее, если какого-то блока не хватает, это сразу же видно в диагностическом буфере. Вообще, это довольно сложно прощёлкать.
Насчёт указателей — были у меня некоторые проекты, в которых я затрудняюсь представить, как бы я обходился без указателей.
Редактирование кода без останова — так это нормально. Всё-таки, не Koyo какое-то.
Редактирование блоков по отдельности — это, кроме прочего, ещё и возможность редактировать свою часть проекта, даже не имея полных исходников.

А ещё Allen-Bradley автоматически программу из контроллера подтянет, когда в онлайн зайдёшь. И гудбай открытый проект… Своеобразная штуковина. Прошу, кстати, обратить внимание: кто тут первый сказал слово «дрянь». Прежде, чем разбрасываться своим экспертным мнением, вам бы стоило поинтересоваться, а что же такое AS-OS Engineering у сименса. A-B здесь близко не стояло. Не умеете готовить сименс — и не надо. Меньше кустарных проектов потом коллегам переделывать.
К слову, у сименса мне больше, чем у других нравится работа с онлайн и оффлайн проектами. У того же GE в онлайне ничего не увидишь, пока онлайн и оффлайн программа не совпадают.
Модуль масштабирования библиотечный, но для среды STEP7 в данном случае он ничем не отличается от пользовательского. А значит и работать с ним надо соответственно, т.е. загрузить в ПЛК перед загрузкой управляющего кода.
Вот необходимость ручного контроля такой заливки для меня и выглядит дикостью. Также, как (почти) невозможность использования vcs.

Для среды разработки нет никакой проблемы вычислять список использованных модулей и проверять наличие и актуальность их версий на контроллере.
Вы правы, проблемы нет. В среде разработки есть (и работает) Cross-reference и сравнение онлайн/оффлайн программы.
Вот необходимость ручного контроля такой заливки для меня и выглядит дикостью.

Как я уже говорил, эта ситуация равносильна той, когда программист взял бы готовый блок у своего коллеги, например.
То, о чем вы говорите, называется системные блоки (SFB/SFC) и они уже находятся в памяти ПЛК.
Функционал для сравнения загруженных блоков в среде есть.
Возможность загружать вручную (хотя никто не мешает грузить всю программу целиком) открывает прекрасные возможности по редактированию программы «на ходу», что в некоторых случаях критически важно.

Ситуация с незагруженным блоком чаще возникает, когда в проект добавлялись какие-то фичи.
Изначально программу прозе грузить целиком, несмотря на отладку по частям (ненужные вызовы просто комментируешь либо условием вызова ставишь Always False).
Кстати, константа FALSE не предусмотрена, это реально грустно. Потому что если какой-то гусь в своем закрытом блоке в конце добавит
SET
S «Always_False»
то возможны часы незабываемого выноса мозга.
это очевидное.
А вот с чем мне приходилось сталкиваться на выездах в чужих программах:
— выход указателем за пределы массива (на STL было дело)
— опрос неинициализированной L-переменной (вообще весело и удивительно, что оно работало)
— залипание релюшек.
совсем из экзотики: на длинном участке текущую позицию хранили в Real в мм, и кое-где не хватало точности real при той реализации программы, что была.
да и многое другое бывало :-)
С откровенно грубыми ошибками в чужих контроллерных программах мне сталкиваться не приходилось. Криво написанные программы — сколько угодно. Без бутылки не разберёшься. А чтобы что-то изменить, так и бутылки не хватит. А уж какую дрянь в SCADA нагородят по неумению…

Самые грубые ошибки, обычно, либо в проекте, либо в монтаже. С монтажом всё понятно: прикрутят провода не туда и как попало — и бегай ищи.
С проектом хуже. Там нагородить можно много больше :) Например, те же не туда и как попало, но оно будет уже в соответствии с проектом. Или заложат в проект защиты и блокировки либо с перестраховкой, либо наоборот. И на пусконаладке у тебя защита не срабатывает, когда она требуется, либо случается круговая блокировка.
А уж всякие модбасы на наладке доставляют просто ни с чем не сравнимое удовольствие — взять хоть приведённый выше пример про контактор :)

У меня был случай. Система на S7-400H, дублированный Profibus. И один из них стабильно висит в отказе, сеть полностью валится. Время от времени они менялись по неустановленной причине. Несколько дней искал. Виновна оказалась операторская панель в одном из шкафов. Тянуть Ethernet туда посчитали нецелесообразным и решили её подключить к Profibus. Да вот незадача: у панельки-то он не дублированный, и через Y-Link она работать не будет :) Решили в шкафу поставить ручной переключатель, который будет коммутировать панель к одному из двух контроллеров (да-да, именно физически переключать кабель Profibus). Никаких репитеров, активных терминаторов и прочих излишеств. Но чёрт с ними, с излишествами. Монтажники наши не дураки, а уже наученные. Если к разъёму приходит только один профибасный кабель — значит, его надо завести на вход разъёма и включить терминатор. И что мы тут имеем? Правильно, 3 терминатора на шине :) На всякий случай, я не просто выключил терминатор (после выключения, к слову, всё заработало), а ещё и кабель переставил со «входа» разъёма на «выход». Чтоб если потом какой умник терминатор включит, так не сеть полностью упадёт, а только панелька отключится.

А уж технологические аварии… Можно словарь писать. Сложили ёмкость при раскачке (я видел 60 м3 цистерну, сложенную таким образом). Взорвали или сожгли ТЭН. Пустили насос всухую (страшный человек этот китаец Всу Х%й). И ладно бы простой насос, а тут с магнитной муфтой… Отключили подачу масла на выбеге… :) Или подали 220 туда, где должно быть 24, и спалили кучу модулей :) Шкаф водой залили… А на одном объекте из-за высокой концентрации серы стабильно сжирает медь. Поэтому, платы долго не живут…
Ещё иногда устраивают полное короткое замыкание на высоком (больше 1000 В) напряжении. Или масляный выключатель взорвут… :)
Я откровенно глупые ошибки обычно встречал после срочных фиксов в криво написанной программе. Когда из-за отсутствия бутылки разобраться ещё не успели, но правку уже внесли и отправили на объект.

А прекрасные проекты и удачливые монтажники — это святое, куда ж без них.
Лично наблюдал: опрос 12 БРИГ-ТВ (прибор измерения вибрации) по модбас в цикле с соблюдением таймаутов. В результате при выключении нескольких приборов на техобслуживание данные с других приборов в цикле считываются с задержкой больше минуты.
По форме:

«Так вод при аварии»
" Схема релейной части отключения главного привода была такой как представлено выше. "
«Вывод

Схемное решение и программные реализации таят в себе не редко глубокие ошибки, которые не всегда выявляются на стадии пусковой наладке.»

и т.д.
— ну как так можно, а?
а само реле притягивать во время пуска главного привода и в рабочем состоянии удерживать его притянутым.

а разве контакты не могут свариться, оставшись замкнутыми после снятия напряжения с катушки?
Так как в этом случае, рабочий контакт является нормально-закрытый, то он только и «имеет» шанс быть «сваренным». Значит после снятия напряжения реле отработает по назначению.
У сигнального реле контакты не могут «свариться». У магнитного пускателя—запросто. Вообще, в системах с автоматическим поиском неисправностей обычно есть контур проверки исполнения команды. В авионике такое практикуется. В железнодорожной автоматике. Да много где.
У сигнального они, скорее, окислятся и сигнала не будет.
Но и на 100% такую вероятность исключать нельзя. Даже занусси ломается. Доказано грузчиками :)
Обычные луддиты с лёгкостью (и не задумываясь) сломают так, что инженер-разработчик бы в жизнь не догадался.
На первом рисунке схема какая-то дурацкая…

А вообще, пост в духе 2х2. Всё правильно, но и совершенно очевидно для тех, кто в теме. Кто не в теме — сразу видно в комментах, как офигевают от сименса :)

Вот если б пост был про проект какой, или технологическую аварию… Почитал бы с удовольствием :)
Есть что вспомнить, да нечего рассказать.
Специфика работы такова, что если начнешь что рассказывать, то как только это попадется на глаза действующим лицам, они моментально узнают себя.

Помнится, как-то на ликёро-водочном заводе мы потратили 4 часа, чтобы найти спирт. Вот же он! море вокруг! но всё опломбировано, а, как назло, люди с допуском к необходимым «краникам» кто в командировке, кто на совещании, кто еще где. Закончилось всё тем, что электрик позвал в подсобку, мы по-быстрому состряпали наш NDA («не спалишь?», — «атвечаю!»), и он из закромов дал мне самогонки.
Еще там же у местных интересный спорт: многие как хобби выбрали самогоноварение, так вот они несут не с завода продукт, а в тайне проносят на завод, чтобы провести все анализы в местной лаборатории, и потом тягаются, у кого «продукт круче».
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории