Показано с 1 по 10 из 103

Тема: ПЛК 63 в примерах

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1
    Пользователь
    Регистрация
    18.07.2008
    Адрес
    Владимир
    Сообщений
    113

    По умолчанию Время - позиционированние по времени - разное полезное

    Все что будет изложено далее опирается на стандартную библиотеку (Standart.Lib)
    Главный элемент для измерения времени это RTC, здесь же приведен пример функционального блока который измеряет время нахождения оборудования в включенном состоянии (OnTime). В некоторых моих программах приведенных на форуме видно что когда я делаю измерение времени без RTC это возможно только используя фиксированный во времени процесс который менял свое состояние каждые полсекунды. Обращаю внимание на тип используемых переменных для различных задач. Для измерения времени лучше всего подходит DATE_AND_TIME (сокр. DT) с шагом значений в одну секунду. Для оценки времени работы оборудования более чем достаточно, а в случае сервоприводов и других процессов надо бы использовать TIME уже с шагом в милисекунды, но и тут есть подводный камень (Максимальное значение для типа TIME : 49d17h2m47s295ms (4194967295 ms)) соответственно надо оборудование сбрасывать или начинать отсчет заново по достижении определенного значения.
    И так функциональный блок OnTime просто состоит всего из двух последовательных элементов RTC и MOVE (использовал EN/ENO из-за простоты в данном конкретном случае), что-то тут комментировать кажется излишним, все очень просто. Чуть сложнее его OnOffTime, он еще измеряет время простоя оборудования. Можно путем внешних операций даже выводить процент использования и тому подобное. Нужен ли тут вход для сброса накопленных значений не значений не знаю, сделать его просто добавится только еще один элемент и логика для сброса и блокировки. С процессами длиннее нескольких секунд понятно, теперь надо вернуться к проблеме измерения миллисекундных процессов. А именно к вопросу вычисления текущего положения по времени работы трехточечных сервоприводов. Проблема заключается в том что хочется измерять с миллисекундной точностью, но без использования дополнительных библиотек. И выход в данном случае нестандартное использование таймера TON.
    В данном случае я использую выход таймера (функциональный блок OnTimeTON) для получения текущих значений времени с момента отсчета. Здесь была определенная сложность чтобы выполнить этот код без использования EN/ENO, как видно можно и тут выкрутиться. В момент снятия сигнала срабатывает триггер по обратному фронту, он затягивает отключение таймера, на один такт, и в этот момент снимаем текущее показания времени. Важный момент, правильность работы возможна только за два такта программы, это надо учитывать при использовании данного функционального блока. Далее стоит ограничитель на 24 часа (не правило можно и месяц поставить кому как удобно но меньше 50 дней), и при его использовании погрешность на один такт в сутки, гарантировано перекрывается погрешностью хода часов, кому важно сделать это точно, надо как уже писалось надо выставить фиксированное время цикла запуска и это время вычесть из 24 часов. Например запуск один раз в секунду тогда время сброса соответственно 23 часа 59 минут 59 секунд . Ну и вход RST для сброса текущих показаний.
    Теперь поговорим об учете положения для трехточечного сервопривода. Сам тип переменных TIME не дает возможности работы с отрицательными значениями, хотя они хранятся в памяти как DWORD что дает возможность к абстрактной работе с ними (например при конвертации). Как же быть, например видно из функционального блока OnOffTime два выхода, в данном случае можно говорить о двухточечном управлении. Но тут нет ограничения в случае простоя двухточечного регулятора. следовательно его можно использовать ограничитель либо встроенным в блок или внешним в программе. Законный вопрос как же это можно реализовать, если сам тип переменной не имеет отрицательных значений. Ответ лежит на поверхности переконвертировать в знаковую целочисленную переменную, но это влечет за собой второй вопрос, а как быть с отрицательными значениями. Или надо отказаться от текущего вывода текущего положения (сделать например процентный вывод) или работать только в положительной зоне (то есть сдвинуться в середину допустимых значений и считать это положение нулевой точной). По мне более предпочтительно работать с целочисленной переменной и оставить ее значения в этом виде, конвертация сопровождается переводом миллисекундные значения в целочисленные. И данный тип уже более удобен для дальнейшей обработки. Он уже не будет привязан к значениям времени и его удобней отображать и видоизменять в программе.
    Здесь пришлось реализовать похожий на счетчик алгоритм управления (TimePositionTON). Причем позволяется одновременная подача сигнала на оба входа, ограничение осталось тоже минимум два такта программы сигнал не должен вернутся для корректной обработки. Блокировки от этого нет, не хочется сильно усложнять код. В момент снятия сигнала производится подведение так сказать итога, так же это происходит в случае достижения ограничителя. Из особенностей хотелось бы подчеркнуть возможность асимметричного использования. Два входа для времени TimeUp и TimeDw, они могут быть указаны произвольно, напоминают ограничитель у счетчика импульсов. В данном блоке есть защита от одновременной подачи сигнала на оба входа UP и DW, все ничего до момента что это не будет висеть длиннее чем время в таймере (25 часов) было желание завести выхода с таймеров на сброс в данном случае, но не хотелось снижать универсальность функционального блока, но сложности обычно начинаются там где не ждешь, а что бы произошло если бы сигнал пропал одновременно, тоже самое, записалась бы позиция выполняемая последней. Так же нет проверки на то что TimeUp>TimeDw, но она и не нужна %). Ограничение типовое, для этого типа подхода, между импульсами в любое положение должна пройти пауза в два такта программы. Это ограничение можно избежать если использовать уже приведенный выше функциональный блок OnTimeTON, для учета работы в любую сторону, тогда смена направления пройдет без пробелов.
    Но в данном блоке есть очень большая неприятная вещь она происходит когда программа доходит до ограничителя, тут надо подробно разобрать как работает таймер. В момент времени когда приходит сигнал работы, начинается отсчет времени с нулевого положения. Соответственно в момент времени когда приходит сигнал выключено, надо еще раз считать текущее положение с таймера, так как если выключим сразу то выход времени с таймера будет равен нулю. Тогда логично получается что не требуется еще один проход в случае когда срабатывает ограничитель, и как только отходим в противоположном направлении, надо снять сигнал Stop. Как видно данный блок разрешает небольшой заход за величину ограничения, определяемую скоростью выполнения программы.
    Ну вот сложный вариант изложен, наверно чтобы больше показать возможности «акробатики» кода (Функциональные блоки OnTimeTON и TimePositionTON воспринимать как «шутку»). А между тем есть более изящное решение. Но для этого потребуется знать чему была равна длительность предыдущего такта программы (в качестве доп. материала см. TaktMeter) и очень будет хорошо если вы используете синхронный (запускаемый через равные промежутки времени) программный процесс. В итоге зная такт можно с высокой точностью работать уже с временными значениями. Написанный функциональный блок T3Position не имеет явных недостатков (если только сигнал не будет висеть больше месяца ), ему не требуются паузы между сигналами, можно подавать сигнал одновременно на два входа, можно сразу после снятия сигнала, в следующем шаге заново подать сигнал. Тут можно выделить три зоны. Первая, здесь происходит вычисление времени исполнения программы, засечка по времени, в случае достижения ограничения, приращение останавливается. Вторая, формируются внутренние сигналы управления и вычисляется текущее положение. Третья, здесь проверяются ограничители. Надеюсь дополнительные комментарии тут излишни. Если что не понятно, спрашивайте, попробую растолковать альтернативно.

    Дополнительный комментарий: Что полезного можно написать используя данные функциональные блоки. Например приложение которое будет знать приблизительное положение заслонки, на основе его можно уже улучшить управляемость объекта. Можно высчитать передаточный коэффициент, по мне это то что не хватает в стандартных библиотеках. Кому интересно прилагается блок измеритель длительности программного такта TaktMeter разбит на три последовательных действия для простоты понимания. Еще один важный момент, для понимания сути происходящего процесса надо знать что при импульсе например одна секунда время работы будет например 0.99 секунды а при длительности 2 секунды уже 1.99, то есть определенное время уходит на срабатывание реле, отсюда и накапливается ошибка позиционирования, и для этого я рекомендую производить инициализацию положения например раз в сутки. В моих задачах это очень хорошо работает и проблем пока не было. Порядок обработки данных в функциональных блоках в соответствии с потоком данных, правильно написанный код не требует дополнительного указания порядка обработки. Как в свое время меня учили, например: правильная программа на С/Pascal не требует использования goto и полученный код будет «красивым». Пишите правильно %). А мне пришлось помучатся чтобы получилось красиво и без использования EN/ENO где можно, оно того стоило.
    Вложения Вложения
    Если человек доверяет судъбе, то она ведет его по жизни, иначе тащит %)

Похожие темы

  1. ошибки в примерах ...
    от Дмитрий Артюховский в разделе ПЛК1хх
    Ответов: 21
    Последнее сообщение: 25.01.2009, 21:17

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •