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();