Вложений: 1
3-х ПОЗИЦИОННЫЙ РЕГУЛЯТОР
Добрый день, уважаемые форумчане.
Много было тем про регуляторы и управление электроприводами клапанов по сигналу "Больше", "Стоп" и "Меньше", но к моему большому сожалению ни один из них не оправдал моих ожиданий и работали они не очень корректно, возможно потому, что применялись не на контроллерах ОВЕН а на контроллерах BECKHOFF, вот и пришлось мне написать небольшую программку "прокладку", как тут все называют для PID регулятора из библиотеки UTIL. Буду рад комментариям и замечаниям. Не получилось у меня отредактировать код, так чтобы он был наглядным, поэтому приложил файл с программой.
FUNCTION_BLOCK VALVE_3_POS
VAR
RANGE: REAL; (*ДИАПАЗОН ПИД РЕГУЛЯТОРА*)
PERIOD: TIME; (*ПЕРИОД ИМПУЛЬСОВ*)
TIME_PULSE: TIME; (*ВРЕМЯ ИМПУЛЬСА*)
TIME_PULSE_R: REAL;
TIME_PAUSE: TIME; (*ВРЕМЯ ПАУЗЫ*)
TIME_PAUSE_R: REAL;
TMR_MAX_HIGHT: TP; (*ТАЙМЕР ВЫДАЧИ ИМПУЛЬСА ПРИ ПИД > 0*)
TMR_MIN_HIGHT: TP; (*ТАЙМЕР ВЫДАЧИ ИМПУЛЬСА ПРИ ПИД < 0*)
TMR_MAX_LOW: TP; (*ТАЙМЕР ВЫДАЧИ ПАУЗЫ ИМПУЛЬСА ПРИ ПИД > 0*)
TMR_MIN_LOW: TP; (*ТАЙМЕР ВЫДАЧИ ПАУЗЫ ИМПУЛЬСА ПРИ ПИД < 0*)
PERIOD_R: REAL;
MIN_TIME_PULSE_R: REAL;
MIN_TIME_PULSE:TIME; (*МИНИМАЛЬНОЕ ВРЕМЯ ИМПУЛЬСА*)
F_TRIG_MAX:F_TRIG; (*ТРИГГЕР ЗАПУСКА ТАЙМЕРА ПАУЗЫ ПРИ ПИД > 0*)
F_TRIG_MIN:F_TRIG; (*ТРИГГЕР ЗАПУСКА ТАЙМЕРА ПАУЗЫ ПРИ ПИД < 0*)
END_VAR
VAR_INPUT
IN_VAL: REAL; (*ВЫХОД ПИД*)
IN_VAL_MIN: REAL := -100; (*МИНИМАЛЬНОЕ ЗНАЧЕНИЕ ПИД НА ВЫХОДЕ ЛУЧШЕ ЗАДАТЬ -15*)
IN_VAL_MAX: REAL := 100; (*МАКСИМАЛЬНОЕ ЗНАЧЕНИЕ ПИД НА ВЫХОДЕ ЛУЧШЕ ЗАДАТЬ 15*)
FULL_MOTION_TIME: REAL := 120; (*ВРЕМЯ ХОДА ПРИВОДА ПРИМЕР: 120*)
DEAD_ZONE: REAL := 0.1; (*ЗОНА НЕЧУВСТВИТЕЛЬНОСТИ ПРИМЕР: 0.1*)
AUTO: BOOL := TRUE; (*АВТОМАТИЧЕСКИЙ РЕЖИМ РАБОТЫ ЕСЛИ TRUE и РУЧНОЙ РЕЖИМ РАБОТЫ ЕСЛИ FALSE*)
OPENED: BOOL := FALSE; (*ОТКРЫТИЕ*)
CLOSED: BOOL := FALSE; (*ЗАКРЫТИЕ*)
END_VAR
VAR_OUTPUT
MORE: BOOL; (*БОЛЬШЕ*)
LESS: BOOL; (*МЕНЬШЕ*)
END_VAR
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\НАЧ АЛО\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*)
(*АВТОМАТИЧЕСКИЙ РЕЖИМ РАБОТЫ*)
IF AUTO THEN
RANGE := IN_VAL_MAX - IN_VAL_MIN; (*ОТПРЕДЕЛЕНИЕ ДИАПАЗОНА*)
MIN_TIME_PULSE_R := ( FULL_MOTION_TIME * 0.005 )*1000; (*ОПРЕДЕЛЕНИЕ МИНИМАЛЬНОЙ ДЛИТ. ИМПУЛЬСА*)
MIN_TIME_PULSE := REAL_TO_TIME( MIN_TIME_PULSE_R ); (*ПРЕОБРАЗОВАНИЕ ТИПОВ*)
PERIOD_R := ( FULL_MOTION_TIME / 20 ); (*ОПРЕДЕЛЕНИЕ ПЕРИОДА ИМПУЛЬСОВ*)
PERIOD := REAL_TO_TIME( PERIOD_R ) * 1000; (*ПРЕОБРАЗОВАНИЕ ТИПОВ*)
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*)
(*ВЫДАЧА ИМПУЛЬСА ПРИ ПОЛОЖИТЕЛЬНОМ ЗНАЧЕНИИ НА ВЫХОДЕ ПИД*)
IF (IN_VAL_MIN <0 AND IN_VAL_MAX >0) AND IN_VAL > (0 + DEAD_ZONE) THEN
LESS := FALSE; (*ОБНУЛЕНИЕ СИГНАЛА "МЕНЬШЕ" ЕСЛИ ОСТАЛСЯ АКТИВИРОВАНЫМ*)
TMR_MIN_LOW (IN:= FALSE, PT := TIME_PAUSE); (*ОБНУЛЕНИЕ ТАЙМЕРА ПАУЗЫ*)
TIME_PULSE_R := ( ( IN_VAL * PERIOD_R) / (RANGE / 2) )* 1000; (*РАСЧЕТ ТЕК ВРЕМЕНИ ИМПУЛЬСА*)
TIME_PAUSE_R := (PERIOD_R*1000 - TIME_PULSE_R); (*РАСЧЕТ ТЕКУЩЕГО ВРЕМЕНИ ПАУЗЫ*)
TIME_PULSE := REAL_TO_TIME ( TIME_PULSE_R );
TIME_PAUSE := REAL_TO_TIME ( TIME_PAUSE_R );
IF TIME_PULSE > MIN_TIME_PULSE THEN (*СРАВНЕНЕНИЕ МИН ВРЕМЕНИ ИМПУЛЬСА И РАСЧ ТЕКУЩЕГО*)
TMR_MAX_HIGHT (IN:= TRUE AND NOT TMR_MAX_LOW.Q, PT := TIME_PULSE); (*ЗАПУСК ТАЙМЕРА*)
END_IF
F_TRIG_MAX (CLK := TMR_MAX_HIGHT.Q); (*ТРИГГЕР ЗАУСКА ТАЙМЕРА ПАУЗЫ ПРИ*)
TMR_MAX_LOW (IN:= F_TRIG_MAX.Q, PT := TIME_PAUSE); (*ЗАПУСК ТАЙМЕРА ПАУЗЫ*)
END_IF
(*ОБНУЛЕНИЕ ТАЙМЕРА ВЫДАЮЩЕГО ИМПУЛЬСЫ ПОКА РАБОТАЕТ ТАЙМЕР ПАУЗЫ*)
IF TMR_MAX_LOW.Q OR (TIME_PULSE < MIN_TIME_PULSE) THEN
TMR_MAX_HIGHT (IN:= FALSE, PT := TIME_PULSE);
END_IF
(*АКТИВАЦИЯ ВЫХОДА РЕГУЛЯТОРА "БОЛЬШЕ" ПОКА РАБОТАЕТ ТАЙМЕР ИМПУЛЬСА И РАСЧЕТНЫМ ВРЕМЕНЕМ*)
IF (TMR_MAX_HIGHT.Q OR IN_VAL = IN_VAL_MAX) AND NOT LESS THEN
MORE := TRUE; (*АКТИВАЦИЯ "БОЛЬШЕ"*)
ELSE
MORE := FALSE; (*ИНАЧЕ ДЕАКТИВАЦИЯ "БОЛЬШЕ"*)
END_IF
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*)
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*)
(*ВЫДАЧА ИМПУЛЬСА ПРИ ОТРИЦАТЕЛЬНОМ ЗНАЧЕНИИ НА ВЫХОДЕ ПИД*)
IF (IN_VAL_MIN <0 AND IN_VAL_MAX >0) AND IN_VAL < (0 - DEAD_ZONE) THEN
MORE := FALSE; (*ОБНУЛЕНИЕ СИГНАЛА "БОЛЬШЕ" ЕСЛИ ОСТАЛСЯ АКТИВИРОВАННЫМ*)
TMR_MAX_LOW (IN:= FALSE, PT := TIME_PAUSE); (*ОБНУЛЕНИЕ ТАЙМЕРА ПАУЗЫ*)
TIME_PULSE_R := ( ( IN_VAL * PERIOD_R *(-1) ) / ( RANGE / 2) ) * 1000; (*РАСЧЕТ ВРЕМЕНИ ИМПУЛЬСА*)
TIME_PAUSE_R := (PERIOD_R*1000 - TIME_PULSE_R); (*РАСЧЕТ ТЕКУЩЕГО ВРЕМЕНИ ПАУЗЫ*)
TIME_PULSE := REAL_TO_TIME ( TIME_PULSE_R );
TIME_PAUSE := REAL_TO_TIME ( TIME_PAUSE_R );
IF TIME_PULSE > MIN_TIME_PULSE THEN (*СРАВНЕНЕНИЕ МИН ВР ИМПУЛЬСА И РАСЧЕТНОГО ТЕКУЩЕГО*)
TMR_MIN_HIGHT (IN:= TRUE AND NOT TMR_MIN_LOW.Q, PT := TIME_PULSE); (*ЗАПУСК ТАЙМЕРА*)
END_IF
F_TRIG_MIN (CLK := TMR_MIN_HIGHT.Q); (*ТРИГГЕР ЗАУСКА ТАЙМЕРА ПАУЗЫ ПРИ*)
TMR_MIN_LOW (IN:= F_TRIG_MIN.Q, PT := TIME_PAUSE); (*ЗАПУСК ТАЙМЕРА ПАУЗЫ ИМПУЛЬСА*)
END_IF
(*ОБНУЛЕНИЕ ТАЙМЕРА ВЫДАЮЩЕГО ИМПУЛЬСЫ ПОКА РАБОТАЕТ ТАЙМЕР ПАУЗЫ*)
IF TMR_MIN_LOW.Q OR (TIME_PULSE < MIN_TIME_PULSE) THEN
TMR_MIN_HIGHT (IN:= FALSE, PT := TIME_PULSE);
END_IF
(*АКТИВАЦИЯ ВЫХОДА РЕГУЛЯТОРА "МЕНЬШЕ" ПОКА РАБОТАЕТ ТАЙМЕР ИМПУЛЬСА И РАСЧЕТНЫМ ВРЕМЕНЕМ*)
IF (TMR_MIN_HIGHT.Q OR IN_VAL = IN_VAL_MIN) AND NOT MORE THEN
LESS := TRUE; (*АКТИВАЦИЯ "МЕНЬШЕ"*)
ELSE
LESS := FALSE; (*ИНАЧЕ ДЕАКТИВАЦИЯ "МЕНЬШЕ"*)
END_IF
END_IF
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\*)
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\*)
(*РУЧНОЙ РЕЖИМ РАБОТЫ*)
IF NOT AUTO THEN
IF OPENED AND NOT LESS THEN (*ЕСЛИ АВТИВИРОВАН ВХОД "OPENED" и НЕ АКТИВНО "МЕНЬШЕ"*)
MORE := TRUE; (*АКТИВАЦИЯ "БОЛЬШЕ"*)
ELSE
MORE := FALSE; (*ИНАЧЕ ДЕАКТИВАЦИЯ "БОЛЬШЕ"*)
END_IF
IF CLOSED AND NOT MORE THEN (*ЕСЛИ АВТИВИРОВАН ВХОД "CLOSED" и НЕ АКТИВНО "БОЛЬШЕ"*)
LESS := TRUE; (*АКТИВАЦИЯ "МЕНЬШЕ"*)
ELSE
LESS := FALSE; (*ИНАЧЕ ДЕАКТИВАЦИЯ "МЕНЬШЕ"*)
END_IF
END_IF
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\*)
(*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\К ОНЕЦ\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\*)