Послання зеленим і недосвідченим #почтипрограмістам ПЛК від #читопрограмера-читовиклада. Ч.2
3. Вибір мови та підходи до програмування.
Яка мова краще?
О! Це саме те професійне питання на форумах, що збирає багатьох програмістів, які починають тролити один одного! Ну що ж, далі йде суто суб’єктивна моя думка (хе, наче в попередніх пунктах була об’єктивною).
Вибирайте мову програмування в залежності від:
- процесу що автоматизується,
- можливостей середовища програмування (зручність налагодження),
- своїх уподобань,
- корпоративних стандартів,
- можливостей мови в даному ПЛК.
Скупо сказав, нижче трохи розжую залежність від процесів.
У якихось стандартах (не пам’ятаю яких) виділені різні типи технологічних процесів: неперервні (Continues), періодичні (Batch), дискретні (Discrete). Для неперервних процесів, зокрема для реалізації контурів регулювання підходить FBD/CFC (повноцінний), для періодичних SFC/Grafcet, для дискретних LD/IL, ST – універсальний. І тут треба сказати про дуже важливий момент – реалізація мов на стільки відрізняється, що в деяких ПЛК, по суті повноцінно використовується тільки одна, а інші для програмістів перестають існувати взагалі. Програмісти! Суперечки щодо мов не мають змісту, поки ви не приземлите їх на конкретну платформу!
Так, наприклад, багато програмістів Step7 (ортодоксальні #Сіматіколюби) не поважають мову FBD, бо вона там дуже куца. Те, що не реалізовано в FBD, реалізовано там в CFC. Я поважаю продукцію Сіменса і навіть являюсь #Сіматіколюбом (не плутати з ортодоксальним), тобто з задоволенням працюю з Step7, але закликаю усіх програмістів розширяти свій кругозір і не зациклюватися на одній платформі! Це стосується випадку, якщо ви хочете з кимось поспорити яка з мов круче. Якщо спорити не збираєтесь, то не варто розпилюватися, краще робити на тому, що добре знаєте!
Звичайно найбільш універсальні це текстові мови типу ST чи IL. Однак, коли справа йде про швидкість відлагодження та інтуїтивну зрозумілість, ці мови поступаються графічним. Так, наприклад з одного погляду на LD в онлайн режимі можна зрозуміти який “контакт не пропускає далі струм і чому не спрацьовує котушка”, іншими словами яка умова не виконалася, щоб спрацював дискретний вихід. Тому для великої кількості взаємопов’язаних умов по”І” чи “АБО”, мова LD можливо буде самим підходящим варіантом.
Мова FBD (з тим функціоналом що в деяких ПЛК мають CFC) доволі наглядно зображають контури регулювання. Нижче на рисунках видно як виглядять однакові програми на мовах FBD та ST.
А ось, як це може виглядіти в онлайні. Відповідно в FBD та ST.
Для Batch процесів (про бачки, Batch звичайно не від слова бачок, тим не менше) – найбільш підходить SFC/Grafcet, але можна використати так званий автоматний підхід.
Ви знаєте що таке автоматний підхід?
Не знаєте? Ні, до АК немає ніякого відношення. Хоч може він і не автоматний?… Я впевнений, що Ви ним користуєтеся … хоч я бачив таких, що не користуються.
Ну добре, ідея наступна. Представте, що у вас є періодичний процес, який складається з декількох стадій:
- простоювання
- умова кнопка “пуск” – наповнення продукту 1 до середнього рівня
- умова сер.рівень – наповнення продукту 2 до верхнього рівня
- умова верхній рів. – нагрівання
- умова досягла температура – витримка
- умова досяг час – злив до нижнього рівня
Як повинна вести себе програма при зливі і відключенні датчика верхнього рівня? Правильно, ніяк, тобто продукт далі повинен зливатися. А знаєте, як веде себе програма у 100% студентських лабораторних роботах при першій перевірці на LD чи ST? (І тут у мене зараз ухмилка на всю морду ліца) Вона відкриває кран наповнення 2-го продукту! Чому? Та тому що спрацьовує середній рівень який відкриває клапан 2-го продукту, і вже не спрацьовує верхній, по якому його закривали. Тобто алгоритм керування в даному випадку повинен бути прив’язаний не тільки до датчиків, а і до стану(кроку) процесу.
У мові SFC/Grafcet, сама мова будується на понятті кроку. Якщо ж ви користуєтесь іншою мовою, можна ввести додаткову змінну кроку. Тоді умова відкриття 2-го клапану звучала б десь так: “Якщо крок=2 і датчик_середнього_рівня=ВКЛ тоді клапан2=ОТКЛ; клапан2=ВКЛ; крок=3”
Якщо так просто можна реалізувати автоматний підхід, навіщо тоді SFC/Grafcet?
Це можуть оцінити тільки користувачі сильних реалізацій SFC/Grafcet, коли він (SFC) є в складі даного ПЛК, і коли є необхідність в реалізації управління складними періодичними процесами. Слід не забувати про такі необхідні речі як:
- можливість добавлення/видалення кроків при вдосконаленні програми (подумайте про плутаницю в нумерації, а в SFC все визначено по зв’язкам)
- контроль часу виконання кроків як по мінімуму так і по максимуму (автоматична генерація алармів)
- необхідність в налаштуванні затримок кроків (різні паузи)
- необхідність в проштовхуванні кроків, ініціалізації SFC-мережі (якщо не уде далі, насильно перемістити)
- відлагодження програми (графічні механізми у SFC з багатошаровістю вкладення макрокроків багато чого варті)
- інтеграція зі SCADA
Типовою помилкою при цьому є написання всієї програми тільки в кроках секцій SFC. Пам’ятайте, що є речі, які не залежать від активності кроку, тому їх треба писати незалежно на інших мовах, або в постійно діючому кроці! Ще одним можливим недоглядом є відсутність програмної реалізації ініціалізації мережі SFC/Grafcet. Якщо умова переходу принципово не виконується, ваша програма зависне на цьому кроці! Що тоді повинна робити експлуатація!? Дайте здогадаюсь – перегрузити ПЛК! Це недопустимо! Зробіть екстрену кнопку ініціалізації SFC, не будьте байдужі до проблем експлуатації, у експлуатаційників хороша пам’ять і вони бувають злими!

У скількох місцях ваша програма змінює значення однієї і тієї ж змінної?
Одна з самих підступних помилок, яку не можуть виловити новачки, пов’язана з тим, що програма декілька раз за цикл змінює одну й ту саму змінну. Не те щоб це було помилкою, але треба чітко розуміти наслідки такого програмування. Відловити причину неправильного функціонування програми не так вже й легко, особливо в тих середовищах, де в інструментах відлагодження ви бачите тільки останнє значення змінної, тобто саме те, яке як правило йде на вихід ПЛК. Особливо збиває з пантелику те, що змінна наче в FALSE – а умова спрацьовує! Старайтеся не розносити запис однієї й тієї ж змінної по всьому проекту, однак якщо іншого виходу немає, пам’ятайте про даний ефект.
Ви любите цикли?
Цикли – дуже потрібна річ, але не настільки, щоб тулити їх усюди.
По-перше, новачки так і хочуть, щоб програма в циклі не пішла далі поки не спрацює умова. І вони довго не можуть зрозуміти чому спрацьовує сторожовий таймер, який їх просто нервує. Перехід до розуміння циклічності виконання ПЛК як правило проходить доволі важко, це ж зміна парадигми від “клацнув воно щось зробилося і зупинилося” до “вічно щось повинно виконувати, причому те саме”. Якщо вже треба підрахувати щось з використанням ітерацій, може є сенс кожну ітерацію запускати в наступному виклику задачі? Досвідчені скажуть “Так цикли ж не для цього потрібні!”. Так, згоден, але ж я звертався не до досвідчених! Цикли можуть знадобитися для інших задач, наприклад програмної обробки для однотипних об’єктів. Тому…
По-друге. Якщо ви звикли до усіляких відлагоджувальних точок зупину, щоб подивитися, а що там всередині на n-й ітерації, то … треба згадати що при цьому зупиняється ПЛК, і … управління процесом теж! Так, є і інші механізми відлагодження, але є ще ефект #платфородепендента. Просто пам’ятайте про це, коли у вас буде вибір робити цикл з 5-ма ітераціями чи викликати їх окремо.
По-третє. Якщо Вам, скажімо, треба буде деякі елементи в процесі наладки виключати з циклу? Так, додаткові іфи спасуть ситуацію. Просто черговий раз подумайте.
Якщо у Вас склалося враження наче я #циклофоб, то мушу Вас заспокоїти, що це зовсім не так. Хоча, цикли мені робили і погану послугу, вірніше я собі ними,.. ну Ви зрозуміли.
Ви користуєтесь стрибками по міткам?
Тоді пам’ятайте про читабельність програм (це можна і в комп’ютерних програмістів спитати) і про сторожовий таймер, особливо якщо стрибок іде вище по коду. Але не переживайте, дядько #Вачдог буде вам добрим вчителем.
4. Робота зі змінними.
А скільки у вашій програмі глобальних змінних, може варто їх опустити на рівень локальних?
Якщо середовище розробки має можливості роботи з локальними змінними, це значно спрощує життя, адже глобальні змінні потрібні тільки для узгодження роботи між програмними POU та обміном з іншими підсистемами (наприклад зі SCADA). Однак треба пам’ятати, що локальні тимчасові змінні в межах функції можуть використовуватися тільки для проміжних обрахунків, значення яких не запам’ятовується між викликами. Якщо ж треба пам’ятати проміжні результати – користуйтеся функціональними блоками, та використовуйте там локальні постійні змінні.
Ох, знову набивати уставки! Та скільки можна?!
Якщо при виключенні живлення ваші змінні обнуляються, а там повинна зберігатися важлива #павернезалежна інформація про уставки, налаштування, чи ще щось там, що не повинно зникати при виключенні живлення – шукайте в документації як зробити їх перманентними (ретентівними та ще якось по іншому можуть називатися). Може для цього достатньо лиш десь поставити галочку, може є спеціальна пам’ять, а може просто треба їх об’явити з потрібним ключем.
Буратино дали три яблока. Два он съел. Сколько яблок осталось у Буратино? Думаете одно? Ничего подобного. Никто не знает сколько у него уже было яблок до этого. Мораль — всегда обнуляйте переменные!
Якщо Ви не будете обнуляти, скажімо, локальні змінні, то на підприємстві навіть через декілька років після вашого від’їзду може з’явитися полтергейст, який буде спонтанно включати насоси і клапани. Не вірите? Припустимо у Вас є в програмі локальні тимчасові змінні, які ніде не ініціалізуються. І ви, по можливо поганній старій звичці, вважаєте, що вона дорівнює нулю (у деяких платформах це дійсно так). Так, от, у вас є умова на включення і є умова на виключення, однак є ситуації, в яких жодна з умов не спрацьовує. В якому буде змінна стані? А хто його знає! Але припустимо, що по збігу обставин (зірки, удача-сиринча і все таке) протягом пусконаладки ця змінна, навіть в ситуації коли жодна з умов не спрацьовувала, дорівнювала нулю. І це вас влаштовувало. Але зірки бувають такі підступні, що в певний час їх настрій починає створювати описані вище полтергейсти. Звідки я знаю? Тому що колись робив такі помилки і приходилось боротись з полтергейстом.
Як Ви називаєте змінні ПЛК?
На моєму першому об’єкті змінні називалися так: “VitrataSokuNaDruhuSaturaciju”. Все зрозуміло? Ну звичайно, навіть тим, хто не знає що таке ПЛК. Однак подумайте, як буде виглядіти формула з 10-ма змінними подібного типу, скільки прийдеться працювати мишкою і буферизувати зображення у своїй голові. Не налякав? То може ви швидко зможете знайти потрібну змінну серед декількох сотень, чи тисяч, не користуючись пошуком?
Якщо середовище програмування дає можливість символьного іменування змінних, програмних одиниць (функцій, функціональних блоків) – перед створенням проекту продумайте систему іменування (ідентифікації та кодування). Продумана система імен робить програму простіше для читання і налагодження.
Для кожного типу об’єкту автоматизації може використовуватися свої підходи. Крім особливостей об’єкту можуть бути вироблені корпоративні підходи (однакові у всіх програмістів однієї фірми). Комусь подобається угорська нотація, комусь система KKS, комусь своя власна (а чому б ні?). Головне – системність найменування!
Мені ближче робити наскрізне найменування відповідно до функціональних позначень на схемах автоматизації. Що значить наскрізне? Це значить, що берете Ви схему автоматизації і бачите там датчик “TT1a”, що підключається до ПЛК. Як ви думаєте, як в мене змінна називається? Вгадали – “TT1a”. Ви скажете, “а якщо там додаткові перетворення йдуть з цілого в дійсні, а ще є фільтрація (а це обов’язково повинно бути для аналогових сигналів), там же ж не одна змінна?!” Так, але суфікси та префікси використовувати ніхто не забороняє (рекомендую ознайомитися з ISA 5.1), наприклад “TT1a_raw”. А Ви не здогадуєтесь яке ім’я я дам заданому значенню для цієї температури? Точно, “TT1a_SP”. Але на цьому наскрізність не закінчується, так само я дам назву тегу в SCADA, причому набирати мені буде ліньки, тому я просто скопіпащу/імпортую/злінкую (вибрати доступне). Тепер у мене у всіх програмах та ще й на схемах (можна і на принципові схеми ті самі дод. позначення ввести) ідентифікація змінних процесу однакова. Це не я видумав, перейняв традиції програмістів інтеграторів-цукровиків.
Важкі комунікації? Може прийшов час переглянути адресацію мережних змінних?
Якщо змінних у вас багато, а обмін скажімо зі СКАДОю важкий, то треба групувати змінні за адресами. Тобто розміщувати комунікаційні змінні в суміжних адресах. СКАДі простіше витягувати змінні групою, ніж по одній. Так, наприклад, якщо використовується Modbus, то зчитування 2-х числових змінних з адресами 1 та 200 займе більше часу ніж зчитування 50-ти змінних від 10 до 59. Чому? Так працює протокол Modbus і більшість протоколів промислових мереж.
5.Налагодження програми.
“Мені тут треба одну змінну змінити. Зупиняйте свої сталелитейні процеси. Я перевантажує ПЛК і будемо пробувати”
Думаю після таких слів, більше цього програміста на даному підприємстві не бачили.
Перш за все звикайте до думки, що у вас немає можливості зупиняти контролер. Принаймні при найменшому чиху в програмі. А отже НЕ НАЖИМАЙТЕ КНОПКУ СТОП НА ПАНЕЛІ ІНСТРУМЕНТІВ тільки тому, що треба змінити кусок кода. Ви працюєте з промисловими контролерами, відлагодження програми яких без зупинки ПЛК є однією з головних необхідностей! А погані звички СТОПати, залишаються надовго і це не дуже добре.
Крім того, перед зміною частини програми в працюючому ПЛК на виробництві, добре подумайте про можливі наслідки. А взагалі, звичайно краще всі зміни вносити при пусконаладці, ну по крайній мірі при досвідній експлуатації, саме для цього ці етапи і потрібні. Але ж це ідеали, які являються в більшій мірі виключенням аніж правилом.
Як перевірити роботу програми без об’єкту?
Для невеликих процесів користуйтеся таблицею або діаграмою залежності вихідних змінних від вхідних (характерно для дискретних процесів). Тобто створіть таблиці(діаграма) залежності стану виходів від входів та перевіряйте як працює ця залежність. Якщо є контури регулювання, для кожного контуру варто наносити збурення, змінювати завдання, змінювати налаштування і дивитися як ведуть себе виходи.
А для складних процесів можна використовувати програмну імітацію, але це вже тема для іншої статті, яку можливо я скоро напишу.
Олександр Пупена, викладач, Київ
Публікації по темі: Послання зеленим і недосвідченим #почтипрограмістам ПЛК від #читопрограмера-читовиклада. Ч.1