PDA

Просмотр полной версии : Проект в Codesys



Atomeg
06.05.2012, 18:13
Нужен человек, который может помочь с доработкой программы в Codesys. Работа не сложная, язык ST (паскалеподобный).
С меня полное объяснение того, что уже написано и того, что нужно доработать.
Не безвозмездно.
Подробности в лс.

Atomeg
08.05.2012, 20:40
Итак, программа осуществляет управление компрессорным холодильником. Управление основано на двухпозиционном способе регулирования. То есть если температура выше какого то Xmax - то компрессор нужно включить, а если температура ниже какого то Xmin то компрессор нужно отключить. Но ввиду того, что такой алгоритм обладает недостатками в виде инерционности самого объекта (после достижения верхней/нижней границы и после вкл/откл компрессора температура какое то время всё равно начинает либо ползти вверх, либо вниз за пределы регулирования [Xmin;Xmax]). Поэтому разрабатывается адаптивный двухпозиционный алгоритм, который бы основывался на ШИМ-импульсах переменной длительности.
Итак, получилось добиться адаптации. Алгоритм описан весь в файле Алгоритм.doc.
Теперь необходимо каким то образом прикрутить к программе ограничение на энергоэффективность. Математическое описание дано в файле Алгоритм.doc-в самом конце. Именно проблема с тем, как это написать в Codesys.
Сам алгоритм вот:

FUNCTION_BLOCK AR3
VAR_INPUT
Xmax, X, Xmin: REAL; {Xmax,Xmin диапазон регулирования управляемой величины, Х - текущая температура}
Revers: BOOL := FALSE;
END_VAR
VAR_OUTPUT
U: BOOL; {Выход блока-либо True(1) либо False (0)}
END_VAR
VAR
onstart: BOOL := TRUE; {лог. переменная, кот. отвечает за запуск программы}
u0, u1: BOOL; {лог.переменная, кот. соответствует выкл и вкл компрессора соответственно}
U_: BOOL; {значение управл.воздействия в предыдущий момент времени, либо True (вкл-1) либо False (выкл-0)}
X_: REAL; {значение темп. в предыдущий момент времени}
Xchange: BOOL; {переменная, показывающая есть ли изменение температуры по сравнению с температурой в предыдущий момент времени}
tonn, toff: TIME; {время, прошедшее с момента начала последнего импульса; время, прошедшее с момента прекращения последнего импульса!!! по сути ведут отсчёт-сколько идёт импульс 1 или импульс 0}
tstop, tstart: TIME; {момент времени прекращения последнего импульса;момент времени начала последнего импульса}
tstop_, tstart_: TIME; {момент времени прекращения предпоследнего импульса;момент времени начала предпоследнего импульса}
timp, trelax: TIME; {адаптируемая продолжительность импульса;адаптируемый интервал времени между импульсами;}
X_max, X_min: REAL; {максимальное значение X в последнем периоде регулирования; минимальное значение X в последнем периоде регулирования}
X_01, X_10: REAL; {значение X в момент t01;значение X в момент t10)
t_max, t_min: TIME; {время, при котором зафиксировано X_max, X_min}
t01, t10: TIME; {момент времени последнего изменения управляющего воздействия с u0 на u1,т.е. с 0 на 1; а t10 - с u1 на u0}
ChangeU: INT; {количество прошедших полупериодов изменения управляющего воздействия, т.е. сколько раз сменилось с 1 на 0, или с 0 на 1 и так далее.}
END_VAR

{Переприсваивание управляющих воздействий}
u0:=Revers; {u0=False или u0=0}
u1:=NOT Revers; {u1=True или u1=1}

{Присваивание начальных значений при пуске программы}
IF onstart THEN {если true то}
U:=u0; {текущий выход блока это False или же 0}
U_:=U; {предыдущее значение управл.воздействия присваивается текущему}
X_:=X; {предыдущ. значение температуры -> текущему значению}
Xchange:=FALSE; {изменения температуры нет}
tstart:=TIME(); {присваиваем текущему времени}
tstop:=tstart;
tonn:=t#0s; {обнуляем наши счётчики длительности импульсов 1 и 0}
toff:=t#0s;
timp:=t#24h;
trelax:=T#24h;
X_max:=Xmin; {см.выше в описании переменных}
X_min:=Xmax;
X_10:=Xmin;
X_01:=Xmax;
t_max:=TIME();
t_min:=t_max;
t01:= TIME();
t10:=t01;
ChangeU:=0;
END_IF

{Рабочий режим, всё согласно алгоритму!}
IF X<Xmin THEN U:=u0; tstop:=TIME(); toff:=t#0s; ELSE {Если тек.значение темп < нижней границы диапазона то компрессор надо выкл - U:=u0}
IF X>Xmax THEN U:=u1; tstart:=TIME(); tonn:=t#0s; ELSE {Если тек.значение темп > высшей границы диапазона то компрессор надо вкл - U:=u1}
IF (U=u1) AND ((X>X_01) OR NOT Xchange) THEN tstart:=TIME();
END_IF;
IF (U=u0) AND ((X<X_10) OR NOT Xchange) THEN tstop:=TIME();
END_IF;
IF tonn>timp THEN U:=u0; tstop:=TIME(); tonn:=t#0s; {Если длительность импульса 1 > адаптируемой длительности импульса 1 то выкл компрессор и т.д.}
END_IF
IF toff>trelax THEN U:=u1; tstart:=TIME(); toff:=t#0s; {Если длительность импульса 0 > адаптируемой длительности импульса 0 то вкл компрессор и т.д.}
END_IF
IF U=u1 THEN tonn:=TIME()-tstart; {Если компрессор вкл то считаем длительность импульса 1 }
END_IF;
IF U=u0 THEN toff:=TIME()-tstop; {Если компрессор выкл то считаем длительность импульса 0 }
END_IF;
END_IF;
END_IF;

{Адаптация, всё согласно алгоритму!}
IF ChangeU>=2 THEN
IF (U=u0) AND (U_=u1) THEN
trelax:=t01-tstop_;
trelax:=REAL_TO_TIME( TIME_TO_REAL(trelax) * (Xmax-X) / (X_max-X_10) );
END_IF;
IF (U=u1) AND (U_=u0) THEN
timp:=t10-tstart_;
timp:=REAL_TO_TIME( TIME_TO_REAL(timp) * (X-Xmin) / (X_01-X_min) );
END_IF;
END_IF;

{Нахождение вспомогательных значений!эти переменные нужны при адаптации. вычисляются они в начале каждого нового периода, вернее, при каждой смене управляющего воздействия (U_ - предыдущий управляющий сигнал, U - текущий). по факту X_max, X_min - величина выбега из заданного диапазона}
IF (U=u0) AND (U_=u1) THEN X_max:=Xmin; t_max:=TIME(); t10:=TIME(); X_10:=X; Xchange:=FALSE;
END_IF;
IF (U=u1) AND (U_=u0) THEN X_min:=Xmax; t_min:=TIME(); t01:=TIME(); X_01:=X; Xchange:=FALSE;
END_IF;
IF X>=X_max THEN X_max:=X; t_max:=TIME();
END_IF;
IF X<=X_min THEN X_min:=X; t_min:=TIME();
END_IF;

IF U<>U_ THEN ChangeU:=ChangeU+1; {Если текущее значение управл. воздействия не равно предыдущему то инкрементируем}
END_IF;
U_:=U;
IF X<>X_ THEN Xchange:=TRUE; {Если текущее значение температуры не равно предыдущему то true}
END_IF;
X_:=X;
tstop_:=tstop;
tstart_:=tstart;
onstart:=FALSE;

bgn62
09.05.2012, 07:35
Нужен человек, который может помочь с доработкой программы в Codesys. Работа не сложная, язык ST (паскалеподобный).
С меня полное объяснение того, что уже написано и того, что нужно доработать.
Не безвозмездно.
Подробности в лс.
это реальная задача по автоматизации обьекта? или чисто теоретическая разработка?

Atomeg
09.05.2012, 09:06
это реальная задача по автоматизации обьекта? или чисто теоретическая разработка?
Реальная задача, которая основывается на мат. аппарате. Алгоритм, который выше, работает на реальном объекте(холодильнике) и действительно улучшает качество регулирования.

bgn62
09.05.2012, 09:34
подобные алгоритмы использовались в системе автоматики увлажнеия смеси для производства силикатного кирпича, еще 80-х в СССР. Качество кирпича заметно повышалось.

Atomeg
09.05.2012, 13:01
подобные алгоритмы использовались в системе автоматики увлажнеия смеси для производства силикатного кирпича, еще 80-х в СССР. Качество кирпича заметно повышалось.
Ну то производство кирпича, а это холодильник и температура... :)

ASo
09.05.2012, 20:02
Atomeg, есть 2 вопроса:
1. А что, у примененного компрессора нет технологических ограничений на макс. число пусков в ед. времени, на минимальный интервал останова перед повторным пуском и т.п.? Или есть, но в вашей циклограмме они не существенны.
2. Учитывая вашу модель аппроксимации 1-го порядка, фактически Вы решили задачу "максимальное время непрерывной работы компрессора с максимальным периодом повторных включений". Это автоматически даст максимальную энергоэффективность, при принятой линейности поступления тепла. Подсчитывать ничего не надо.
3. Это не ШИМ регулирование.