Привет, Хабр! Это мой первый опыт написания здесь, если что, уж сильно не пинайте). Сам я программист самоучка. Новый язык 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
Создаем новый проект. выбираем конфигурацию нашего ПЛК.

Главная программа будет на языке CFC. Так наглядней и проще для тех кто не знаком с языками программирования.

По ТЗ у нас на ПЛК приходят сигналы:
Discrete inputs:
Защита по сухому ходу (низкое давление на входе насоса).
Защита по превышению давления на выходе насоса.
Внешняя авария (авария частотного преобразователя).
Статус частотного преобразователя "Работа" (RUN).
Discrete outputs:
Запустить частотный преобразователь.
Квитировать/сбросить аварию частотного преобразователя.
Импортируем в программу нашу виртуальную модель ПЛК, структуру для ее работы и методы.



Теперь к этому блоку мы можем как на электрической схеме подключить наши сигналы к дискретным входам. Допустим у нас станция будет из трех насосов. Подключаем наши сигналы виртуальными проводочками. Для работы с входами ПЛК мы их упаковываем в inputs_plc имеющей тип данных classPLC32m2StatusInputs

Для работы с этими данными у нас имеются методы: 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.

Эти блоки для работы с ПЛК110-32 универсальны и могут использоваться в любых других проектах под этот контроллер. Визуально все в одном месте и при онлайн отладке удобно наблюдать за состоянием входов-выходов ПЛК.
Для получения давления на входе и выходе насоса используются датчики 4-20мА. Сигнал в контроллер приходит через модуль аналоговых входов МВ110-8а. Импортируем модель этого модуля в проект.

В PLC_PRG добавляем наш блок аналоговых входов. analog_inputs упаковываются в соответствующий класс classInfoAnalogInputModule

Для работы необходим вспомогательный блок с настройками SetChannelsAnalogInputsModule. Этот блок содержит конфигурацию входов модуля. По умолчанию настройки всех каналов (0-100, 4-20мА).

Конфигурация регистров:

Не забываем проставить адреса регистров которые мы будем считывать (см инструкцию Приложение В, таблица В.4 - регистры протокола modbus.


Сконфигурировав канал аналогово модуля можем импортировать блок для датчика 4-20мА.

Метод get_channel_current_value(number_channel: int, analog_inputs: classInfoAnalogInputModule)
позволяет получить значение с АЦП соответствующего канала.
И собрав нехитрую конструкцию, получить информацию о давлении которое приходит на датчик.

Насосом у нас управляет частотный преобразователь. Импортируем содержимое папки invertor_drive.

Добавляем блок в проект, подключаем данные со входов ПЛК, используя метод get_di. ain_value (float) - это аналоговый вход частотника, подключаем туда наше давление, которое мы собираемся контролировать. set_point (float) - это уставка по давлению.

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мА.
Для регулятора импортируем блок распаковки настроек регулятора.

PID регулятор возьмем из библиотеки Util.lib которая идет в комплекте с Codesys (через менеджер библиотек добавляем в проект).

Вывод частоты преобразовывается в токовый сигнал отправляется на модуль аналогового вывода.

Для работы насосной станции предусмотрены 3 режима. Single - одиночный режим работы, когда выбираем насос и он всегда работает; Cycle - режим циклического переключения насосов. Задаем время переключения и активные насосы по очереди работают. Cascade - режим каскадного включения насосов, при недостатке давления на выходе. Чтобы насос участвовал в работе его флаг active должен быть True

Каждый блок может управлять до 8-ми насосов. Притом для цикла и каскада необходимо более 2х активных насосов.
Рулит этими режимами - селектор.

В селекторе предусмотрен режим обработки ошибок, например таких как: не выбран режим работы или не задан опорный насос и пр.
Обработкой всех ошибок занимается alarm_manager. Для аварий частотного преобразователя сделан свой блок. Сюда собираются все аварийные флаги и в случае нештатной ситуации генерируется код аварии и сообщение.

Не забываем вывести наши выходные сигналы на выходы ПЛК.

Можно запустить эмуляцию и проверить как работают режимы.
Для работы функциональных блоков в фреймворке реализованы functions project. Простенькие функции для работы с массивами, функция масштабирования диапазона и функция для задания времени.

Вот в принципе и всё. Я надеюсь что основная мысль понятна. С помощью фреймворка для контроллера буквально за 15-20 минут можно реализовать программу для нескольких групп насосов работающих независимо друг от друга. Останется дело за малым, сконфигурировать вывод параметров на HMI. Но об этом в следующий раз.