PDA

Просмотр полной версии : Использование переменной TIME



Валера Храмцов
01.07.2008, 13:44
Здравствуйте! Помогите начинающему, пожалуйста.
Есть ПЛК 100 и МВУ8.У. Необходимо, чтобы унифицированный сигнал напряжения, выходящий с МВУ8 менялся во времени, как синусоида (или косинусоида). Я пробовал массивы, цикл FOR - ничего не помогает.
В CoDeSyS есть понятие переменной типа TIME. Возможно, именно это поможет мне. Только я не знаю, как ее грамотно использовать.
Не мог бы кто-нибудь помочь и написать пример цикла с использованием этой переменной? Например, чтобы сигнал менялся с 0 до 10 В в течении 5 секунду, а потом обратно (с 10 до 0 В) в течении 5 секунд и опять - так в течении минуты.
Переменная выхода 1 - out1 типа word.
Огромное спасибо.

Игорь Петров
01.07.2008, 16:14
См. манул по CoDeSys: Библиотеки CoDeSys > Библиотека UTIL.lib > Генераторы сигналов > функциональный блок GEN. Там есть пример FBD.

Валера Храмцов
02.07.2008, 12:26
Спасибо большое!

Валера Храмцов
02.07.2008, 16:04
И все-таки, наверняка есть смысл в наличии переменной типа TIME.
В описании к CoDeSyS нет примера ее применения. Может быть, кто-нибудь подскажет, как это делается? Или приведет какой-нибудь пример?
Буду очень благодарен.

Игорь Петров
03.07.2008, 11:51
И все-таки, наверняка есть смысл в наличии переменной типа TIME.
В описании к CoDeSyS нет примера ее применения...
Переменная типа TIME применяется в МЭКовсих блоках очень широко. В мануале описано море блоков, где используется переменные типа TIME. Еще примеры см. тут. (http://www.prolog-plc.ru/docs/TimeExperience.pdf)

В МЭК существуют несколько разных типов переменных для времени/даты/длительности. Для человека, при напряжении мозга, будет ясно как проводить разные операции с такими данными: как их вычитать, складывать, умножать, сравнивать и др. Например, понятно, что две даты можно сравнивать, к дате можно прибавить длительность, но не другую дату. Вычесть время дня из времени дня можно, но при этом получиться длительность.
Поскольку операции '+', '-' и др. полиморфны, то компилятор должен знать какой код генерировать с разными типами переменных. Отсюда возникает нужда иметь специальный тип для длительности (просто некий интервал времени, с точностью до мс) – это TIME, время дня TIME_OF_DAY (от 0 до 24 часов), дата DATA (календарная), временной штамп DATE_AND_TIME (уникальная метка времени). Ничего хитрого тут нет. Все типы данных (такие как BOOL, INT, REAL, STRING и др.) нужны для правильной обработки выражаемых ими физических сущностей. Временные типы ничем особенным тут не выделяются. Если мне надо задать 100 миллисекунд, то лучше использовать для этого TIME, чем просто целое число 100. В этом случае я дам компилятору возможность контроля, возможность красиво отображать значение в отладчике и визуализации (в секундах) и др.

Исторически в некоторых МЭК системах программирования начального уровня их изготовители сразу не додумались, как реализовать требуемые по стандарту МЭК функциональные блоки таймеров (см. TON, TOF). Главная сложность в том, что экземпляров этих блоков допускается создавать не ограничено много... Для упрощения, некоторые просто ограничили допустимое число используемых в программе таймеров. Оригинально поступили разработчики Изографа (ранних версий). Они изобрели так называемые 'таймерные переменные'. Объявил такую переменную и она сама 'пошла' – как часы. Засекая по ней время, можно программно измудриться соорудить нормальный таймер. Потом пришлось к этим таймерным перемененным придумывать сервисные функции... Версия 5 этой системы наконец то доросла до нормальной стандартной МЭК реализации типов данных.

В рез. получается если человек имел опыт использования Изографа, то ему трудно понять как работают стандартные таймеры МЭК. В CoDeSys все сделано четко по стандарту. Если нужно меняющееся время, то в программу ставим экземпляр функционального блока 'таймер' и на его выходе получаем то, что нужно. Результат можно хранить в переменных типа TIME, сравнивать, вычитать и др. Реально тип TIME ничем не отличается от остальных типов данных. Меняться сами собой такие переменные не должны, это кошмар и глупость.

Валера Храмцов
03.07.2008, 16:46
Спасибо за сочинение в духе "Войны и мира".

Игорь Петров
07.07.2008, 10:27
Спасибо за сочинение в духе "Войны и мира".

:) Эпилог: есть еще функция TIME(), которая возвращает системное время…

Роман26
12.02.2009, 13:26
А у меня функция TIME() возвращает значение - T#0ms.
Мучаюсь уже неделю, не могу присвоить глобальной переменной:
DDateTime: DATE_AND_TIME;
значение текущей даты и времени в ПЛК. У меня ОВЕН 100.
Спасибо.

kucherik
13.02.2009, 09:48
:) Эпилог: есть еще функция TIME(), которая возвращает системное время…

Я пока пошел более простым путем, задал программу которая запускается 1 раз в пол секунды и перекидывает флаг, если придется еще что-то считать наверно придется идти через функции времени

Николаев Андрей
13.02.2009, 10:03
Мне кажется как то все сложно...
А нельзя просто использовать круговую синусоиду для Вашей задачи: y:=a*SIN(6.28*t*f)
Или библиотека Util.lib. Блок GEN.
В нем есть переменная период, которая как раз в формате времени.
Попробуйте блок подключить и посмотреть как происходит работа при изменении значения входных переменных блока на визуализации. Все на свои места станет.

Используйте как отдельный блок, вызываемый по времени и все.

kucherik
15.02.2009, 17:53
Вот пример в CFC использования функции time для счета времени работы агрегата, может кому пригодиться

Kirill
16.02.2009, 10:55
Вот пример в CFC использования функции time для счета времени работы агрегата, может кому пригодиться

Идентификатор time в кодесис уже зарезервирован. Назовите хотя-бы time1.

kucherik
17.02.2009, 15:43
так его же и использую (time), только если человек будет работать с ним постоянно, придется учесть переход через переполнение, а это так пример для короткой засечки времени

Филоненко Владислав
17.02.2009, 19:35
Если вычитать 2 беззнаковых числа - разница между ними не зависит от переполнения. (маленкий программистский хитрост)

kucherik
18.02.2009, 09:17
тогда более всего подойдет тип
UDINT: от 0 до 4294967295 32 Бит

vasylye
05.12.2015, 20:16
:) Эпилог: есть еще функция TIME(), которая возвращает системное время…

Кто бы из знающих подсказал:

Функция ведет отсчет, базируясь на данных RTC ?
Хотелось бы знать точность этого времени.

Потому что у меня такая проблема - беру время функцией GetTimeEx - на основе его формирую секундные и минутные стробы
Программа работает на 16-ти ПЛК - половина из них ПЛК150, половина ПЛК110

На 150-ых - все нормально, а на 110ых - иногда в минуте бывает 59 секунд (в результате того, что поле .Second обновляется как то не равномерно)
За сутки таких минут набирается около 50-ти



VAR_OUTPUT
sec_pulse : BOOL := FALSE;
min_pulse : BOOL := FALSE;
END_VAR
VAR
clock : CurTimeEx;
datetime : SystemTimeDate;
uptime : SysTime64;

second_counter : BYTE := 0;
second_copy : BYTE := 0;

minute_counter : BYTE := 0;
hour_counter : BYTE := 0;

prew_second : INT;
prew_minute : INT;

END_VAR
VAR CONSTANT
nulldt: SystemTimeDate; (*нужна для обнуления параметров*)
END_VAR

...
datetime := nulldt;
clock(SystemTime := uptime, TimeDate := datetime);
sec_pulse := datetime.Second <> prew_second;
IF sec_pulse THEN
prew_second := datetime.Second;
END_IF
min_pulse := datetime.Minute <> prew_minute;
IF min_pulse THEN
prew_minute := datetime.Minute;
END_IF

(* Счет импульсов *)
IF sec_pulse THEN
second_counter := second_counter + 1;
END_IF
IF min_pulse THEN
second_copy := second_counter; (* Вот здесь бывает 60 сек. а иногда - 59 сек. *)
(* Также в первую минуту это значение может быть не корректно, не обращать внимание *)
second_counter := 0;
END_IF



Может кто посоветует, Как формировать секундные и минутные стробы с максимально возможной точностью, и чтобы не было потерь секунд.
Уход за сутки +/- 5 минут удовлетворяет, но не больше (((((
К тому же вижу, что часы на самом ПЛК идут достаточно точно.
Цикл плк 15 мс, за это время програма формирования импульсов вызывается от 20 до 120 раз в секунду (понимаю ,что когда она вызывается 20 раз - плк немножко перегружен, но это бывает примерно раз в минуту), но по идее, этого должно быть достаточно, чтобы поймать изменение времени на 1 секунду

Валенок
05.12.2015, 21:25
Для этих стробов syslibtime не нужен
sec_pulse,min_pulse : f_trig;
sec : byte;

sec_pulse(CLK := (time_to_dword(time()) mod 1000) > 500);
sec := (sec + sel(sec_pulse.q,0,1)) mod 60;
min_pulse(CLK := sec = 0);

Точней - ни как.

vasylye
07.12.2015, 11:27
Спасибо, выручили! )))

Grampus
12.01.2017, 09:27
Мне кажется как то все сложно...
А нельзя просто использовать круговую синусоиду для Вашей задачи: y:=a*SIN(6.28*t*f)
Или библиотека Util.lib. Блок GEN.
В нем есть переменная период, которая как раз в формате времени.
Попробуйте блок подключить и посмотреть как происходит работа при изменении значения входных переменных блока на визуализации. Все на свои места станет.

Используйте как отдельный блок, вызываемый по времени и все.



А как обозначить t и f. как программа их узнает? это наверно время и частота!? или нет?

Александр_Скурихин
26.08.2021, 09:34
Всем здравствуйте, подскажите как мне найти WORD_TO_TIME или DWORD_TO_TIME их просто напросто нет CDS v3.5 может они в какой-то особой библиотеке?! Хочу передавать значения в панели оператора и использовать их в таймере

Mr Helper
26.08.2021, 09:48
Они являются стандартными операторами конверсии - их можно найти в Ассистенте ввода (F2), также с версии SP14 используют преобразователь вида: TO_TIME (Не нужно писать тип входной переменной)