Загрузка данных


IF BlinkState_05S THEN
 C := NOT(C);
END_IF
 
IF Stop OR Flow_alarm OR Pump_fault OR NOT(phase_ok) THEN // остановка аварийной кнопкой
 PV.On_chiller:= FALSE;
END_IF

Alarm_comp := (pressure_real > 32) OR NOT(Pressure_low) OR NOT(Pressure_up);
 
IF PV.On_chiller THEN                                    // включение с панели
     On_sw_chiller:="СТОП";
     Pump_on:=TRUE;
ELSE 
     On_sw_chiller:="ПУСК";	
     Pump_on:=FALSE;
END_IF

Time_pump                                               //Задержка ошибки реле протока.
        (IN := Pump_on,PT := PV.Pump_time);
IF Time_pump.Q THEN
    Flow_alarm := NOT(Flow);
    Time_pump(IN := FALSE);
END_IF
// Сброс аварии потока при выключении насоса
IF NOT Pump_on THEN
    Flow_alarm := FALSE;
END_IF

IF PV.On_chiller THEN
 
  Water_PID(                                          //Пид регулятор воды
    ACT:= temp_in, 
    SET:= Pv.temp, 
    SUP:= 0.1, 
    OFS:= 0, 
    M_I:= , 
    MAN:= , 
    RST:= NOT (PV.On_chiller), 
    KP:= Water_KP, 
    TN:= Water_KI, 
    TV:= Water_KD,  
    LL:= Water_LL, 
    LH:= Water_LH, 
    Y=> Water_PI_out, 
    DIFF=> , 
    LIM=> Water_LIM);
    Water_PI_real_out := Water_LH - Water_PI_out;
    
    Pump1_time := PV.Comp_on_time;
    Pump2_time := PV.Comp_on_time;   // исправлено: одинаковое время задержки (при необходимости замените на отдельную уставку)

    // Определение требуемого числа компрессоров и управление ими
    IF NOT(Alarm_comp) THEN
        // Вычисление req_comp
        IF Water_PI_real_out <= 5 THEN
            req_comp := 0;
        ELSIF Water_PI_real_out < 90 THEN
            req_comp := 1;
        ELSE
            req_comp := 2;
        END_IF
        
        // Управление компрессорами с чередованием по наработке
        CASE req_comp OF
            0:  // выключены оба
                Comp_1_on := FALSE;
                Comp_2_on := FALSE;
            2:  // включены оба
                Comp_1_on := TRUE;
                Comp_2_on := TRUE;
            1:  // работает один
                IF Comp_1_RUN AND Comp_2_RUN THEN
                    // Переход 2 → 1: выключаем тот, у кого наработка БОЛЬШЕ
                    IF PV.WorkTime_drill_comp1_MIN > PV.WorkTime_drill_comp2_MIN THEN
                        Comp_1_on := FALSE;
                        Comp_2_on := TRUE;   // второй остаётся
                    ELSE
                        Comp_1_on := TRUE;
                        Comp_2_on := FALSE;
                    END_IF
                ELSIF Comp_1_RUN AND NOT Comp_2_RUN THEN
                    // Уже работает первый – оставляем
                    Comp_1_on := TRUE;
                    Comp_2_on := FALSE;
                ELSIF NOT Comp_1_RUN AND Comp_2_RUN THEN
                    // Уже работает второй – оставляем
                    Comp_1_on := FALSE;
                    Comp_2_on := TRUE;
                ELSE
                    // Ни один не работает: включаем того, у кого наработка МЕНЬШЕ
                    IF PV.WorkTime_drill_comp1_MIN <= PV.WorkTime_drill_comp2_MIN THEN
                        Comp_1_on := TRUE;
                        Comp_2_on := FALSE;
                    ELSE
                        Comp_1_on := FALSE;
                        Comp_2_on := TRUE;
                    END_IF
                END_IF
        END_CASE
    ELSE
        // Авария по давлению – снимаем команды
        Comp_1_on := FALSE;
        Comp_2_on := FALSE;
    END_IF
 
    // Таймер открытия клапана (автоматический)
    Valve (
        IN := Comp_1_on OR Comp_2_on,
        PT := PV.Comp_on_time - PV.Valve_on_time
    );
    // Valve_on теперь формируется ниже с учётом ручного режима

    // Таймеры минимального простоя
    Time_comp_1_RUN (
        IN := Comp_1_on,
        PT := Pump1_time
    );
    IF Time_comp_1_RUN.Q THEN
        Time_comp_1_STOP(IN := FALSE);
        Comp_1_RUN := TRUE;
    END_IF
     
    Time_comp_2_RUN (
        IN := Comp_2_on,
        PT := Pump2_time
    );
    IF Time_comp_2_RUN.Q THEN
        Time_comp_2_STOP(IN := FALSE);
        Comp_2_RUN := TRUE;
    END_IF
     
    // Таймеры минимальной работы
    Time_comp_1_STOP (
        IN := NOT(Comp_1_on),
        PT := PV.Comp_off_time
    );
    IF Time_comp_1_STOP.Q THEN
        Time_comp_1_RUN(IN := FALSE);
        Comp_1_RUN := FALSE;
    END_IF
    
    Time_comp_2_STOP (
        IN := NOT(Comp_2_on),
        PT := PV.Comp_off_time
    );
    IF Time_comp_2_STOP.Q THEN
        Time_comp_2_RUN(IN := FALSE);
        Comp_2_RUN := FALSE;
    END_IF
     
    // Аварийное отключение компрессоров по давлению
    IF Alarm_comp THEN
        Comp_1_on := FALSE;
        Comp_2_on := FALSE;
        Time_comp_1_RUN(IN := FALSE);
        Time_comp_1_STOP(IN := FALSE);    // добавлен сброс таймера STOP
        Comp_1_RUN := FALSE; 
        Time_comp_2_RUN(IN := FALSE);
        Time_comp_2_STOP(IN := FALSE);    // добавлен сброс таймера STOP
        Comp_2_RUN := FALSE; 
    END_IF
     
    // Автоматическое закрытие клапана при останове обоих компрессоров
    Valve_TRIG(CLK := NOT(Comp_1_RUN) AND NOT(Comp_2_RUN));
    IF Valve_TRIG.Q THEN 
        Valve(IN := FALSE);   // сбрасываем автоматический таймер
        // Valve_on не трогаем – он вычисляется ниже с учётом ручного
    END_IF
  
    // Ручное управление клапаном: по нажатию кнопки Valve_RES открыть на 3 секунды
    Valve_Manual_Timer(IN := Valve_RES, PT := T#3S);
    // Итоговый сигнал клапана: автоматика ИЛИ ручное
    Valve_on := Valve.Q OR Valve_Manual_Timer.Q;

    // Расчет наработки компрессоров
    Time_comp1(IN := Comp_1_RUN, PT := T#1M);   // исправлено Comp_1_run -> Comp_1_RUN
    Time_comp1_TRIG(CLK := Time_comp1.Q);
    IF Time_comp1_TRIG.Q THEN
        PV.WorkTime_drill_comp1_MIN := PV.WorkTime_drill_comp1_MIN + 1;
        Time_comp1(IN := FALSE);
    END_IF 
    IF PV.WorkTime_drill_comp1_MIN = 1440 THEN 
        PV.WorkTime_drill_comp1_D := PV.WorkTime_drill_comp1_D + 1;
        PV.WorkTime_drill_comp1_MIN := 0;
    END_IF
  
    Time_comp2(IN := Comp_2_RUN, PT := T#1M);   // исправлено Comp_2_run -> Comp_2_RUN
    Time_comp2_TRIG(CLK := Time_comp2.Q);
    IF Time_comp2_TRIG.Q THEN
        PV.WorkTime_drill_comp2_MIN := PV.WorkTime_drill_comp2_MIN + 1;
        Time_comp2(IN := FALSE);
    END_IF 
    IF PV.WorkTime_drill_comp2_MIN = 1440 THEN 
        PV.WorkTime_drill_comp2_D := PV.WorkTime_drill_comp2_D + 1;
        PV.WorkTime_drill_comp2_MIN := 0;
    END_IF

ELSE
    // Чиллер выключен
    Comp_1_on := FALSE;
    Comp_2_on := FALSE;
    Vent_1_on := FALSE;
    Vent_2_on := FALSE;
    Comp_1_RUN := FALSE;
    Comp_2_RUN := FALSE;
    Valve_on := FALSE;
    Time_comp_1_STOP(IN := FALSE); 
    Time_comp_1_RUN(IN := FALSE); 
    Time_comp_2_STOP(IN := FALSE); 
    Time_comp_2_RUN(IN := FALSE);
    Valve(IN := FALSE);
END_IF

  Vent_PID(               //Пид регулятор вентиляторов
    ACT:= pressure_real, 
    SET := Pv.pressure,
    SUP:= 0.1, 
    OFS:= 0, 
    M_I:= , 
    MAN:= , 
    RST:= NOT (Comp_1_RUN OR Comp_2_RUN), 
    KP:= Vent_KP, 
    TN:= Vent_KI, 
    TV:= Vent_KD,  
    LL:= Vent_LL, 
    LH:= Vent_LH, 
    Y=> Vent_PI_out, 
    DIFF=> , 
    LIM=> Vent_LIM);	
    Vent_PI_real_out := Vent_LH - Vent_PI_out;
    Vent_PI_INT_out := TO_UINT (Vent_PI_real_out);
    Vent_1_on := Comp_1_RUN OR Comp_2_RUN;
    Vent_2_on := Comp_1_RUN OR Comp_2_RUN;