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

Тема: Перемеренная типа TIME

  1. #1
    Пользователь
    Регистрация
    21.04.2015
    Адрес
    Екатеринбург
    Сообщений
    37

    По умолчанию Перемеренная типа TIME

    Добрый день. Подскажите пожалуйста как быть если необходимо реализовать таймер который просто считает время при активировании переменной. допустим вкл. кнопку таймер побежал, суть в том что считать нужно не всегда определенное значение времени, это может быть и год и полтора. Переменная типа TIME максимум может дает поставить 1000 часов. Дальше ошибка : константа слишком велика для типа TIME
    Последний раз редактировалось andrey96; 17.09.2015 в 14:52.

  2. #2
    Пользователь
    Регистрация
    13.10.2011
    Адрес
    Златоуст
    Сообщений
    1,021

    По умолчанию

    TIME это миллисекунды. Вам нужны миллисекунды? Значит, и TIME ни к чему. Считайте минутами, часами, да хоть годами.

  3. #3
    Пользователь
    Регистрация
    21.04.2015
    Адрес
    Екатеринбург
    Сообщений
    37

    По умолчанию

    Каким образом? на вход таймера значения задаются в формате t#0h0m0s. или стандартными таймерами это не реализовать и нужен другой таймер?

  4. #4
    Пользователь
    Регистрация
    13.10.2011
    Адрес
    Златоуст
    Сообщений
    1,021

    По умолчанию

    Do you have any requirements?

    1. Самый простой и самый неточный способ: считать остатком деления по TIME. Удовлетворительная точность при периодах включения как минимум на пару порядков больше размерности счётчика. Корректно работает в сканах быстрее половины размерности.
    Код:
    VAR
    	on: BOOL;
    	uptimeSeconds: UDINT;
    	tickTock: R_TRIG;
    END_VAR
    
    tickTock(CLK := TIME_TO_UDINT(TIME()) MOD 1000 > 500);
    uptimeSeconds := uptimeSeconds + BOOL_TO_UDINT(on AND tickTock.Q);
    2. Аналогичный первому и чуть более предсказуемый способ: считать по таймеру в режиме самосброса. По-прежнему требуется периодичность включения на порядки больше размерности. Корректно работает в сканах быстрее единицы размерности.
    Код:
    VAR
    	on: BOOL;
    	uptimeSeconds: UDINT;
    	tickTock: TON := (PT := T#1s);
    END_VAR
    
    tickTock(IN := on AND NOT tickTock.Q);
    uptimeSeconds := uptimeSeconds + BOOL_TO_UDINT(tickTock.Q);
    3. Чуть более сложный и менее читаемый, но гораздо более точный и надёжный метод: копить в TIME до размерности учёта, затем складывать и сбрасывать. Время скана влияет только на точность учёта.
    Код:
    VAR
    	on: BOOL;
    	uptimeSeconds: UDINT;
    	prevTime, acc: TIME;
    END_VAR
    
    IF on THEN
    	acc := acc + TIME() - prevTime;
    END_IF
    uptimeSeconds := uptimeSeconds + TIME_TO_UDINT(acc) / 1000;
    acc := UDINT_TO_TIME(TIME_TO_UDINT(acc) MOD 1000);
    prevTime := TIME();

  5. #5

    По умолчанию

    Код:
    FUNCTION_BLOCK TIMER
    VAR_INPUT
    	iCntUp : BOOL;
    	iCntDn : BOOL;
    	iCntRes : BOOL;
    	iCntSP : TIME;
    	(*iIncSP : TIME;----ДОБАВЛЕНО для данного топика: величина периода, который считает/приращивает счетчик*)
    END_VAR
    VAR_OUTPUT
    	OutTime : TIME;
    	OutAlm : BOOL;
    	(*OutCnt : UINT;----ДОБАВЛЕНО для данного топика: считайте сколько нужно дней/часов/минут/недель*)
    END_VAR
    VAR
    	TimeAct : TIME;
    	TimeOld : TIME;
    	TimeDelta : TIME;
    	DoCalc : UINT;
    	Init: BOOL;
    	CntUpOld :BOOL;
    	CntDnOld : BOOL;
    END_VAR
    
    
    
    IF iCntRes THEN Init := FALSE; END_IF
    
    
    (*INIT*)
    IF NOT Init THEN
    				Init := TRUE;
    				iCntUp := iCntDn := CntUpOld := CntDnOld := OutAlm := FALSE;
    				TimeAct := TimeOld := TimeDelta := OutTime := t#0ms;
    	(*ДОБАВЛЕНО: 		OutCnt := 0;*)
    				DoCalc := 0;
    				RETURN;
    END_IF
    
    
    (*DOCALC*)
    DoCalc := DoCalc +1;
    
    IF (DoCalc MOD 10=0) OR (iCntUp <> CntUpOld) OR (iCntDn <> CntDnOld) THEN
    
    
    TimeAct :=TIME();
    
    		IF TimeOld > t#0ms THEN
    		TimeDelta := TimeAct - TimeOld;
    
    		(*COUNT_UP*)
    			IF iCntUp OR (CntUpOld > iCntUp) THEN
    						IF iCntSP > OutTime THEN OutTime := OutTime + TimeDelta;
    						IF OutTime > iCntSP THEN OutTime := iCntSP; END_IF
    						END_IF;
    			END_IF
    
    		(*COUNT_DOWN*)
    			IF iCntDn OR (CntDnOld > iCntDn) THEN
    						IF OutTime > TimeDelta THEN OutTime := OutTime - TimeDelta;
    						ELSE OutTime := t#0ms;
    						END_IF;
    			END_IF
    
    (*ДОБАВЛЕНО:	IF OutTime >= iIncSP THEN OutCnt := OutCnt + 1; OutTime := OutTime - iIncSP; END_IF*)
    		OutAlm := iCntSP > t#0ms AND OutTime = iCntSP;
    
    		END_IF
    
    		TimeOld := TimeAct;
    
    END_IF
    
    CntUpOld := iCntUp;
    CntDnOld := iCntDn;

  6. #6
    Пользователь
    Регистрация
    21.04.2015
    Адрес
    Екатеринбург
    Сообщений
    37

    По умолчанию

    Цитата Сообщение от spectrum48k Посмотреть сообщение
    Код:
    FUNCTION_BLOCK TIMER
    VAR_INPUT
    	iCntUp : BOOL;
    	iCntDn : BOOL;
    	iCntRes : BOOL;
    	iCntSP : TIME;
    	(*iIncSP : TIME;----ДОБАВЛЕНО для данного топика: величина периода, который считает/приращивает счетчик*)
    END_VAR
    VAR_OUTPUT
    	OutTime : TIME;
    	OutAlm : BOOL;
    	(*OutCnt : UINT;----ДОБАВЛЕНО для данного топика: считайте сколько нужно дней/часов/минут/недель*)
    END_VAR
    VAR
    	TimeAct : TIME;
    	TimeOld : TIME;
    	TimeDelta : TIME;
    	DoCalc : UINT;
    	Init: BOOL;
    	CntUpOld :BOOL;
    	CntDnOld : BOOL;
    END_VAR
    
    
    
    IF iCntRes THEN Init := FALSE; END_IF
    
    
    (*INIT*)
    IF NOT Init THEN
    				Init := TRUE;
    				iCntUp := iCntDn := CntUpOld := CntDnOld := OutAlm := FALSE;
    				TimeAct := TimeOld := TimeDelta := OutTime := t#0ms;
    	(*ДОБАВЛЕНО: 		OutCnt := 0;*)
    				DoCalc := 0;
    				RETURN;
    END_IF
    
    
    (*DOCALC*)
    DoCalc := DoCalc +1;
    
    IF (DoCalc MOD 10=0) OR (iCntUp <> CntUpOld) OR (iCntDn <> CntDnOld) THEN
    
    
    TimeAct :=TIME();
    
    		IF TimeOld > t#0ms THEN
    		TimeDelta := TimeAct - TimeOld;
    
    		(*COUNT_UP*)
    			IF iCntUp OR (CntUpOld > iCntUp) THEN
    						IF iCntSP > OutTime THEN OutTime := OutTime + TimeDelta;
    						IF OutTime > iCntSP THEN OutTime := iCntSP; END_IF
    						END_IF;
    			END_IF
    
    		(*COUNT_DOWN*)
    			IF iCntDn OR (CntDnOld > iCntDn) THEN
    						IF OutTime > TimeDelta THEN OutTime := OutTime - TimeDelta;
    						ELSE OutTime := t#0ms;
    						END_IF;
    			END_IF
    
    (*ДОБАВЛЕНО:	IF OutTime >= iIncSP THEN OutCnt := OutCnt + 1; OutTime := OutTime - iIncSP; END_IF*)
    		OutAlm := iCntSP > t#0ms AND OutTime = iCntSP;
    
    		END_IF
    
    		TimeOld := TimeAct;
    
    END_IF
    
    CntUpOld := iCntUp;
    CntDnOld := iCntDn;
    Спасибо, решил проблему созданием счетчика из него взял нужное количество дней)

Похожие темы

  1. Использование переменной TIME
    от Валера Храмцов в разделе ПЛК1хх
    Ответов: 20
    Последнее сообщение: 26.08.2021, 09:48
  2. Преобразование в TIME
    от АлексPetr в разделе ПЛК1хх
    Ответов: 3
    Последнее сообщение: 07.02.2010, 14:01
  3. Polling time для ТРМ
    от Антон12345 в разделе ПЛК1хх
    Ответов: 4
    Последнее сообщение: 23.12.2009, 12:20

Ваши права

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