PDA

Просмотр полной версии : Глюки таймеров?



superMAX
02.08.2009, 12:30
На объекте сложилась крайне сложная ситуация - постоянные сбои оборудования - программа время от времени не видит сработок датчиков. Никакой закономерности в наступлении подобных ослеплений не наблюдается. В шкафу ПЛК100+МДВВ, сигналы получаем и воздействия выдаем через МДВВ. 115200, 8, четность, экран. Силовая коммутация расположена здесь же, но ошибки связи крайне редки - порядка одной на 10000 опросов. Естественно, при ошибке связи цикл работы пропускается. ST. Цикл программы, как правило, не превышает 5 мс. Используется встроенная визуализация, но компьютер к ПЛК, как правило, не подключен. Логирования нет.

Все работало удовлетворительно до тех пор, пока заказчик не начал увеличивать скорость работы конвейера. Употреблялось даже слово "идеально". Текущее состояние дел именуется "не работает и не работало никогда"...

Так как этот участок конвейера работает автоматически (когда работает), - для диагностики неисправностей используются таймеры. Все двигатели включаются на время, в течение которого ожидается сработка соответствующего датчика. Если событие не наступило - диагностируется ошибка, работа механизмов блокируется и включается звонок, числом звонков в серии указывающий место сбоя. "Идеально" было, когда механизмы (и, соответственно, таймеры) включались поочередно - этот участок проезжало только одно изделие. После ускорения на этом участке конвейера одновременно находятся несколько изделий (и одновременно включены несколько таймеров TON) - тут-то и начались огромные проблемы (и изрядные финансовые убытки). Ложных сработок нет - есть пропуски сигналов, причем с разных датчиков (хотя вероятности пропуска сигналов неодинаковы для разных датчиков, - так, некоторые в пропуске сработок замечены не были).

В течение трех суток были предприняты все мыслимые и немыслимые меры обеспечения корректности работы оборудования - экранирование (раньше, как выяснилось, работало с неподключенными экранами датчиков - и ничего), замена БП (Овен. Один канал выдавал 18 В вместо положенных 24), МДВВ (производитель примененных в них реле заявляет 50000 сработок, а один из выходов отработал 60000) и ПЛК; были убраны китайские твердотельные реле, коммутировавшие пускатели; многократно проверялись датчики (транзисторные npn оптические на отражение от объекта, Китай. Особо проверялись на ложное размыкание при работе на движущийся объект с неровной поверхностью); заменялись пускатели, и т.д., и т.п. Программа перекраивалась два десятка раз, но спорадические сбои повторяются с дивной регулярностью (90% которых происходят во время отсутствия программиста на объекте).

Наконец была выявлена пренеприятная особенность - одновременная активность нескольких таймеров значительно увеличивает вероятность появления ошибок. Так, при "идеальной" работе единовременно работало не более трех таймеров, а после разгона конвейера одновременно могут быть включены до 7-8 TON, расположенных в массиве.

Исключение из программы двух таймеров принесло значительное облегчение, однако, стоило мне после вторых бессонных суток покинуть объект, - скорость задрали еще выше, и глюки посыпались вновь.

Кажется, где-то я натыкался на обещание вроде "использование множества таймеров приводит к милым сюрпризам", но никак не могу найти, где именно. Кто-нибудь может подтвердить проблемы при одновременной работе множества таймеров?

P.S. Завтра утром - момент истины. Если работа не будет налажена - меня со всем оборудованием Овен отправят в топку.

P.P.S. Запуск таймеров выглядит так:

IF front(guillotineLoaded) AND NOT guillotineOn AND NOT acceleratorOn THEN
guillotineOn := start(which := tmGuillotine);
acceleratorOn := start(tmAccel);
start(tmWndToTranspDown);
END_IF;

Внутри функции start:

tmTONs[which](in := FALSE, pt := WORD_TO_TIME(c + tmDelays[which]));
tmTONs[which](in := TRUE);

Останов так:

IF front(distributorLoaded) AND transporterOn THEN
transporterOn := stop(tmTransporter);
positionTransporter(FALSE);
END_IF;

Внутри функции stop:

tmTONs[which].IN := FALSE;

Хммм... ФБ не вызывается при останове, но ведь раньше все работало?! Да и сейчас, как правило, работает. Часами и даже сменами. А вызываются все ФБ в каждом цикле проги в массиве:

(* Даем процессорное время таймерам оборудования и заполняем столбец обратного отсчета в массиве статистики *)
FOR i := 1 TO TIMERS_UP_BOUND DO
tmTONs[i]();
tmStat[TIMERS_CURRENT, i] := TIME_TO_WORD(tmTONs[i].PT - tmTONs[i].ET);
IF tmTONs[i].ET = t#0ms THEN
tmStat[TIMERS_CURRENT, i] := 0;
END_IF;
END_FOR;

Проверка таймаута:

IF acceleratorOn AND tmTONs[tmAccel].Q THEN
acceleratorOn := err(_ERR_ACCELERATOR_TIMEOUT_);
END_IF;

Функция err устанавливает переменную номера ошибки, при ненулевом значении которой программа просто не вызывается.

Николаев Андрей
02.08.2009, 13:12
Какая прошивка контроллера?
Выложите программу с точным наименованием контроллера, версией прошивки и Target.

Вы убедились, что вопросов к обмену нет? То есть если данные МДВВ передает и принимает - то делает он это всегда? 1 из 10 000 не считается...

Сами по себе таймеры вряд ли глючат. 10 лет не глючили, и вот начали...
Вопрос к методу вызова таймеов. Не забываете сбрасывать таймеры при необходимости? Смотрели ли действительный цикл в модуле Статистика? Возможно стоит увеличить\уменьшить параметр MinCycleLen (PLC Configurations - настройки модуля самого контроллера).

superMAX
02.08.2009, 16:51
МДВВ стоял 1.07, сейчас заменен на 1.09.
На предыдущем ПЛК К-М была 2.02.8, сейчас ПЛК Р-М (или Р-Л, - заказчик умудрился прикупить три разных модели, блин) 2.10.7, ядро перешито. На последнем припаян резистор 9К между ногами 10 и 12 микрухи 485 порта. Единственное, что я сегодня припомнил - на ноуте таргет остался, по всей видимости, старый, а в цехе я с него перепрограммировал контроллер, после чего перестала работать кнопка Старт и индикатор работы.
При переходе на новую версию прошивки модуль статистики удалялся и добавлялся заново, а в целом конфиг экспортировался (или он даже не слетал - точно не помню). В нем приличный объем настроек, поэтому на создание его заново времени нет.
В визу сделана индикация числа ошибок и времени цикла - озвученные цифры из нее. Да! Однажды я увидел максимальное время цикла около 500 мс и был сильно удивлен, но это произошло, кажется, когда я подключал ноут и было какое-то взаимодействие ПЛК и КоДеСис...
КоДеСис 2.3.9.9.
Проект прилагается. Сырой, правда, и имеет следы многочисленных правок. Бибка ваша, но, так как бета, я от греха подальше сделал код доступным для отладки, а то в поставляемой библиотеке он запаролен. Но так ниче вроде, работает.
Да! Сбоит, собственно, программа stage2. Ее вызывает main, если значение константы PRG = 1 (что, собственно, задается EasyWorkPLC).

А как вы предлагаете убедиться в корректности работы МДВВ? Разве что завести обратную связь через ПЛК и смотреть, отработал ли выход МДВВ?..
Хмм... Действительно, MinCycleLength стоит 1 мс... MaxCycleLength = 2000... Нездоровая фигня, но в визуализации цикл постоянно около 3-5 мс, и ничего, работает.

Да, обращаю Ваше внимание, что сбои случаются редко - может нормально работать 6 часов непрерывно, а могут следовать один за другим. Основные подозрения, что большое число одновременно запущенных таймеров съедают слишком много времени цикла либо получается дольная/кратная чему-то частота наступления событий. Скорость прихода продукции колеблется в диапазоне от прибл. 1 до 2,5 событий front(guillotineLoaded) в минуту (сработка датчика, подключенного к первому входу МДВВ); остальные приводы конвейера, управляемые stage2, работают с фиксированной скоростью (но наблюдается незначительный разброс интервалов движения продукции из-за проскальзывания ее на конвейере).
Сбоят главным образом датчики, подключенные к 3-5 входам МДВВ: transporter1, transporterTop, transporterBottom. Время достижения транспортером положения от transporterBottom до transporterTop (и обратно, соответственно) обычно составляет около 500 мс. В текущей редакции проги он совершает несколько движений туда-обратно, пока не поймает событие Top, но зачастую, к сожалению, он его не видит...

В конфигурации системных событий задействованы события Start и Stop - исполняются POU onStart и onStop соответственно (слетают при смене платформы).
Используется шаблон МДВВ - только вчера заметил, что на форуме его использовать... не рекомендуют, что меня несколько удивило. В чем причина подобных советов?

Евгений_Томск
02.08.2009, 18:57
Может чем-то поможет , но сложилось ощущение , для того , чтобы все таймеры тикали , каждый из них надо вызывать хотя бы один раз в каждом цикле , пусть даже вхолостую ( без принятия решения ).

Евгений_Томск
02.08.2009, 19:05
Как вариант ,для ускорения обмена данными, можно попробовать МДВВ заменить на ПЛК , и информацию со входов передавать на главный ПЛК через сетевые переменные по TCP/IP.

Sniper007
03.08.2009, 11:08
У меня была подобная фигня. В одном участке программы тоже вызывалось много таймеров и все начинало висеть - ИП-320 теряла связь, входы МДВВ тормозили.
По совету Андрея Малышева я в Task Configuration выставил время цикла 10мс. Все стало работать нормально...
Вам может быть нужно будет поставить побольше

Филоненко Владислав
03.08.2009, 11:11
Может чем-то поможет , но сложилось ощущение , для того , чтобы все таймеры тикали , каждый из них надо вызывать хотя бы один раз в каждом цикле , пусть даже вхолостую ( без принятия решения ).

1. Именно так. Все таймеры запускать каждый цикл. Иначе будут проблемы.
2. Каково требуемое время реакции на события? Если на уровне времени цикла - работать не будет однозначно. Надо иметь 3-4-х кратный запас. Нарисуйте временную диаграмму вклучения/срабатывания всех таймеров в самом тяж. случае.

Малышев Олег
03.08.2009, 19:44
КЛЮЧЕВАЯ проблема:
Ложных сработок нет - есть пропуски сигналов, причем с разных датчиков (хотя вероятности пропуска сигналов неодинаковы для разных датчиков, - так, некоторые в пропуске сработок замечены не были).

Если дело обстоит так жестоко - предлагаю временно - поставить вместо МДВВ ПЛК - завести его на Ethernet (не 485),на входах завести модуль счетчиков (или триггеров) - вывести на 50 51 регистр модбас TCP слева чтобы просто модуль mobus мастера МДВВ

Хотя меня грызут смутные сомнения что логику надо менять - я бы все же не пренебрегал языком SFC - в свое время при управлении движением очень выручил(но это потом).

И все же freeweeling не вариант, надо делать by timer

superMAX
04.08.2009, 01:30
Таймеры, безусловно, вызываются в каждом цикле работы. Замена МДВВ на ПЛК мне совершенно не нравится (забавно то, что пока что ПЛК стоит в том же шкафу, но его входы не используются. Можно было, конечно, быстро заткнуть проблему, переключив шалящие датчики на него, но я предпочитаю докапываться до сути вещей) - конечная конфигурация предполагает централизованное управление с одного ПЛК, по моим ощущениям, его ресурсов будет более чем достаточно.

К SFC и прочим извращениям испытываю стойкое предубеждение.

Датчики замыкаются на секунды! Просто некоторые сработки обрабатываются по фронту сигнала - и именно они почему-то более уязвимы.

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

Собственно, таймеры используются для ограничения времени включения исполнительных механизмов и контроля за проходом изделий по конвейеру - отключив их, я лишь убрал из программы диагностику ошибок в работе конвейера.

Также было установлено, что возрастание темпа сработок датчиков стремительно увеличивает вероятность сбоя.

Изменения min- и maxCycleLength ничего, кроме значительного замедления программы не дали - сбои повторялись. Были перепробованы значения в 5, 10, 20 и 50 мс.

Переменная модуля Statistic "Cycle time in 100 mks" работает несколько странно - мне почему-то казалось, что она должна возвращать реальное время работы цикла программы, а ее показания скорее можно назвать интервалами времени между вызовами программы. Более того, продолжительность работы звонка, запускаемого при ошибке связи и выключающегося в следующем цикле программы, навела на определенные мысли. Судите сами: при частоте сети 50 Гц один период длится 20 мс. За это время имеем два максимума амплитуды, каждому из которых соответствует удар бойка о дальнюю чашку звонка, плюс еще два удара о другую чашку, осуществляемые под действием возвратной пружины. Цикл программы по показаниям "Cycle time in 100 mks" занимает не более 5 мс (плюс, как мне думалось, время работы системного ПО - но изменения этого счетчика при увеличении minCycleLength (по крайней мере в одной из прошивок) заставляют думать, что ничего прибавлять не надо). Добавим времена сработки выходов ПЛК и внешнего реле, коммутирующего звонок... Ну, положим 20 мс на все. Тогда единичная ошибка связи должна вызывать короткий звук, состоящий не более чем из 4 ударов бойка по чашкам, а в действительности боек успевает сделать едва ли не на порядок больше движений... Только не смейтесь над столь оригинальным методом поверки. В общем, есть подозрение, что там возвращается время цикла вовсе не в сотнях микросекунд, а в миллисекундах.

С другой стороны, введенный флаг корректного завершения работы программы а-ля

global
f : bool;
{ (* main prg entry point *)
if f then
achtung! Previous cycle was not terminated!
endif;
f := true;
...
do all our work
...
f := false;
} (* prg exit *)

какого-то черта на объекте не сработал ни разу, хотя в лабораторных условиях сработки наблюдались (а вот со сбоями ситуация диаметрально противоположна).

Сейчас буду писать собственные таймеры - с одним вызовом функции из sysLibTime на цикл работы программы. Тем более, что он у меня и так производится.

В общем, возникли чудовищные подозрения, что КоДеСис или ОС или что там еще живет - для каждого запуска таймера создает некие элементы в некоей динамической структуре, причем выделяет место под них поштучно, и хранится сие в виде списка. И, скорее всего, не уничтожается до тех пор, пока таймер не отработает свой интервал времени полностью. А потом запускается сборка мусора. И в итоге имеем квадратичный (или даже более быстрый) рост вычислительных потребностей от числа стартовавших в системе таймеров. На это накладываются странности "Cycle time in 100 mks" и менеджера задач (watchdog-то не активирован... Нафига задачу сносить или перезапускать?), а использование мной функции front() для сигналов - без внутреннего квитирования их обработки, - и приводит к столь странному поведению программы.

Надеюсь, выражался достаточно ясно и - не сочтите за ересь.

А насчет by timer... Надо будет попробовать, безусловно.

Время реакции... Ну, положим max 300 мс. Собственно, важно лишь одно - чтобы оно было постоянным. Датчики-то настраиваются по положению ;)

magirus
04.08.2009, 09:44
a МДВВ сколько? и по какому протоколу?
у меня сейчас пять штук стоит, подключены через модбас рту и универсал модбас девайс...
и в программе таймеров штук 25....

Малышев Олег
04.08.2009, 14:01
В общем, возникли чудовищные подозрения, что КоДеСис или ОС или что там еще живет - для каждого запуска таймера создает некие элементы в некоей динамической структуре, причем выделяет место под них поштучно, и хранится сие в виде списка.
Подозрения совершенно напрасны. Единственно что может возникнуть, а возможно и возникает, у Вас длинный цикл - системный таймер между вызовами таймеров внутри цикла увеличивается.

Филоненко Владислав
04.08.2009, 16:02
И используйте стандартные ФБ для поиска фронтов. Они работают стабильно.

Малышев Олег
06.08.2009, 12:30
Прошу прощения, но очень интересно чем закончилось?

superMAX
07.08.2009, 21:33
Сейчас, собсно, работает версия без таймеров. Точнее, в работе конвейера остался задействован один таймер; остальные не юзаются.
Готова версия с собственными таймерами, прошедшее после запуска время (в миллисекундах) в которых обновляется один раз в каждом цикле программы - и тут же принимается решение об установке выхода, но внедряться она будет при плановой остановке производства. Там я на всякий случай не стал делать ФБ, а просто массивчик...
Пока что freewheeling, но, по Вашему совету, перейду на периодическое исполнение проги и, соответственно, опрос МДВВ by command. Спасибо.

Ладно, если предположение, что огромные накладные расходы на обслуживание таймеров вызваны их динамической природой, неверно, - есть другая гипотеза: сам по себе тип данных time в CoDeSys крайне тормозной и для операций над ним вызываются процедуры вычисления дат и т.д. Либо - еще одна мысль - таймеры прицепляются к обработчику прерывания часов (ну, не знаю, как там RTC реализован) и он старательно обновляет их состояние с устрашающей частотой. Как Вы к ней относитесь?

Просто выявление этой проблемы заняло очень много времени - она старательно маскировалась под сбои оборудования. Сейчас полет нормальный.

Да, и еще. Инструкция как-то не вполне объясняет инфернальный смысл параметра minCycleTime. Если это время превышено, - что, текущая задача снимается и производится запуск нового цикла? Так ли необходимы эти параметры, если есть отдельный watchdog?

И еще... Оффтопик, конечно, но, как я посмотрю, гуру обратили внимание... Опубликуйте, плиз, схему симисторного выхода приборов Овен. От греха подальше есть желание выкинуть из МДВВ релюшки, а то 60000 сработок в месяц - это все же чревато. В фирменном журнале что-то было нарисовано, но как-то слишком обобщенно.