Здравствуйте! Подскажите, пожалуйста, как реализовать таймер на языке ST.
Posted by AdAstra Technical Support (Участник № / Member № 4) on :
Можно любым способом ввести в ST-программу значение текущего времени (например, через канал TIME, связанный с системной переменной @t_Set_Date), делать засечки в глобальных переменных и затем сравнивать эти засечки с текущим временем.
Posted by Grigorovskih (Участник № / Member № 1915) on :
Здравствуйте Господа
Необходимо сделать таймер в миллисекундах, но к сожалению все сводится к циклу пересчета канала, а он привязан к циклу работы монитора, а цикл работы монитора плавает. Это проверено с использованием системных и диагностических переменных. Поэтому вопрос как воспользоваться каналом с циклом пресчета FAST, задав для этого цикла разрешение 100 мс. Т.е. использовать его (канал с циклом FAST) как эталонный таймер, а в нем сделать счетчик (вызов шаблона программы) который будет считать количество его (канала) пересчетов и сбрасываться по внешнему аргументу, подсчитав количество пересчетов с разрешением в 100 мс Будет вообще это работать или будет плавать? Или посоветуйте как реализовать счетчик с разрешением 100 мс но без "плавания". Разрешение секунда не подходит.
Posted by AdAstra Technical Support (Участник № / Member № 4) on :
Продолжительность цикла в потоке FAST задается ключом в файле конфигурирования запуска узла.
"FSTLOOP=<fstLoop> – время цикла FAST, мс (@Calc_Loop OUTPUT с Параметр=9); "
Однако, следует учитывать, что конечная точность отработки таймерной функции будет зависеть от синхронности всех входящих параметров, включая и "сброс по внешнему аргументу".
Posted by Grigorovskih (Участник № / Member № 1915) on :
Провели испытания использовав для этих каналов цикл fast, установив для него через переменную CalcLoop заданное значение в мс. По результатам получаем отставание на 10% от времени в секундах самой операционной системы. Т.е. на 100 с ОС получаем 92 с "расчетных", полученных в этом канале путем подсчета количества циклов отработки самого этого канала (шаблон программы один FBD блок сбрасывающий сам себя при достижении заданного значения), т.е. без использования аргумента с внешними привязками для сброса. Так же в настройках узла во вкладке "дополнительно/приоритеты потоков" для этого цикла устанавливали TimeCritical, но отставание так и осталось, т.е. точность не изменилась. Может есть еще способы повысить точность или разрешающую способность при такой реализации таймера?
Posted by AdAstra Technical Support (Участник № / Member № 4) on :
Специально провели 2 эксперимента с одним и тем же проектом с потоком FAST (период 100 мс) на двух ПК: Windows XP SP3 с CPU Intel(R) Core(TM)2 Duo 2.66GHz и Windows 7 SP1 с CPU Intel(R) Core(TM) i5 3/20 GHz
В первом случае 6000 циклов FAST были выполнены за 680-690 сек. Во втором за 600 сек. (с точностью измерения 1 сек.). Причина различий - величина и стабильность кванта времени, выделяемого задачам приложения.
В первом случае - 15-16 мс, во втором - 10мс.
Видимо, под Windows CE реальная точность может быть еще хуже. Это определяется возможностями ОС и аппаратуры. Присвоение какому-либо потоку уровня приоритета TimeCritical осуществляется только "по разрешению" ОС. Де-факто ОС эти возможности фактически исключает.
Posted by Nico (Участник № / Member № 5342) on :
1. в TM6 есть FBD блок выдающий интервал в ms между вызовами программы. его и надо суммировать на каждом цикле расхождение будет гораздо меньше
Posted by AdAstra Technical Support (Участник № / Member № 4) on :
Перепроверено решение, предлагаемое NICO. На ПК с Windows XP точность стала вдвое выше.
Posted by Grigorovskih (Участник № / Member № 1915) on :
quote:Отправитель / Originally posted by Nico: 1. в TM6 есть FBD блок выдающий интервал в ms между вызовами программы. его и надо суммировать на каждом цикле расхождение будет гораздо меньше
Я использую FBD который является счетчиком, счет происходит с разрешением (разрешающей способностью) равным периоду пересчета этого канала (время пересчета), таким образом получаем генерацию, а Ваш способ этого уже не реализует, а может только измерить время м/у событиями (сигналами). Проверка показала что при измерении времени этим способом на 1000 секунд разница 5с всего, т.е. достаточно точно. Но повторюсь, это не уже не генератор в реальном времени (таймер). Ну да ладно, все было бы хорошо, но вот этот блок выдает всегда "1000" у канала который FAST, не смотря на то какое время задано для этого FAST-а, у Канала с обычным типом цикла пересчета этот FBD работает и показывает время
Posted by Grigorovskih (Участник № / Member № 1915) on :
Уважаемая Техподдержка проверьте у себя пожалуйста с каналом FAST, этот блок выдает всегда значение "1000"
Posted by AdAstra Technical Support (Участник № / Member № 4) on :
Не очень понятна методика тестирования.
Пришлите, пожалуйста, Ваш тестовый проект в службу техподдержки с комментариями, где и как наблюдать.
Posted by Grigorovskih (Участник № / Member № 1915) on :
Методика такая: канал с циклом пресчета fAST, с привязанной к нему программой (вызывается шаблон)где есть один единственный FBD блок - "TSTEP", его выходное значение ч/з аргумент программы привязан к реальному значению канала. Запускаем и должны увидеть в реальном значении канала время пересчета этого канала. Так вот не смотря на то что для цикла FAST задано время X мс в реальном значении канала всегда 1000. Т.е. якобы время обновления канала равно X ( любое целое, например 10, 50, 100 150 и т.п.) Но если установить цикл пересчета этого канала равный CALC или другой F1-F3 то мы увидим что реальное значение канала покажет значение в мс равное заданному времени цикла в настройках узла. Цикл FAST устанавливается ч/з диагностическую переменную CALCLOOP с параметром - 9 тип OUTPUT. Значение этого цикла проверяется той же переменной только INPUT, и оно соответствует заданному.
Posted by Бычков Константин (Участник № / Member № 7036) on :
Я новичок в Тм. Не могу реализовать такую программу на ST что бы определять идет увеличение сигнала или его уменьшение. Хотел сделать так что бы A:=вход_сиг потом таймер формирует задержку B:=вход_сиг И сравнить их. Как мне это сделать?
Posted by Бычков Константин (Участник № / Member № 7036) on :
Опишите пожалуйста подробнее как в ST запросить системное время.(например, через канал TIME, связанный с системной переменной @t_Set_Date) как это сделать?
Posted by AdAstra Technical Support (Участник № / Member № 4) on :
Есть штатная функция у каналов Float - атрибут ТЕНДЕНЦИЯ (6) (см. "Каналы и системные переменные/Общие атрибуты каналов/Атрибуты каналов, отображаемые профайлером"). По этому атрибуту можно оценить мгновенное изменение значения канала.
При наличии в спектре сигнала естественных шумов, возможно, определение тенденции следовало бы осуществлять после очистки сигнала от шумов (в том числе и штатными средствами, имеющимися в функциях первичной обработки каналов FLOAT - см. документацию) или введения метрологически оправданного округления сигнала.
В языке ST нет таймерных функций. Для таких задач придется использовать аргумент программы, в который тем или иным способом передается текущее время (например, через канал TIME, связанный с системной переменной @t_Set_Date).
Возможно, эту задачу более удобно решать на языке FBD, где есть и таймерные функции и функции сравнения.
Posted by Бычков Константин (Участник № / Member № 7036) on :
Как связать канал с системной переменной @t_Set_Date? Я новичок в ТМ
Posted by AdAstra Technical Support (Участник № / Member № 4) on :
Создайте в узле канал класса TIME. Создайте в слое "Источники/Приемники/Диагностика и сервис/Системные/" компонент @t_Set_Date и D&D залинкуйте этот компонент с каналом TIME.