PDA

Просмотр полной версии : СПК207. Системное время. Функции "GetDateAndTime" и "SetDateAndTime". Ошибка 5802.



Yarst
16.06.2015, 17:51
Имею устройство СПК207.

Задача состоит в получении и в установке системного времени.

Работаю с функциями "GetDateAndTime" и "SetDateAndTime".

В ходе отладки программы выяснилось, что данные функции возвращают ошибку 5802 (этот код отсутствует в описании возможных кодов ошибок для данных функций) и не работают как должны.

Несколько часов "танцев с бубном" ни к чему не привели. Оказалось:

РЕШЕНИЕ ПРОБЛЕМЫ: После передергивания питания панели СПК207 все заработало идеально.

Zeon
15.02.2017, 08:06
Имею устройство СПК207.

Задача состоит в получении и в установке системного времени.

Работаю с функциями "GetDateAndTime" и "SetDateAndTime".

В ходе отладки программы выяснилось, что данные функции возвращают ошибку 5802 (этот код отсутствует в описании возможных кодов ошибок для данных функций) и не работают как должны.

Несколько часов "танцев с бубном" ни к чему не привели. Оказалось:

РЕШЕНИЕ ПРОБЛЕМЫ: После передергивания питания панели СПК207 все заработало идеально.

Я к этой функции обращаюсь несколько раз в одном проходе программы. И получается при первом обращении она выдает мне 1970 год с нулями. При повторном обращении - системное время, потом снова ноль и потом системное время, цикл может повторяться до бесконечности. У меня сложилось мнение что она слишком медленно работает и не успевает считать время. Ставил цикл while пока функция в .Basy... Панель наглухо зависает. Горит проект, помогите пожалуйста.

Евгений Кислов
15.02.2017, 08:08
Я к этой функции обращаюсь несколько раз в одном проходе программы.

Так делать не стоит (если вы действительно делаете именно это).

Ознакомьтесь с документом СПК. Системное время.

Zeon
15.02.2017, 10:01
Если честно мне немного непонятно, для чего переменную DT рвать на год, месяц день и т.д. и потом опять склеивать в DT??? Почему сразу нельзя её использовать?

Zeon
15.02.2017, 10:03
Закольцевал
FUNCTION strDateTime : STRING
VAR_INPUT
END_VAR
VAR
SysTime:DT;
END_VAR

GDaT(xExecute:=NOT GDaT.xDone);
SysTime:=GDaT.dtDateAndTime;
Sys_Time:=DELETE(DT_TO_STRING(SysTime),3,1);
GDaT(xExecute:= FALSE);
strDateTime:=Sys_Time;

Но не помогло. Все равно один проход нули потом сист время...

Zeon
15.02.2017, 10:05
VAR
SysTime: DT;
END_VAR

Евгений Кислов
15.02.2017, 10:13
Время с выхода .dtDateAndTime можно забирать только когда .xDone=TRUE.
Считывание времени занимает не один цикл, а несколько.



IF GDaT.xDone THEN
SysTime:=GDaT.dtDateAndTime;
END_IF;

Zeon
15.02.2017, 10:15
строку GDaT(xExecute:= FALSE); удалил, определилась положительная динамика2952029520

Zeon
15.02.2017, 10:17
через три пропуска берет верное имя. Мне не понятно почему только он вместо нулей не ставит предыдущее. Попробую сравнивать с нулевым, и если равно брать старое.
Спасибо за вектор в правильном направлении!!!

Евгений Кислов
15.02.2017, 10:18
строку GDaT(xExecute:= FALSE); удалил, определилась положительная динамика2952029520

Рекомендую пример 11.2.5 из документа СПК. Визуализация - он как раз соответствует вашей задаче.

Zeon
15.02.2017, 10:24
Время с выхода .dtDateAndTime можно забирать только когда .xDone=TRUE.
Считывание времени занимает не один цикл, а несколько.



IF GDaT.xDone THEN
SysTime:=GDaT.dtDateAndTime;
END_IF;



Проблема в том что пока IF сработает, у меня произойдет несколько проходов программы, а мне надо несколько 2-4 раза в одном проходе программы вызывать это время. Получается этот проход идет меньше одной секунды и пока .Done<>TRUE , он мне выплевывает ноль.

Евгений Кислов
15.02.2017, 10:35
В пределах одного прохода программы значение времени не изменяется с точки зрения контроллера. Каждый проход обычно занимает 10-20 миллисекунд, у вас время в таблице отображается с точностью до секунд. Вероятно, вам надо в пределах программы в нескольких местах использовать значение времени? Но для этого достаточно считать его один раз за проход.

Я еще раз рекомендую посмотреть пример из документа СПК. Визуализация - возможно, он решит ваши вопросы.

Zeon
15.02.2017, 10:44
Рекомендую пример 11.2.5 из документа СПК. Визуализация - он как раз соответствует вашей задаче.

Ок, Спасибо!
Я с него начинал. Дело в том что там 1 запрос в 2 секунды, а у меня 4 запроса в менее чем 1 сек. Я похоже решил проблему. Буду сравнивать с нулевым временем и присваивать предыдущее значение если оно равно нулю.
Еще раз спасибо! 2 дня пучил мозг, с Вашей помощью дело сдвинулось с мертвой точки!

Zeon
15.02.2017, 11:23
Подскажите пожалуйста как корректно объявить переменную типа DT?
NullDateTime:DT:='DT#1970-00-00-00:00:00';
пишет что константа NullDateTime слишком велика для DT.

Zeon
15.02.2017, 11:23
NullDateTime: DT:=DT#1970-00-00-00:00:00;

Евгений Кислов
15.02.2017, 11:32
Надо так:


nullDateTime: DT:=DT#1970-01-01-00:00:00;

Нулября и нуледельника не существует же.

Но, на самом деле, можно переменную типа DT просто сравнивать с 0 - результат будет тем же.

Zeon
15.02.2017, 11:39
Блин, точно! Спасибо! Глаза замылились совсем очевидных вещей не замечаю...