В недавнем проекте по автоматизации котельных в Оренбургской области — ПЛК управляет каскадом котлов, от двух до четырёх штук.
До этого программировал только каскады насосов с частотными преобразователями и алгоритм строился на анализе частоты и давления. Тут всё просто — запущенные частотники работают на одной частоте. Если дошли до максимума, а давления мало — подключаем ещё один. И наоборот, частота упала ниже заданной границы — отключаем.
Но в случае котлов анализируется один единственный параметр — создаваемая ими температура воды в котловом контуре. Как, зная эту температуру и уставку, определить сколько котлов должно работать?
Ответ — с помощью температурно-временных интегралов. Да, звучит не особенно увлекательно и лучше сходите в кино, но если приспичило узнать о каскадном управлении — вперед.
PS. Интеграл называется температурно-временным только условно. Описывать я буду математический алгоритм, который с успехом применяется и к каскаду насосов, опираясь на создаваемое ими давление.
PPS. Программный код функционального блока на языке ST прилагается. Халява!
Еще раз о задаче
Необходим алгоритм, который включает и отключает котлы для поддержания заданной температуры на общем выходе этих котлов. Из доступной информации — температура и уставка. Количество котлов не имеет значения. Обратной связи о мощностях котлов нет.
В оренбургском проекте ПЛК управляет еще и мощностью горелок по ПИДу, защищает котлы (помимо автоматики самого котла), анализирует сигналы работы и аварии, сбрасывает ошибки. Но всё это делает другой функциональный блок, и речь не о нём.
Изучение вопроса
Чтобы узнать как функционирует каскадный регулятор я (вы не поверите!) скачал инструкции на приборы каскадного управления котлами разных марок: Viessmann, Kromschroder, Siemens, Honeywell, Danfoss.
Большинство инструкций не порадовали. Некоторые составители под инструкцией сервисного уровня подразумевают тупую расшифровку пунктов меню и не описывают принципы работы. Еще оказалось, что «каскадом» в одних случаях называют несколько котлов, а в других — контуры ГВС и отопления.
Единственное, но полноценное, описание алгоритма каскадных переключений я нашел в инструкции на Siemens Synco RMK770. График в начале поста оттуда и его почти достаточно для понимания принципа. Инструкцию на русском читать не советую — переводил google translate. Каскад описывается в главе 6.3.6 «Switching boilers on and off», монструозно переведенную на русский как «Включенные и выключенные переключающие котлы» вместо простого «Включение и отключение котлов». У Сименса (да и остальных) нет денег на переводчика? Себя не предлагаю — английский чуть выше элементари.
Как это работает
Если присесть и порассуждать то покажется, что для решения задачи подойдёт двухпозиционный регулятор: упала температура ниже уставки — включаем дополнительный котел, поднялась выше уставки — отключаем. Плюс-минус гистерезис (нейтральная зона).
На практике же окажется, что котлы переключаются слишком часто, отключения происходят слишком быстро, а включения медленно, появляются ложные переключения при запуске долго стоявших котлов и температура скачет как блоха.
Шаг 1
Двухпозиционный регулятор
Следующим логичным поступком станет добавление задержек включения и отключения. Причем задержку включения желательно подольше.
Вроде дело пошло, но вдруг сталкиваемся с ситуацией когда температура плавно опустилась ниже границы включения всего на пол градуса, и падать дальше не собирается — всем видно, что включать ещё один котел не стоит. Всем, кроме контроллера — он делает, то что ему сказали — выжидает время и подключает дополнительный котел. В другой раз температура стремительно падает, и вот она уже ниже уставки на 10… на 20 градусов. Нужно срочно включать котел. Что делает контроллер? — ждет заданное время. И не надо на него ругаться.
Шаг 2
Вводим задержки. Тут-то мы и приходим к тому, что задержка времени должна зависеть от температуры. Суть температурно-временного интеграла как раз в этом. Графически-геометрически интеграл — это площадь под температурной кривой. Чем дальше температура от уставки, тем больше площадь и быстрее она растет.
Шаг 3
Задержки зависят от температуры
Вместо задержек по времени мы отсчитываем площадь. Зададим максимальные значения интеграла для включения и отключения. Если вычисленный интеграл (площадь) превысит их — функциональный блок запустит или остановит очередной котел. Базовый алгоритм готов!
Учтем ещё один нюанс — при «холодном» пуске (давно стоявшего и остывшего) дополнительного котла неизбежна просадка котловой температуры. Т. е. в первые несколько минут после пуска, когда котел не нагревает, а охлаждает, нельзя вычислять интеграл. Для этого введем паузу:
Программный код
Приступим к реализации. Не заморачиваемся с кодом блока интегрирования — берем готовый (Engineering > control > INTEGRATE) из библиотеки OSCAT Basic и добавляем ему функцию сброса.
FUNCTION_BLOCK INTEGRATE VAR_INPUT E : BOOL := TRUE; X : REAL; K : REAL := 1.0; RES : BOOL; END_VAR VAR_IN_OUT Y : REAL; END_VAR VAR X_last : REAL; init: BOOL; last: DWORD; tx: DWORD; END_VAR
tx := TIME_TO_DWORD(TIME());
IF NOT init THEN
init := TRUE;
X_last := X;
ELSIF E THEN
Y := (X + X_LAST) * 0.5E-3 * DWORD_TO_REAL(tx-last) * K + Y;
X_last := X;
END_IF;
IF RES THEN Y := 0; END_IF
last := tx;В основном блоке я учел следующие моменты:
- Алгоритм не выдает число необходимых для работы котлов. Вместо этого — триггерные булевы переменные PLUS и MINUS для включения или отключения одного котла.
- Интеграла не два — один на отключение и один на включение. Он единственный, просто считает в одну из двух сторон.
- Абсолютное значение котловой температуры и её уставки не нужны для вычисления интеграла. Используем только их разность (diff) и этим сократим число переменных.
- Есть множество внешних условий при которых котлы останавливаются. В этих случаях ФБ останавливается с помощью переменной stop.
- Когда запущены все доступные котлы интеграл вычисляется только в сторону отключения. Об этом событии сообщает переменная stopOn.
- И наоборот, когда штатно остановлены все котлы (или остался один, или два — зависит от внешнего кода управления котлами) вычисляется только интеграл включения. Инфа из переменной stopOff.
FUNCTION_BLOCK CASCADE
VAR_INPUT
diff :REAL; (*разность между уставкой и температурой*)
zone :REAL; (*величина нейтральной зоны. гистерезис*)
iON :WORD; (*величина интеграла вкл*)
iOFF :WORD; (*величина интеграла откл*)
delay :WORD; (*задержка после включения или отключения котла, мин*)
stop :BOOL; (*остановка ФБ*)
stopOn :BOOL; (*запущены все котлы. Перестаем считать интеграл на включение*)
stopOff :BOOL; (*остановлены все котлы. Перестаем считать интеграл на отключение*)
END_VAR
VAR_OUTPUT
leftTime :REAL; (*осталось минут*)
PLUS :BOOL; (*вкл котел*)
MINUS :BOOL; (*откл котел*)
ON :BOOL; (*идет отсчет до вкл*)
OFF :BOOL; (*идет отсчет до откл*)
END_VAR
VAR
INTEGR :INTEGRATE; (*ФБ интеграл*)
it :REAL; (*величина интеграла*)
trig :R_TRIG; (*триггер переключения*)
tick :TON := (PT:=T#1s); (*период вычисления интеграла — 1 секунда*)
timer :TP; (*таймер задержки (паузы)*)
init :BOOL := TRUE; (*первый запуск ФБ*)
END_VAR
tick (IN := NOT tick.Q); (*отстукиваем ритм*)
trig (CLK := leftTime<0); (*досчитали*)
timer (IN := PLUS OR init, PT := DWORD_TO_TIME(delay * 60000)); (*пауза при включении нового*)
init := FALSE;
IF tick.Q THEN
(*вычисляем интеграл*)
INTEGR( RES := timer.Q OR ABS(diff)< zone OR stop OR (stopOn AND diff>0) OR (stopOff AND diff<0) OR leftTime<0,
X := ABS(diff)-zone,
Y := it,
K := 1.0/60);
(*осталось времени в минутах*)
leftTime := (SEL(diff>0, iOFF, iON) - it) / MAX(INTEGR.X, 1);
END_IF
(*определяем куда идет отсчет если вообще идет*)
ON := NOT INTEGR.RES AND diff>0;
OFF := NOT INTEGR.RES AND diff<0;
(*включаем или отключаем*)
PLUS := trig.Q AND ON;
MINUS := trig.Q AND OFF;Вызов и взаимодействие с блоком управления группой котлов выглядит так:
integra(diff := Tsp-T10, stop := GR.off, stopOn := GR.ALL, stopOff := GR.NULL); GR(PLUS := integra.PLUS, MINUS := integra.MINUS);
Пример готовой программы
Накидал очень упрощенную программу по управлению четырьмя котлами. Количество задается только в одном месте, поэтому его легко изменить на любое. Но визуализация рассчитана на четыре или меньше.
PROGRAM PLC_PRG
VAR CONSTANT
num :BYTE:=4; (*общее число котлов*)
END_VAR
VAR
integra :CASCADE;
Tsp :REAL; (*температура на выходе котлов*)
T1 :REAL; (*уставка*)
i, j :INT;
main :BYTE:=1; (*номер основного котла*)
amount :BYTE:=0; (*необходимое число котлов*)
run :BYTE; (*число запущенных котлов*)
nonorm :BYTE; (*число котлов в нерабочем состоянии*)
boiler :ARRAY[0..num] OF BOOL; (*запуск котла*)
alarm :ARRAY[0..num] OF BOOL; (*авария котла исключеат его из работы*)
END_VAR (*Сбрасываем переменные для нового расчета*)
nonorm := 0;
run := 0;
(*Определяем сколько котлов в нерабочем состоянии*)
FOR i:=0 TO num DO
nonorm := nonorm + WHEN(alarm[i]);
END_FOR
(*Вычисляем интеграл*)
integra(diff := Tsp-T1,
stopOn := (amount=num-nonorm),
stopOff := (amount=0));
(*Определяем необходимое число котлов*)
amount := amount + WHEN(integra.PLUS) - WHEN(integra.MINUS);
(*Назначаем основной котел*)
WHILE alarm[main] AND nonorm < num DO main := NEXT(main, num); END_WHILE
(*Запускаем необходимое число котлов, остальные останавливаем*)
FOR i := main TO main+num-1 DO
j := SEL(i>num, i, i-num);
IF NOT alarm[j] AND run < amount
THEN boiler[j] := TRUE; run := run+1;
ELSE boiler[j] := FALSE;
END_IF
END_FOR Работа и интерфейс управления симулируется в визуализации. Котел выводится из работы кликом по нему, при этом загорается надпись «Авария».
Нейтральная зона — 2 °С. Пауза после запуска котла — 5 секунд. Интеграл отключения и включения задаются с клавиатуры. Вычисление интеграла можно остановить кнопкой «Стоп». Температура и её уставка меняются ползунками.
Недостатки и преимущества метода
− Не очень хорош при отключении дополнительных модулирующих котлов, работающих по ПИДу. Возможна ситуация работы большинства котлов на минимальной мощности. Решается дополнительными алгоритмами, например с помощью «баланса мощности».
+ Не требует много информации. Достаточно котловой температуры и дискретного сигнала включения котла.
+ Универсален. Работает с котлами с любыми видами горелок. Единственный адекватный вариант для одно- и двухступенчатых горелок.
Может показаться, что алгоритм подходит только для работы с котлами одинаковой мощности — интегралы отключения и включения ведь одни на всех. Но всё наоборот — метод интегралов хорош для таких случаев, т.к. работает не с мощностями, а с их следствием — температурой. Чем выше мощность котла, тем бóльшую температуру он создаст, и наоборот:
S — заданный интеграл отключения.
T1 и T2 — созданные мощным и слабым котлом температуры в котловом контуре.
t1 и t2 — вычисленные интервалы времени, через которые произойдет отключение.
Мощный котел создает большую температуру:
T1 > T2
В упрощенном варианте интеграл — это произведение:
S = (T1-SP) * t1 = (T2-SP) * t2
Поэтому t1 < t2, т. е. мощный котел отключится быстрее.
t1 и t2 — интервалы включения.
Мощный котел поддерживает большую температуру:
T1 > T2
В упрощенном варианте интеграл — это произведение:
S = (SP-T1) * t1 = (SP-T2) * t2
Поэтому t1 > t2 и включение мощного котла произойдет позже.
Сравнение с другими методами
Кроме интеграла есть ещё один вариант работы каскада — по «балансу мощности». В самом начале я писал про каскад насосов с ПЧ. Суть та же, только в случае котлов анализируется и регулируется их текущая мощность. «Баланс мощности» прост для понимания и программирования, более точен в идеальных условиях, хорошо справляется с отключением котлов. Но неуниверсален; посмотрите на картинку с примером алгоритма:
Пример с четырьмя модулирующими котлами, которые последовательно включаются и отключаются.
Базовая ступень первого котла — 30% номинальной мощности. С увеличением расхода тепла каждый котел увеличивает мощность до 100 кВт(100%) перед тем, как включится следующий. Четыре котла вместе выдают максимум 400 кВт. Граница отключения по мощности установлена на 60%.
Он использует много информации. Во-первых нам необходимо плавно управлять мощностью, во-вторых мы мы должны знать её текущее значение. Причем не относительное значение в процентах, а реальное абсолютное в киловаттах. Почему? Котлы могут быть разной мощности.
Исходя из этого нам подходят только модулирующие котлы с внешним заданием мощности и обратной связью по цифровому или аналоговому интерфейсу. При этом нам важно знать максимальную мощность котла и точность соответствия реальной и передаваемой по интерфейсу мощности.
На практике
Запущено пока на двух котельных. Вкупе с адекватным регулированием мощности котлов по ПИДу четко держит установленное значение котловой температуры и экономит до 27% газа по сравнению с переключениями вручную.
Об операторах подумали и добавили обратный отсчет (leftTime) до запуска или останова котла в условных минутах. Условных, потому что показывают сколько времени останется если температура замрет и не будет меняться. Чтобы понять в какую сторону считается интеграл введены переменные ON и OFF. Кусочки интерфейса панели с обратным отсчетом:
Экран панели с настройкой котловых параметров:
Работает отлично. Практика показала экономию газа на производство и отпуск тепловой энергии. В зависимости от мощности котельной, от состоянии оборудования и потерь на теплотрассах процент составил от 7 до 27 процентов. Так же повысилось качество подачи тепловой энергии потребителю.
Истчоник: https://www.asutp-volgograd.com/blog/cascade.html
🔗 Каскадное управление котлами на ПЛК. Температурно-временные интегралы