Просмотр полной версии : Отсчёт времени ПЛК110 М02 с погрешностью 5 сек за 10 мин
Есть свободно исполняемая задача в Кодесис 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 раза. Время между этими вызовами "теряется".
Лучше в "начале" процесса просто сохраните "текущее время", и когда нужна длительность, то просто вычитайте из текущего времени "время старта".
код написан по идиотски. Наличие нескольких вызовов таймеров ни как не влияет, а вот какой то бредовый способ самостоятельно вычислять секунды, минуты и т.д не дает добиться приемливого результата. Ну есть же в оскате функции получения времени из миллисекунд, зачем придумывать "велосипед"
Подскажите Как называется эта функция? Есть ли она для 2ого кодесус?
ИСПОЛЬЗОВАЛ ФУНКЦИЮ ONTIME из OSCAT и офигел от объёма получившегося кода. Он сразу увеличился на 50 кБ.
ИСПОЛЬЗОВАЛ ФУНКЦИЮ ONTIME из OSCAT и офигел от объёма получившегося кода. Он сразу увеличился на 50 кБ.
ну значит Вам так хочется. Не проще полученную разницу преобразовать с помощью DWORD_TO_TIME и уже полученное время в любой момент будет актуальным с начала отсчета,+-погрешность контроллера. А затем уже из полученнного времени вычислять отдельно секунды минуты и т.п.
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 мин и т. п.
да Вы настырный, всё пытаетесь свой велосипед доделать, так не проще
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а раз у Вас уже есть разница в дворд, то и эта функция упростится
Проблема не в вычислении часов минут секунд, а получении правильного секундного тика из ПЛК.
Проблема не в вычислении часов минут секунд, а получении правильного секундного тика из ПЛК.
так его не берут через задний проход, ну есть у Вас строка ms := TIME_TO_DWORD(TIME()) - tx; этого достаточно чтоб получить отдельные элементы времени, а все эти вычисления больше либо равно тогдда плюсуем единичку, это и есть Ваша ошибка в неточности полученных значений
Моя проблема в подсчёте времени процесса в секундах от 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 дело говорит.
Весь ваш код нужно удалить и заменить на одну строку с оператором "вычитания".
А можно привести код (ну недоходит до меня уж простите)
После изнасилования МОЗГА получил результат
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
А чем ton.ET не угодил-то ?
а есть предвидение когда случиться максимальный предел времени?
Филоненко Владислав
24.10.2016, 10:14
Итак. В ПЛК есть 2-е часов. Системные (на базе кварца 16МГц) и реального времени (32768Гц).
Первые действительно не идеально точные, и такой уход (5 секунд за 10 минут, или 0,8%) не является неисправностью.
Поэтому, если требуется высокая точность задания времени на больших отрезках - используйте часы реального времени.
Если же нужно отмерить 300часов 10мс - то корректируйте системное время по часам реального времени, а лучше не пытайтесь достичь недостижимого. Атомных часов в ПЛК мы не ставим. не помещаются.
Powered by vBulletin® Version 4.2.3 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot