 | |
Предыдущие результаты
[quote:952f4cfd99="AlexV"][quote:952f4cfd99="Locky"]А можно и без ONS RES если записать:
XIC Timer.DN ADD Variable Accum Accum
XIO Timer.DN TON 1000 0[/quote:952f4cfd99]
Нельзя! :P
Логическая ошибка, ADD будет выполняться на следующий скан после установки DN таймера.[/quote:952f4cfd99]Ну, расчет суммы задержится на один скан, но работать будет и даже результат сильно не изменится т.к. все отсчеты на этот один скан будут сдвинуты. Строки можно местами поменять, тоже работать будет, и уже в том же скане когда DN установится. :P
В данном примере просто хотел показать что для управления таймером можно обойтись без доп. операторов (ONS & RES) если знать что сброс входного условия таймера сбрасывает его аккумулятор, что в свою очередь приводит к сбросу бита DN.
|
[quote:b8f7578fc8="Locky"]А можно и без ONS RES если записать:
XIC Timer.DN ADD Variable Accum Accum
XIO Timer.DN TON 1000 0[/quote:b8f7578fc8]
Нельзя! :P
Логическая ошибка, ADD будет выполняться на следующий скан после установки DN таймера.
И еще добавлю свои 5 копеек :roll:
Фоновая задача имеет не просто низкий, а САМЫЙ низкий приоритет.
|
[quote:a88c028a49="oldDad"]Немножко сложновато да? Задавайте вопросы, если что.[/quote:a88c028a49]Да нет, ничего сложного, просто действительно забыл что где исполняется и что continuous task (это ведь она кроется под "фоновой пользовательской программой"?)имеет низкий приоритет.
Большое СПАСИБО за столь подробный ответ.
|
Давайте посмотрим на момент, в который выяснится, что таймер в фоновой пользовательской программе досчитал до DN и пора выполнять действия.
Момент, когда таймер отсчитает 1000мс, - это необязательно момент, когда фоновой задаче станет это известно, т.к. время пользовательского таймера течет асинхронно по отношению к актуальному времени, текущему в скане фоновой задачи. Время этого таймера течет параллельно скану фоновой задачи и отсчитывается системным таймером ядра операционной системы.
С высокой вероятностью, то, что таймер готов, выяснится только через некоторое время ([i:95e6ec6eb6]несколько[/i:95e6ec6eb6] единиц миллисекунд или даже десяток миллисекунд) после того, как этот таймер станет готов.
Иначе говоря, факт DN выяснится через время
[b:95e6ec6eb6]T [/b:95e6ec6eb6]= [b:95e6ec6eb6]T[/b:95e6ec6eb6]pre + [b:95e6ec6eb6]Т[/b:95e6ec6eb6]от_начала_скана_мс.
Это время, в принципе, нестабильно, т.к. [b:95e6ec6eb6]Т[/b:95e6ec6eb6]от_начала_скана_мс до обнаружения факта готовности таймера зависит от актуального времени скана, которое колеблется.
Эти флюкутации времени скана зависят, как мы знаем, от количества и характера имеющихся в фоновой задаче зависящих от внешних условий логических операций (actions) и связанных с ними действий (reactions), как от начала скана до момента определения готовности пользовательского таймера, так и после него до конца скана и, затем, снова из конца программы в начало следующего скана, от предшествующей этому моменту в следующем скане логики и связанных с этой логикой действий. Такие флюктуации могут достигать единиц и даже иной раз десятков миллисекунд.
Кроме того, как мы знаем, в многозадачной операционной среде реального времени с прерываниями работают задачи, имеющие более высокий, по отношению к фоновой задаче, приоритет, которые рвут контекст фоновой задачи тогда, когда им нужно, и так надолго, насколько им нужно. Они отбирают у фоновой задачи процессор и возвращают его ей через некоторое (также неопределенное) время, которое им необходимо для обработки, и которое также нестабильно.
В итоге, в такой системе флюктуации момента обнаружения готовности пользовательского таймера, расположенного в фоновой задаче, могут составлять даже десятки миллисекунд. А если рвущая фоновую задачу более приоритетная задача прерывается ещё более приоритетной и.т.п., каждая из которых (непредсказуемо для фоновой задачи) требует процессорного времени, то и еще больше.
Если, к тому же, система построена неоптимальным образом, и более приоритетные задачи загружены сильнее, чем низкоприоритетные, что в корне неверно, или же вообще не используется многозадачность, а всё тупо прописывается в одной фоновой задаче, то система превращается в тормоз ( всё в относительном времени, разумеется), и её динамика будет в несколько раз хуже, чем у оптимизированой многозадачной среды.
Теперь давайте рассмотрим альтернативу.
Имеется очень короткая очень высокоприоритетная задача, запускаемая периодически раз в секунду по системному таймеру ядра, имеющему наивысший приоритет. Эта задача состоит из строчки с оператором ADD, где наращивается интегральный расход. И всё. Логику сброса интегрального расхода в нужной ситуации можно спокойно поместить в фоновую задачу.
Время выполнения такой высокоприоритетной задачи будет доли миллисекунды, это время будет [i:95e6ec6eb6]всегда[/i:95e6ec6eb6] идентично, без вариаций, и она [i:95e6ec6eb6]всегда[/i:95e6ec6eb6] будет запускаться [i:95e6ec6eb6]ровно раз в секунду[/i:95e6ec6eb6], без никаких флюктуаций, по системному таймеру ядра операционной системы. Поэтому точность вычисления интегрального расхода в этом случае будет намного выше.
Немножко сложновато да? Задавайте вопросы, если что.
|
[quote:a1598e710a="oldDad"]При этом Ваш ADD будет считаться в такой задаче принципиально более точно, чем при реализации периодического "интегрирования" пользовательским таймером. Объяснить, почему?[/quote:a1598e710a]Объясните если не сложно. Ведь, насколько я могу помнить, период опроса модулей ввода-вывода не связан с выполнением остальных задач и одно и то же значение будет использовано как при обработке по таймеру, так и в отдельной задаче. Какой нюанс я забыл?
(Без сарказма, действительно интересно где я ошибаюсь.)
|
[quote:ed920ff713="AlexV"]Простейшие вариант: таймер TON, после его DN - ONS RES ADD инструкции[/quote:ed920ff713]А можно и без ONS RES если записать:
XIC Timer.DN ADD Variable Accum Accum
XIO Timer.DN TON 1000 0
|
[quote:d9fdbae6c4="DiabloXan"]mp3corp - Ваша инструкция ADD не выполняется раз в секунду-она выполняется раз в цикл контроллера при выполнении условия GRT.
И все равно из выше написанного не увидел как сделать выполнение любого блока 1 раз в секунду в главной рутине([/quote:d9fdbae6c4]
Почему, таймер 1000 мс, как только он насчитает бит DN станет - 1, далее идет 1 цикл счета и сброс таймера в 0 и так по кругу.
Условие GRT служит для того, чтоб расход не начал считать в обр. сторону, например будет ток <4 ма...
|
[quote:ad091eb44f="DiabloXan"]И все равно из выше написанного не увидел как сделать выполнение любого блока 1 раз в секунду в главной рутине([/quote:ad091eb44f]
Вам же уже написали:
[quote:ad091eb44f="AlexV"]Простейшие вариант:
таймер TON, после его DN - ONS RES ADD инструкции[/quote:ad091eb44f]
Таймер считает в главной программе, и ADD считается только в том цикле, в котором устанавливается DN таймер, т.е. каждую секунду.
Позвольте также поинтересоваться, чем Вам не нравится задача, запускаемая ядром операционной системы контроллера точно раз в секунду? Этот механизм специально придуман именно для того, чтобы реализовывать функции, подлежащие периодическому выполнению. При этом Ваш ADD будет считаться в такой задаче принципиально более точно, чем при реализации периодического "интегрирования" пользовательским таймером. Объяснить, почему?
|
mp3corp - Ваша инструкция ADD не выполняется раз в секунду-она выполняется раз в цикл контроллера при выполнении условия GRT.
И все равно из выше написанного не увидел как сделать выполнение любого блока 1 раз в секунду в главной рутине(
|
Создаешь Routine в программе, потом вызываешь ее с помощью хоть JSR инструкции, хоть FOR для циклического вызова c индексацией.
В отличие от сименса, тут допустима запись вида array1[index1,index2]
Т.е. тут реализовано стандартное структурное процедурное программирование. UserType - стандартные структуры как в классических языках программирования.
|
Предыдущие результаты
Ещё результаты |
|
| |
|