всего лишь подбиваю уйти от трещетки и работать с накоплением времени а не импульсов )
Вид для печати
всего лишь подбиваю уйти от трещетки и работать с накоплением времени а не импульсов )
не путаем. речь идет не об обострении перфекционизма и борьбой с каждой потерянной милисекундой, а именно с большой накопленной погрешностью. для кого некритично, вообще заморачиваться не стоит. хотелось бы прийти к истинно правильному методу с точки зрения математики и плк-шного квантования времени, так сказать к примеру №1 добавить пример №2 для ценителей)) (желательно простой и без посторонних бибок , как у меня)
Так вот товарищ Петера выше все сделал !
А можно еще изящнее - задействовать TASK_Manager и отдаться ему (Du hast mich:p) вызывая 1 раз в секунду программу Tik_1s с одной строчкой Tik:=true;
С точки зрения математической правильности конечно надо с TIME() работать .
Америкосы тоже калаш сначала модернизировать пытались , зазоры все убрали , подогнали все четко-идеально ... , а он не заработал ...
вариации на тему)
Код:
FUNCTION_BLOCK TIMER
VAR_INPUT
iCntUp : BOOL;
iCntDn : BOOL;
iCntRes : BOOL;
iCntSP : TIME;
END_VAR
VAR_OUTPUT
OutTime : TIME;
OutAlm : BOOL;
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;
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
OutAlm := iCntSP > t#0ms AND OutTime = iCntSP;
END_IF
TimeOld := TimeAct;
END_IF
CntUpOld := iCntUp;
CntDnOld := iCntDn;
Круть!
Как там у Филоненко , -"Любую проблему можно решить увеличением числа параметров , кроме проблемы чрезмерного числа параметров".
Сброс Вар_Инпут тоже ... странный маневр.
(*Подсчет действительного времени наработки*)
IF NOT Wrk_drv1 THEN
t_Start:=tim;
ELSE
Wrk_tim:=tim-t_Start;
END_IF
petera какое поведение будет при переходе через ноль ? при смене суток.
Функция TIME() возвращает время работы ПЛК в мс от момента его включения, и к времени суток (RTC) отношения не имеет.
По этому переполнение произойдет не при смене суток, а через 49d17h2m47s295ms (4294967295 ms) от момента включения ПЛК.
ЗЫ. Уточню. Переполнение TIME() произойдет не при смене суток, а через 49d17h2m47s295ms (4294967295 ms) от момента включения ПЛК.
Поэтому максимальное значение Wrk_tim при таком варианте подсчета равно 49d17h2m47s295ms.
при большом желании при превышении интервала более суток можно плюсовать счетчик суток, а из дворда интервала времени вычитать t#1d