Do you have any requirements?
1. Самый простой и самый неточный способ: считать остатком деления по TIME. Удовлетворительная точность при периодах включения как минимум на пару порядков больше размерности счётчика. Корректно работает в сканах быстрее половины размерности.2. Аналогичный первому и чуть более предсказуемый способ: считать по таймеру в режиме самосброса. По-прежнему требуется периодичность включения на порядки больше размерности. Корректно работает в сканах быстрее единицы размерности.Код: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);3. Чуть более сложный и менее читаемый, но гораздо более точный и надёжный метод: копить в TIME до размерности учёта, затем складывать и сбрасывать. Время скана влияет только на точность учёта.Код: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);Код: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();




Ответить с цитированием