Привет, Хабр! Это мой первый опыт написания здесь, если что, уж сильно не пинайте). Сам я программист самоучка. Новый язык Structured Text и среду разработки Codesys разбирал по мануалу и стандарту МЭК-61131-3. В статье будет рассматриваться легкий самописный фреймворк для быстрой сборки насосной станции реализованной на ПЛК 110-32м2 фирмы ОВЕН.
Посчастливилось мне на работе из рядового слесаря по КИПиА перевестись в инженеры-программисты в состав группы комплексной автоматизации, в которой кроме меня состоял только начальник этой самой группы.
Большую часть парка промышленного оборудования на предприятии фирмы ОВЕН (это различные датчики температуры и давления, ТРМы, блоки питания, ПЛК (110) аналоговые и дискретные модули ввода-вывода (110), сенсорные панели (СП307 и СП310), и сетевые шлюзы для доступа к сервису OwenCloud, частотные преобразователи(ПЧВ). Основной контроллер который мы используем - ПЛК 110-60 (для автоматизации котельных) и ПЛК 110-32 (для автоматизации ЦТП). Разработка программ для этих ПЛК происходит в Codesys 2.3. Поскольку Программистских академий мы не кончали, а курсов по промышленному программированию на языках МЭК никто отродясь не видывал, пришлось с нуля осваивать новую стезю. О первый мой рабочий код.. я буду плакать по тебе кровавыми слезами. Надеюсь сейчас мой код выглядит получше, чем тогда..
Случилось так что на ЦТП вышла из строя, по сроку годности, одна импортная насосная станция. И светлым умам нашего предприятия пришла идея собрать свою, на ПЛК. набросали хардкодингом-быдлокодингом одну программу.. Через полгода скачком напряжения убило насосную станцию на другом объекте.. Снова ПЛК и снова захардкодили программу. Местному руководству так понравилась идея собственной разработки насосной станции, что при ближайшей реконструкции объекта заменяла старую станцию - собственной разработкой ведь экономия средств то какая. Но конфигурация станций всегда разная: тут два насоса, там пять; на этом объекте надо чтобы насосы поочередно переключались, на следующем чтобы работали в каскадном режиме. Разные запросы были. И тут-то я созрел - нужен какой-нибудь фреймворк, чтобы можно было быстро собирать эти станции различной конфигурации.
Для работы нам понадобятся:
Codesys 2.3
Таргет-файл для ПЛК 110-32м2
Подключить к проекту библиотеку Util.lib
Создаем новый проект. выбираем конфигурацию нашего ПЛК.
![](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/45d/f68/88f/45df6888fd163a5124ed0804d7fec541.png)
Главная программа будет на языке CFC. Так наглядней и проще для тех кто не знаком с языками программирования.
![](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/08d/0f5/061/08d0f50619a8c2cd4238f80ce6c05224.png)
По ТЗ у нас на ПЛК приходят сигналы:
Discrete inputs:
Защита по сухому ходу (низкое давление на входе насоса).
Защита по превышению давления на выходе насоса.
Внешняя авария (авария частотного преобразователя).
Статус частотного преобразователя "Работа" (RUN).
Discrete outputs:
Запустить частотный преобразователь.
Квитировать/сбросить аварию частотного преобразователя.
Импортируем в программу нашу виртуальную модель ПЛК, структуру для ее работы и методы.
![Сложим наши свежие импорты в папочку чтоб не растерять. Сложим наши свежие импорты в папочку чтоб не растерять.](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/022/c4f/06b/022c4f06be058f9ddf5653e09e986148.png)
![Структуры необходимые для работы блока ПЛК110 Структуры необходимые для работы блока ПЛК110](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/248/ff9/2ab/248ff92ab142b63e6cba60e6ebae39de.png)
![Вид ПЛК110-32 на языке CFC Вид ПЛК110-32 на языке CFC](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/f5e/29f/cf0/f5e29fcf0617ddc5876cbda9c13952c8.png)
Теперь к этому блоку мы можем как на электрической схеме подключить наши сигналы к дискретным входам. Допустим у нас станция будет из трех насосов. Подключаем наши сигналы виртуальными проводочками. Для работы с входами ПЛК мы их упаковываем в inputs_plc имеющей тип данных classPLC32m2StatusInputs
![inputs_plc присваиваем соответствующую структуры данных. inputs_plc присваиваем соответствующую структуры данных.](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/fbf/55c/4d8/fbf55c4d88717b2be02fc84b58caa483.png)
Для работы с этими данными у нас имеются методы: get_fdi и get_di
get_fdi(number_fdi: int, inputs_plc: classPLC32m2StatusInputs) -> bool;
get_di(input_number: int, inputs_plc: classPLC32m2StatusInputs) -> bool;
Подключим наши выходные сигналы к выходам. Для управления выходами добавляем вспомогательный блок get_status_outputs, он принимает на соответсвующий вход булевое состояние и упаковывает все в тип данных classPLC32m2StatusOutputs, с которым работает блок main_plc.
![К входам блока outputs мы будем подключать непосредственно результат логики работы нашего контроллера. К входам блока outputs мы будем подключать непосредственно результат логики работы нашего контроллера.](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/93f/ea0/8f3/93fea08f3993bc3cde6ac9edf7aca42a.png)
Эти блоки для работы с ПЛК110-32 универсальны и могут использоваться в любых других проектах под этот контроллер. Визуально все в одном месте и при онлайн отладке удобно наблюдать за состоянием входов-выходов ПЛК.
Для получения давления на входе и выходе насоса используются датчики 4-20мА. Сигнал в контроллер приходит через модуль аналоговых входов МВ110-8а. Импортируем модель этого модуля в проект.
![](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/7b3/6bb/854/7b36bb8540f4cf067de12165ecea5bff.png)
В PLC_PRG добавляем наш блок аналоговых входов. analog_inputs упаковываются в соответствующий класс classInfoAnalogInputModule
![](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/907/eb1/ebb/907eb1ebb4a7df69afc36edfff9dd854.png)
Для работы необходим вспомогательный блок с настройками SetChannelsAnalogInputsModule. Этот блок содержит конфигурацию входов модуля. По умолчанию настройки всех каналов (0-100, 4-20мА).
![](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/6ba/4f3/df3/6ba4f3df325ad5710777f85b5b4bb711.png)
Конфигурация регистров:
![](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/299/ca6/72a/299ca672aa91c676eb4759756d792140.png)
Не забываем проставить адреса регистров которые мы будем считывать (см инструкцию Приложение В, таблица В.4 - регистры протокола modbus.
![](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/0f1/887/41c/0f188741cdebcf46458ebd5b043c66f9.png)
![](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/b37/947/818/b37947818b876fe6d5444b456f8cfd6e.png)
Сконфигурировав канал аналогово модуля можем импортировать блок для датчика 4-20мА.
![](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/cc6/8d0/143/cc68d0143878103933c0a336155d7eeb.png)
Метод get_channel_current_value(number_channel: int, analog_inputs: classInfoAnalogInputModule)
позволяет получить значение с АЦП соответствующего канала.
И собрав нехитрую конструкцию, получить информацию о давлении которое приходит на датчик.
![Блок с параметрами датчика нужен для соответствующего масштабирования согласно параметрам реального датчика. Блок с параметрами датчика нужен для соответствующего масштабирования согласно параметрам реального датчика.](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/c91/186/3b4/c911863b4734ced768ad0391c54e3721.png)
Насосом у нас управляет частотный преобразователь. Импортируем содержимое папки invertor_drive.
![Функциональный блок частотника и его методы. Функциональный блок частотника и его методы.](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/054/f79/cf2/054f79cf279d62351d5897fcdd2653fd.png)
Добавляем блок в проект, подключаем данные со входов ПЛК, используя метод get_di. ain_value (float) - это аналоговый вход частотника, подключаем туда наше давление, которое мы собираемся контролировать. set_point (float) - это уставка по давлению.
![](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/b74/10b/622/b7410b6222f65f05c9eac6b277778c0a.png)
start_id (bool) - сигнал на старт частотного преобразователя; auto_id (bool) - когда True, то работает ПИД-регулятор, когда False - режим manual; manual_hz - значение выходной частоты в режиме manual (Hz) ;active_id (bool) - флаг готовности к работе насоса; alarm_on (bool) - это флаг аварийного состояния, когда он активен, частотник не стартует. P, I, D - это коэффициенты регулятора, по умолчанию (2, 10, 0). min, max _range - это нижний и верхние пределы значения на выходе регулятора. aout_value - сюда мы подключим частоту на выходе регулятора и она на выходе автоматически масштабируется в значение тока 4-20мА.
Для регулятора импортируем блок распаковки настроек регулятора.
![](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/fde/8b2/867/fde8b2867d019772ef615e6458c59bed.png)
PID регулятор возьмем из библиотеки Util.lib которая идет в комплекте с Codesys (через менеджер библиотек добавляем в проект).
![Частотник готов к работе и теперь им можно управлять. Частотник готов к работе и теперь им можно управлять.](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/67f/4de/a0d/67f4dea0da3c801cce0ecf997ef86dfc.png)
Вывод частоты преобразовывается в токовый сигнал отправляется на модуль аналогового вывода.
![Реализация модуля аналогового вывода. Реализация модуля аналогового вывода.](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/faf/51d/33e/faf51d33e4649ec2fd2961e9640a4748.png)
Для работы насосной станции предусмотрены 3 режима. Single - одиночный режим работы, когда выбираем насос и он всегда работает; Cycle - режим циклического переключения насосов. Задаем время переключения и активные насосы по очереди работают. Cascade - режим каскадного включения насосов, при недостатке давления на выходе. Чтобы насос участвовал в работе его флаг active должен быть True
![Блоки режимов работы станции. Блоки режимов работы станции.](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/486/c5a/3b9/486c5a3b9d977c11c4a3fdd58159ea9f.png)
Каждый блок может управлять до 8-ми насосов. Притом для цикла и каскада необходимо более 2х активных насосов.
Рулит этими режимами - селектор.
![](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/f91/ff8/b30/f91ff8b30b2f3d5c302c4cd5dac9d554.png)
В селекторе предусмотрен режим обработки ошибок, например таких как: не выбран режим работы или не задан опорный насос и пр.
Обработкой всех ошибок занимается alarm_manager. Для аварий частотного преобразователя сделан свой блок. Сюда собираются все аварийные флаги и в случае нештатной ситуации генерируется код аварии и сообщение.
![Менеджер возвращает нам флаг аварии, код аварии и расшифровку в виде информационного сообщения. Менеджер возвращает нам флаг аварии, код аварии и расшифровку в виде информационного сообщения.](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/4f2/22e/c84/4f222ec840a38ecb54e9d49d8dd07939.png)
Не забываем вывести наши выходные сигналы на выходы ПЛК.
![Конфигурируем выходы ПЛК. Конфигурируем выходы ПЛК.](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/6be/569/cec/6be569cecc8a3be5a77bcef4dd028164.png)
Можно запустить эмуляцию и проверить как работают режимы.
Для работы функциональных блоков в фреймворке реализованы functions project. Простенькие функции для работы с массивами, функция масштабирования диапазона и функция для задания времени.
![Общие функции фреймворка. Общие функции фреймворка.](https://webcf.waybackmachine.org/web/20220930091244/https://habrastorage.org/getpro/habr/upload_files/e91/3d2/24b/e913d224b7b13c3160caccd3ec6335af.png)
Вот в принципе и всё. Я надеюсь что основная мысль понятна. С помощью фреймворка для контроллера буквально за 15-20 минут можно реализовать программу для нескольких групп насосов работающих независимо друг от друга. Останется дело за малым, сконфигурировать вывод параметров на HMI. Но об этом в следующий раз.