Страница 3 из 3 ПерваяПервая 123
Показано с 21 по 24 из 24

Тема: Управление лампой "Авария" сериями импульсов в зависимости от статусов

  1. #21

    По умолчанию

    Цитата Сообщение от Smitka Посмотреть сообщение
    Доброго дня! Не могу сообразить, как реализовать управление лампой "Авария" импульсами в зависимости от статусов на ПР200. В зависимости от того какая аварийная ситуация, индикатор выдает серию миганий. Мигание индикатора при определении аварии происходит интервально, при этом количество включенных состояний индикатора в серии импульсов показывает номер определенной аварии. Серия из одного импульса, далее пауза 1,5-2 секунды и переход к индикации следующей аварии своим количеством импульсов (два, три и т.д.). Индикация аварий осуществляется циклично.
    Добавляю более читаемый код (разработан в codesys 3.5), который, думаю, можно переделать и для ПР. Остается только коды аварий самому разработать...

    Код:
    PROGRAM PLC_PRG
    VAR
    	ALARMok:			ARRAY [1..VOLUMEofALARM] OF BOOL;	//наличие аварии для данного кода
    	TIMEforEACHcode:		ton;					//таймер на каждую активную аварию
    	NEXTalarm:			INT:= 1;				//номер шага для поиска следующей активной аварии
    	NEXTok:				BOOL;					//следующая активная авария найдена
    	OUTforLAMP:			BOOL;					//выход на сигнализацию
    	i:				INT;					//для цикла
    END_VAR
    VAR CONSTANT
    	VOLUMEofALARM:		INT:= 4;					//количество аварий
    END_VAR
    -----------------------------------------------------------
    //каждые 10 секунд показывать новую аварию
    TIMEforEACHcode(in:= NOT TIMEforEACHcode.q, pt:= T#10S);
    //ограничение по максимуму аварий
    IF NEXTalarm> VOLUMEofALARM THEN
    	NEXTalarm:= 1;
    END_IF
    //поиск следующей активной аварии
    IF NOT ALARMok[NEXTalarm] AND NOT NEXTok THEN
    	NEXTalarm:= NEXTalarm + 1;
    	IF ALARMok[NEXTalarm] THEN
    		NEXTok:= TRUE;
    	END_IF
    END_IF
    //старт поиска следующей активной аварии
    IF TIMEforEACHcode.q THEN
    	NEXTok:= FALSE;
    	NEXTalarm:= NEXTalarm + 1;
    END_IF
    
    //выход на сигнализацию
    //так:
    //OUTforLAMP:= (POU_SIG.OutX[1] AND (NEXTalarm= 1)) OR (POU_SIG.OutX[2] AND (NEXTalarm= 2)) OR (POU_SIG.OutX[3] AND (NEXTalarm= 3)) OR (POU_SIG.OutX[4] AND (NEXTalarm= 4));
    //или так:
    OUTforLAMP:= FALSE;
    FOR i:= 1 TO VOLUMEofALARM DO
    	OUTforLAMP:= OUTforLAMP OR (POU_SIG.OutX[i] AND (NEXTalarm= i));
    END_FOR
    Эх, без аварий - косячит... Надо разбираться. Но все равно, мне на ST больше код удобен, чем на FBD
    Последний раз редактировалось МихаилГл; 26.11.2025 в 12:46.

  2. #22
    Пользователь
    Регистрация
    09.12.2013
    Адрес
    Ставрополь
    Сообщений
    2,004

    По умолчанию

    Ну, у меня как-то так получилось. На нулевой бит повесил постоянное свечение

    Код:
    function_block AlarmFlash
        
        var_input
            bmAlarm : udint; //битовая маска аварий
        end_var
        
        var_output 
            Q : bool;
        end_var
        
        var 
            bitAl :bool;
            numAl : udint := 1;
            blink : SYS.BLINK;
            ctu : SYS.CTU;
            pause : SYS.TON;
            fl : SYS.FTRIG;
        end_var
        
        bitAl := shr(bmAlarm, numAl) mod 2 > 0;
        
        if bmAlarm > 1 then
            if not bitAl or pause.Q then
                ctu(R := true);
                numAl := numAl + 1;
                if numAl > 7 then numAl := 1; end_if
            end_if
        
            blink(I := bitAl and not ctu.Q, Th := t#500ms, Tl := t#500ms);
            fl(I := blink.Q);
            ctu(C := fl.Q, N := numAl, R := false);
            pause(I := ctu.Q, T := t#2s);
        else
            numAl := 1;
            ctu(R := true);
        end_if
        
        Q := blink.Q or bmAlarm.0;
    
    end_function_block
    Последний раз редактировалось Dimensy; 26.11.2025 в 19:02. Причина: Избавился то массива по подсказке Валенка

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

    По умолчанию

    to Dimensy
    массив не нужен. i-тый бит маски в этом лайт-ST
    shr(маска,i) mod 2 > 0;

  4. #24
    Пользователь
    Регистрация
    09.12.2013
    Адрес
    Ставрополь
    Сообщений
    2,004

    По умолчанию

    В продолжении мармезонского балета, еще один макрос на 32 аварии. Аварии разбиты на 4 группы по 8 бит

    Код:
    function_block AlarmFlash_2
        
        var_input
            bmAlarm : udint; //битовая маска аварий
        end_var
        
        var_output 
            Q : bool;
            Code : udint;
        end_var
        
        var 
            bitAlarm : bool;
            numGr : udint; 
            numAl : udint := 0;              
            codeAl : SYS.BLINK;
            cGroup, cAlarm : SYS.CTU;
            pGroup  : SYS.TON;
            pAlarm : SYS.TP;
            faseGr, faseAl : bool;
            flashAl :udint;
            next : SYS.RTRIG;
            res : bool;
        end_var
        
        codeAl(Th := t#300ms, Tl := t#300ms); //период моргания
        pGroup(T := t#500ms); //пауза между группа - код
        pAlarm(T := t#2700ms); // пауза между авариями
        
        //Поиск аварий
        bitAlarm := shr(bmAlarm, numAl) mod 2 > 0;
        if not bitAlarm or next.Q then
            res := true;
            numAl := numAl + 1;
            if numAl > 31 then
                numAl := 0;
            end_if
        else
            res := false;
        end_if
           
        if not pAlarm.Q then
            flashAl := 1 + (numAl mod 8);
            if numAl > 23 then numGr := 5;
                elsif numAl > 15 then numGr := 4;
                elsif numAl > 7 then numGr := 3;
                else numGr := 2;
            end_if;
        end_if
        
        cGroup(C := not Q and faseGr, N := numGr, R := res); 
        cAlarm(C := not Q and faseAl, N := flashAl, R := res);
        next(I := cAlarm.Q);
        pGroup(I := cGroup.Q);
        pAlarm(I := cAlarm.Q);
        
        faseGr := bitAlarm and not (cGroup.Q or pAlarm.Q);
        faseAl := pGroup.Q and not cAlarm.Q;
        
        codeAl(I := (faseGr or faseAl), Q => Q);
        
        if faseGr or faseAl then
            Code := numAl + 1;
        elsif bmAlarm = 0 then
            Code := 0;
        end_if
        
    end_function_block

Страница 3 из 3 ПерваяПервая 123

Похожие темы

  1. Ответов: 1
    Последнее сообщение: 18.08.2021, 09:18
  2. Ответов: 1
    Последнее сообщение: 08.09.2017, 05:55
  3. как выбрать управление "прямое" или "обратное"
    от maxmore в разделе Эксплуатация
    Ответов: 1
    Последнее сообщение: 18.01.2010, 10:13
  4. Ответов: 10
    Последнее сообщение: 11.07.2008, 13:37
  5. МДВВ постоянно уходит в режим "Авария"
    от clockwise в разделе Эксплуатация
    Ответов: 10
    Последнее сообщение: 11.07.2008, 13:37

Ваши права

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