Показано с 1 по 5 из 5

Тема: Таймеры, переменные и условия

  1. #1

    По умолчанию Таймеры, переменные и условия

    Здравствуйте уважаемые форумчане, прошу подтолкнуть в сторону решения следующей задачи:
    есть три булевые переменные vent1,vent2,vent3. Все они включаюся по тамеру, который определяет время работы(true) и время паузы(false) у каждой переменной отдельно, как организоавать цикл для проверки следующего условия:
    Если таймер переменной подошел к запуску то проверить, что другие(другая) перменные уже работают более 3 секунд или до их остановки более 3 секунд, то запуститься сразу иначе отложить запуск переменой на 5 секунд.
    Под запуском понимается переход в true.

    Код:
    vent1(ENABLE:=stop_vent1, TIMELOW:=Pause_Time1 , TIMEHIGH:=Run_Time1 , OUT=> );
    Timer_Run1(IN:=vent1.OUT, PT:=Run_Time1 , Q=> , ET=> );
    Timer_Pause1(IN:=NOT vent1.OUT, PT:=Pause_Time1 , Q=> , ET=> );
    Pause_Time1 и Run_Time1 переменные для задачи времени
    Stop_Vent1 булевая переменная аварийной остановки
    Timer_Run1 и Timer_Pause1 таймеры для вывод информации о текущем времени работы и паузы
    out1, out2, out3 непосредственно дискретные выходы плк
    Код:
    IF vent2.OUT THEN
    		IF    (Vent1.out AND  Timer_Run1.ET < T#3s) OR (Stop_Vent1 AND (NOT out1 AND (Pause_Time1-Timer_Pause1.ET < T#3s))) THEN
    			out2_ton(in:=TRUE, pt:=T#5s);
    			out2:=out2_ton.Q;
    			ostalos2:=(Run_Time2-Timer_Run2.ET);
    		ELSE
    			out2:=TRUE;
    			ostalos2:=(Run_Time2-Timer_Run2.ET);
    		END_IF
    
    ELSE
    		out2:=FALSE;
    		out2_ton(in:=FALSE, pt:=T#0s);
    		ostalos2:=(Pause_Time2-Timer_Pause2.ET);
    
    END_IF
    вот творчество пока на этом зависло...

  2. #2

    По умолчанию

    Обновление переменных, связанных с таймером (например, TON) происходит не само по себе, а только при вызове ФБ - т.е. нужно вызовы ФБ выполнять не в ветках IF, а в основной части, а in:=true/false формировать при помощи переменной. Иначе в ELSE вложенного IF обновление out2_ton.out прекратится.

    А по алгоритму. Сейчас пытаюсь решить подобную задачу.
    Т.к. программа (на любом из языков IEC) выполняется не одновременно, а последовательно слева направо и сверху вниз, то значит для агрегата (вентилятора) №1 будут актуальны блокировки пуска от других вентиляторов из прошлого машинного цикла.

    Т.е. нужны комплекты переменных для каждого агрегата:
    - bRequestStart1...3 - запрос включения (из алгоритма)
    - bStart1...3 - состояние включения (то, что на пускатель пойдёт)
    - bStartPrevious1...3 - состояние включения (то, что на пускатель пойдёт) на предыдущем машинном цикле
    - bSwitchingNow1...3 - выполняется отсчёт паузы по переключению от 1 (...3) к остальным агрегатам
    - bSwitchingEn1...3 - разрешение 1 (...3) агрегату менять состояние
    - таймеры импульсов TP1...3 - для отсчёта паузы запрещающей переключение другим.

    Для каждого агрегата определять:
    1. разрешение менять состояние bSwitchingEn1 := not(bSwitchingNow2 or bSwitchingNow3)
    2. если есть разрешение и необходимость изменения, то изменить состояние
    Код:
    if bSwitchingEn1 and (bRequestStart1 <> bStart1) then
        bStart1 := bRequestStart1;
    end_if
    3. запустить отсчёт таймера TP по условию изменения состояния (bStart1 xor bStartPrevious1) сам таймер за пределами IF
    4. изменить состояние bSwitchingNow1 := TP1.out, по которому заблокируется потом переключение других агрегатов
    5. обновить bStartPrevious1 := bStart1

    И потом повторить это для каждого из агрегатов.
    Именно такими блоками и размножить, т.к. код выполняется последовательно и по мере выполнения могут блокироваться переключения для нижерасположенных агрегатов.

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

    Мне кажется так нужно

  3. #3
    Пользователь
    Регистрация
    23.09.2008
    Адрес
    Центророссийск
    Сообщений
    3,081

    По умолчанию

    Цитата Сообщение от savir Посмотреть сообщение
    .. для проверки следующего условия:
    Если таймер переменной подошел к запуску то проверить, что другие(другая) перменные уже работают более 3 секунд или до их остановки более 3 секунд, то запуститься сразу иначе отложить запуск переменой на 5 секунд..
    Это через анус сказано что пауза между переключениями вентов должна быть не менее чем что-то?

  4. #4

    По умолчанию

    Можно и подтолнуть:
    Код:
    Pause : BOOL;
    TMR1, TMR2, TMR3 : TON;
    TMR_Pause : TOF;
    
    // Отсчёт времени работы или простоя
    TMR1(IN := TRUE, PT := SEL(vent1, Pause_Time1, Run_Time1));
    TMR2(IN := TRUE, PT := SEL(vent2, Pause_Time1, Run_Time1));
    TMR3(IN := TRUE, PT := SEL(vent3, Pause_Time1, Run_Time1));
    
    TMR_Pause(IN := Pause, PT := T#5s);		// Таймер паузы - перезапустится, если нужна пауза
    Pause := FALSE;
    
    IF NOT TMR_Pause.Q THEN 	// Пауза выдержана
    	IF TMR1.Q AND NOT vent1 THEN		// Пришло время включить vent1
    		IF vent2 THEN		// vent2 - работает
    			Pause := Pause OR (TMR2.ET < T#3s OR TMR2.PT - TMR2.ET < T#3s);	// если работает меньше 3s или должен скоро остановиться - нужна пауза
    		END_IF
    		IF vent3 THEN		// vent3 - работает
    			Pause := Pause OR (TMR3.ET < T#3s OR TMR3.PT - TMR3.ET < T#3s);	// если работает меньше 3s или должен скоро остановиться - нужна пауза
    		END_IF
    		vent1 := NOT Pause; IF vent1 THEN TMR1(IN := FALSE); END_IF// Запуск vent1 и сброс таймера
    	END_IF
    
    	IF TMR2.Q AND NOT vent2 THEN		// Пришло время включить vent2
    		IF vent1 THEN		// vent2 - работает
    			Pause := Pause OR (TMR1.ET < T#3s OR TMR1.PT - TMR1.ET < T#3s);	// если работает меньше 3s или должен скоро остановиться - нужна пауза
    		END_IF
    		IF vent3 THEN		// vent3 - работает
    			Pause := Pause OR (TMR3.ET < T#3s OR TMR3.PT - TMR3.ET < T#3s);	// если работает меньше 3s или должен скоро остановиться - нужна пауза
    		END_IF
    		vent2 := NOT Pause; IF vent2 THEN TMR2(IN := FALSE); END_IF	// Запуск vent2 и сброс таймера
    	END_IF
    
    	IF TMR3.Q AND NOT vent3 THEN		// Пришло время включить vent3
    		IF vent1 THEN		// vent1 - работает
    			Pause := Pause OR (TMR1.ET < T#3s OR TMR1.PT - TMR1.ET < T#3s);	// если работает меньше 3s или должен скоро остановиться - нужна пауза
    		END_IF
    		IF vent2 THEN		// vent2 - работает
    			Pause := Pause OR (TMR2.ET < T#3s OR TMR2.PT - TMR2.ET < T#3s);	// если работает меньше 3s или должен скоро остановиться - нужна пауза
    		END_IF
    		vent3 := NOT Pause; IF vent3 THEN TMR3(IN := FALSE); END_IF	// Запуск vent3 и сброс таймера
    	END_IF
    
    END_IF
    
    IF TMR1.Q AND vent1 THEN	// Пришло время выключить vent1
    	vent1 := FALSE; TMR1(IN := FALSE);	// Стоп vent1 и сброс таймера
    END_IF
    IF TMR2.Q AND vent2 THEN	// Пришло время выключить vent2
    	vent2 := FALSE; TMR2(IN := FALSE);	// Стоп vent2 и сброс таймера
    END_IF
    IF TMR3.Q AND vent3 THEN	// Пришло время выключить vent3
    	vent3 := FALSE; TMR3(IN := FALSE);	// Стоп vent3 и сброс таймера
    END_IF
    Последний раз редактировалось EFrol; Сегодня в 16:39.

  5. #5

    По умолчанию

    У меня для 5 агрегатов в Owen Logic так получилось
    В OwenLogic нет возможности передать время, поэтому в ФБ передаётся целое число с последующим преобразованием в тип time, из-за выбора единиц измерения входной переменной в секундах, домножаю на 1000.
    bEnable - это для назначения всех выходов в выключенное состояние - например, при аварийном останове или на период инициализации после подачи питания.
    Код:
    FUNCTION_BLOCK NotAllAtOnce5_
    
        VAR_INPUT
            bEnable: BOOL;
            bRequest1: BOOL;
            bRequest2: BOOL;
            bRequest3: BOOL;
            bRequest4: BOOL;
            bRequest5: BOOL;
            nDelay_s: UDINT;
        END_VAR
    
        VAR_OUTPUT
            bStart1: BOOL;
            bStart2: BOOL;
            bStart3: BOOL;
            bStart4: BOOL;
            bStart5: BOOL;
        END_VAR
    
        VAR
            tDelay: TIME;
    
            bStartPrevious1: BOOL;
            bStartPrevious2: BOOL;
            bStartPrevious3: BOOL;
            bStartPrevious4: BOOL;
            bStartPrevious5: BOOL;
    
            tpPause: SYS.TP;
    
            bSwitchEn: BOOL; // разрешение изменить состояние
    
        END_VAR
    
        // преобразование типа и пересчёт значения в [с]
        tDelay := UDINT_TO_TIME(nDelay_s * 1000);
        // ограничение минимального значения
        IF tDelay < T#1s THEN
            tDelay := T#1s;
        END_IF
        // присвоение таймеру для уменьшения параметров в следующих вызовах
        tpPause(T := tDelay);
    
        IF bEnable THEN
            // обработка для агрегата 1
            bSwitchEn := NOT(tpPause.Q) AND (bRequest1 <> bStart1);
            IF bSwitchEn THEN
                bStart1 := bRequest1;
            END_IF
            tpPause(I := bSwitchEn); // обновление значения выхода таймера для следующего обработчика
    
            // обработка для агрегата 2
            bSwitchEn := NOT(tpPause.Q) AND (bRequest2 <> bStart2);
            IF bSwitchEn THEN
                bStart2 := bRequest2;
            END_IF
            tpPause(I := bSwitchEn); // обновление значения выхода таймера для следующего обработчика
    
            // обработка для агрегата 3
            bSwitchEn := NOT(tpPause.Q) AND (bRequest3 <> bStart3);
            IF bSwitchEn THEN
                bStart3 := bRequest3;
            END_IF
            tpPause(I := bSwitchEn); // обновление значения выхода таймера для следующего обработчика
    
            // обработка для агрегата 4
            bSwitchEn := NOT(tpPause.Q) AND (bRequest4 <> bStart4);
            IF bSwitchEn THEN
                bStart4 := bRequest4;
            END_IF
            tpPause(I := bSwitchEn); // обновление значения выхода таймера для следующего обработчика
    
            // обработка для агрегата 5
            bSwitchEn := NOT(tpPause.Q) AND (bRequest5 <> bStart5);
            IF bSwitchEn THEN
                bStart5 := bRequest5;
            END_IF
            tpPause(I := bSwitchEn); // обновление значения выхода таймера для следующего обработчика
        ELSE
            // отсчёт от момента выключения, для паузы при быстром переключении bEnable
            tpPause(I := bStart1 OR bStart2 OR bStart3 OR bStart4 OR bStart5);
            // выключить все агрегаты
            bStart1 := FALSE;
            bStart2 := FALSE;
            bStart3 := FALSE;
            bStart4 := FALSE;
            bStart5 := FALSE;
        END_IF
        bStartPrevious1 := bStart1;
        bStartPrevious2 := bStart2;
        bStartPrevious3 := bStart3;
        bStartPrevious4 := bStart4;
        bStartPrevious5 := bStart5;
    END_FUNCTION_BLOCK

Похожие темы

  1. Таймеры TON TOF в ST
    от Veronik в разделе ПЛК1хх
    Ответов: 7
    Последнее сообщение: 10.12.2018, 23:46
  2. Таймеры
    от Постнов Никита в разделе Среда программирования OWEN Logic
    Ответов: 2
    Последнее сообщение: 30.03.2016, 09:28
  3. Таймеры
    от Атаман в разделе ПЛК1хх
    Ответов: 12
    Последнее сообщение: 03.10.2015, 14:52
  4. Таймеры
    от sd_white в разделе ПЛК1хх
    Ответов: 4
    Последнее сообщение: 01.04.2014, 10:41
  5. Условия в цикле
    от Wanted в разделе ПЛК1хх
    Ответов: 5
    Последнее сообщение: 23.11.2008, 11:12

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •