PDA

Просмотр полной версии : Отсчёт времени ПЛК110 М02 с погрешностью 5 сек за 10 мин



Антон_Б
22.10.2016, 18:53
Есть свободно исполняемая задача в Кодесис 2.3 для ПОК110 М02 в которой ведётся отсчёт времени процесса от 0 до 1 час 30 мин 00 сек. Но получается очень большое отклонение по времени от "эталонного" секундомера. Код


PROGRAM TIMER_SEC
VAR
(* глобальные переменные
_SEC : BYTE := 0;
_MIN : BYTE := 0;
_HUR : BYTE := 0;
*)
tx : DWORD;
last : DWORD;
ms : DWORD;

(* ЭЛЕМЕНТЫ *)
R_trigger : R_TRIG;
END_VAR
(* ОБНУЛЕНИЕ ПЕРЕМЕННЫХ ВРЕМЕНИ *)
IF (RESET_TIMER) THEN
_SEC := 0;
_MIN := 0;
_HUR := 0;
_SEC_PROC := 0;
RESET_TIMER := FALSE;
END_IF

(* ТАКТИРОВАНИЕ ТРИГГЕРА *)
R_trigger( CLK := START_TIMER AND NOT (STOP_TIMER) );


(* ЗАПУСК ТАЙМЕРА ПО КОМАНДЕ *)
IF ( START_TIMER AND NOT (STOP_TIMER) ) THEN

(* ВХОД В ФУНКЦИЮ. ВЫПОЛНЯЕТСЯ ОДИН РАЗ ПРИ ВХОДЕ *)
IF R_trigger.Q = TRUE THEN
tx := TIME_TO_DWORD(TIME());
END_IF

ms := TIME_TO_DWORD(TIME()) - tx;

(* УВЕЛИЧЕНИЕ ВРЕМЕНИ ПРОЦЕССА НА 1 сек*)
IF ms >= 1000 THEN
_SEC_PROC := _SEC_PROC + 1;

IF _SEC < 59 THEN _SEC := _SEC + 1; ELSE _SEC := 0;

IF _MIN <59 THEN _MIN := _MIN + 1; ELSE _HUR := _HUR + 1; _MIN := 0; END_IF

END_IF

ms := 0;
tx := TIME_TO_DWORD(TIME());

END_IF
END_IF


Прошу помощи в решении проблемы более точного отсчёта времени.

Владимир Ситников
22.10.2016, 19:16
Прошу помощи в решении проблемы более точного отсчёта времени.

У вас TIME() выполняется 2 раза. Время между этими вызовами "теряется".

Лучше в "начале" процесса просто сохраните "текущее время", и когда нужна длительность, то просто вычитайте из текущего времени "время старта".

capzap
22.10.2016, 19:27
код написан по идиотски. Наличие нескольких вызовов таймеров ни как не влияет, а вот какой то бредовый способ самостоятельно вычислять секунды, минуты и т.д не дает добиться приемливого результата. Ну есть же в оскате функции получения времени из миллисекунд, зачем придумывать "велосипед"

Антон_Б
22.10.2016, 19:32
Подскажите Как называется эта функция? Есть ли она для 2ого кодесус?

Антон_Б
22.10.2016, 20:49
ИСПОЛЬЗОВАЛ ФУНКЦИЮ ONTIME из OSCAT и офигел от объёма получившегося кода. Он сразу увеличился на 50 кБ.

capzap
22.10.2016, 20:56
ИСПОЛЬЗОВАЛ ФУНКЦИЮ ONTIME из OSCAT и офигел от объёма получившегося кода. Он сразу увеличился на 50 кБ.

ну значит Вам так хочется. Не проще полученную разницу преобразовать с помощью DWORD_TO_TIME и уже полученное время в любой момент будет актуальным с начала отсчета,+-погрешность контроллера. А затем уже из полученнного времени вычислять отдельно секунды минуты и т.п.

Антон_Б
22.10.2016, 20:59
IF _SEC <= 59 THEN _SEC := _SEC + 1; ELSE _SEC := 0;

IF _MIN <=59 THEN _MIN := _MIN + 1; ELSE _HUR := _HUR + 1; _MIN := 0; END_IF

Похоже ошибка в проверке не просто < 59 , а <=59. Недоставало 1 сек 1 мин и т. п.

capzap
22.10.2016, 21:21
да Вы настырный, всё пытаетесь свой велосипед доделать, так не проще
VAR_INPUT
IN : Time;
END_VAR

VAR_OUTPUT
HOUR : Int;
MINUTE : Int;
SECOND : Int;
END_VAR

VAR_TEMP
tik : DInt;
END_VAR


BEGIN
#tik := TIME_TO_DINT(#IN);
#tik := #tik / 1000;
#SECOND := DINT_TO_INT(#tik MOD 60);
#tik := #tik / 60;
#MINUTE := DINT_TO_INT(#tik MOD 60);
#tik := #tik / 60;
#HOUR := DINT_TO_INT(#tik MOD 24);

END_FUNCTIONа раз у Вас уже есть разница в дворд, то и эта функция упростится

Антон_Б
22.10.2016, 21:33
Проблема не в вычислении часов минут секунд, а получении правильного секундного тика из ПЛК.

capzap
22.10.2016, 22:21
Проблема не в вычислении часов минут секунд, а получении правильного секундного тика из ПЛК.

так его не берут через задний проход, ну есть у Вас строка ms := TIME_TO_DWORD(TIME()) - tx; этого достаточно чтоб получить отдельные элементы времени, а все эти вычисления больше либо равно тогдда плюсуем единичку, это и есть Ваша ошибка в неточности полученных значений

Антон_Б
22.10.2016, 22:30
Моя проблема в подсчёте времени процесса в секундах от 0 до 3800 секунд.
IF ms >= 1000 THEN
_SEC_PROC := _SEC_PROC + 1;
Но разница по эталонным часам на 300 сек 60 сек. Если я использую ms := TIME_TO_DWORD(TIME()) - tx;
Откуда погрешность не томи

Владимир Ситников
22.10.2016, 22:37
Откуда погрешность не томи
capzap дело говорит.
Весь ваш код нужно удалить и заменить на одну строку с оператором "вычитания".

Антон_Б
22.10.2016, 22:42
А можно привести код (ну недоходит до меня уж простите)

Антон_Б
22.10.2016, 22:58
После изнасилования МОЗГА получил результат


R_trigger( CLK := START_TIMER AND NOT (STOP_TIMER) );


IF (RESET_TIMER) THEN
_SEC_ := 0;
_MIN_ := 0;
_HUR_ := 0;
_SEC_PROC_ := 0;
RESET_TIMER := FALSE;
END_IF


IF ( START_TIMER AND NOT (STOP_TIMER) ) THEN

IF R_trigger.Q = TRUE THEN
tik0 := TIME_TO_UDINT(TIME());
END_IF


tik := TIME_TO_UDINT(TIME()) - tik0;
_SEC_PROC_ := tik;
tik := tik / 1000;
_SEC_ := UDINT_TO_INT(tik MOD 60);
tik := tik / 60;
_MIN_ := UDINT_TO_INT(tik MOD 60);
tik := tik / 60;
_HUR_ := UDINT_TO_INT(tik MOD 24);

END_IF

capzap
23.10.2016, 22:46
А чем ton.ET не угодил-то ?

а есть предвидение когда случиться максимальный предел времени?

Филоненко Владислав
24.10.2016, 10:14
Итак. В ПЛК есть 2-е часов. Системные (на базе кварца 16МГц) и реального времени (32768Гц).
Первые действительно не идеально точные, и такой уход (5 секунд за 10 минут, или 0,8%) не является неисправностью.

Поэтому, если требуется высокая точность задания времени на больших отрезках - используйте часы реального времени.
Если же нужно отмерить 300часов 10мс - то корректируйте системное время по часам реального времени, а лучше не пытайтесь достичь недостижимого. Атомных часов в ПЛК мы не ставим. не помещаются.