fixik_papus (fixik_papus) wrote,
fixik_papus
fixik_papus

Зловредный ноль, или Провод откусан неспроста

 Нет, сегодня разговор вовсе не про зануления там всякие. Которые бывают такие, что между нулем и землей искры летят.
И не про деление на ноль, результат которого примерно равен количеству глюков в программах, таковым делением вызванным.
Это все банально (хотя и "весело" временами).

В ППР перебирали перекладчик.
Это, как можно догадаться из названия, такой механизм, перемещающийся по двум координатам, который может нечто в одном месте взять и в другое положить. Штуковина не самая сложная на свете.
Сам механизм - серийно выпускаемый, а для работы с конкретным продуктом снабжается специализированным съемным инструментом. На английском жаргоне инструмент зовется "dress". Типа, "платье" (робота). В нашем случае - куча присосок.
Инструмент легко-быстро меняется, и часто их бывает несколько, под разные виды продукта. В этой машине - инструмент один и другого не будет никогда.

Во время переборки обнаружили на инструменте оборванный проводочек-перемычку. Натурально оборванный, ну, или откусанный, или перебитый. Очень обрадовались, что обнаружили. И восстановили. (Там все очевидно, откуда и куда. И на схеме нарисовано).

После переборки - перекладчик работать не пожелал. И даже вручную с панели управления двигаться не пожелал. И вообще на панели бред какой-то творится, половина функций не выполняется.

Такая ситуация после переборки бывает частенько.
Что-то где-то не так собрали, не туда подключили, не там обнулили...
Провозились несколько часов. Проверили всё три раза. Толку - ноль.

Тогда вспомнили про оборванный проводочек. От полной безнадеги и уныния - выдернули его из клеммы обратно.
И - внезапно! все заработало. Вот же чудеса на свете творятся...

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

Итак, перемычка эта живет прямо на разъеме инструмента и отвечает за его "кодирование". Каждый инструмент имеет свой код. Всего перемычек 4 шт, 3 шт замкнуты и одна откушена (потом восстановлена нами и опять откушена, ага). Идет все это на дискретные входы контроллера (перемычка - нолик, нет ее - единичка).

Исходя из полученного кода, контроллер определяет, какой именно инструмент прицепили, и подгружает соответствующий набор форматных данных (координаты и траектория движения, границы рабочей области, параметры секвенсора и прочая). Реализовано это (в Сименсе S7-300) как копирование соответствующего форматного блока данных в рабочий. При сохранении параметров формата - рабочий блок данных копируется обратно в нужный.
Отдельно обрабатываются ситуации "инструмента нету" = все единички и "инструмент только один" = все нолики (наш случай).

Программа написана на языке FBD (Function Block Diagram). Это важно!



Если инструмента нету - все понятно. Стоим и ругаемся "насяльника, дай лопату, кидать нечем".
Если инструментов много - вычисляется номер форматного блока данных (DB100+номер инструмента, получается от DB101 до DB114), и он копируется в DB100 (это рабочий блок).
Если инструмент один - все манипуляции с форматами отключаются и работаем сразу с "рабочим" блоком данных.
Все хорошо? Замечательно! Но есть нюанс...

Проверка на ноль сделана так: если ноль - то расчет номера обходим и принудительно ставим DB100. Все, проверка окончена. Что есть проверка, что нет ее...
Дальше программа пытается системной функцией BLKMOV (Block Move) копирнуть DB100 в DB100. Сделать это она не может - и сообщает об ошибке. Как? Снимает выходной сигнал ENO. (у функции есть и еще выход кода ошибки, но его успешно проигнорировали).

Теперь  - на тему обработки ошибок в языке FBD. Кому интересно - подробно написано, например, здесь (pdf! трафик!); а в посте - коротенько.

Примерчик из учебника (крупно по клику). Ссылку не даю умышленно, ибо такой учебник читать НЕ НУЖНО!



Большинство блочочков (инструкций, вызовов функций и прочая) имеют вход разрешения EN и выход разрешения ENO. Если все хорошо - EN и ENO активны (1). Если EN=0 то блочочек не выполняется и передает дальше ENO=0. Если в блочочке ошибка - он снимает свой  ENO. Выход ENO предыдущего передается на вход EN последующего.

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

Что происходит в нашем случае? Системная функция вылетела с ошибкой (ENO=0). После чего - последующие команды в цепочке, которым выданы EN=0, тупо не выполняются. Инициализация формата проходит криво, и машина не заводится...
Это еще повезло, что просто "не заводится". Могла бы сойти с ума и стукнуть инструментом по конвейеру, например.


Неведомый итальянский наладчик, обнаружив такую бяку на заводе-изготовителе, почему-то не стал объясняться с программистами. Чтобы те нашли и устранили косяк. А просто откусил проводок на единственном инструменте. После чего машина стала работать с форматом №1 (DB101). И работала так много лет, пока мы этот проводок откушенный случайно не обнаружили и не восстановили.

Чудес, как обычно, не бывает. Причину нашли. А что теперь делать-то?
После недолгих совещаний - пошли по пути "наименьшего сопротивления". Перемычку эту вредную демонтировали, и в схеме ее зачеркали крестиками. Оно, конечно, не совсем правильно... но так все с гарантией будет работать. И не нужно выяснять, где и при каких условиях там еще кривая проверка на ноль вылезет...
Так и работаем по сей день.
Как таких бяк избежать?

1. На самом деле, FBD (и LD) вообще использовать не нужно ныне в новых проектах. Ladder diagram и Function Block Diagram были придуманы в 1970е, когда программируемые контроллеры только появлялись. Чтобы разработчикам, привыкшим к релейной "лестничной логике", было попроще привыкать, и полегче существующие проекты в контроллер загнать.
Но сейчас 21 век на дворе! Делать проекты на LD / FBD - это как считать на логарифмической линейке. Можно, но не нужно, потому что давно есть способы и лучше, и быстрее (IL=ассемблер, ST=Паскаль, ну и С, если мы о ПЛК говорим).

2. Если же все же пишем (точнее, рисуем) в FBD - про "рекомендации из учебников" забываем сразу! Не всегда они добру учат.
Вот прям из учебника картинка (см. выше) - давайте разберем ее по полочкам.


2А. Начнем с цепи (network) №2. Что будет, если #RampTMP=0? Правильно, деление на ноль. Команда деления DIV не выполнится, а за ней не выполнится и все остальное (в примере - ADD).... А последний выход ENO в цепочке, как обычно, вообще не проверяется (потому что учатся по такому вот учебнику, да). В результате - расчет переменной #TMP просто не будет выполнен, с непредсказуемыми последствиями.
ОК, при делении на 0 мы еще получим исключение (exception) и можем его обработать, но не на все есть исключения.

Как нужно?
Никаких соединений EN-ENO нигде и никогда!
EN всегда всем ставим в 1.
КАЖДАЯ ошибко-опасная команда или функция (а-ля деление, где может ноль попасться) - проверяется на ENO=0 сразу, с соотвествующим алгоритмом обработки (ну хотя бы индикации) ошибки. Как минимум -взводим флаг, и возвращаем из процедуры для проверки, как она выполнилась. Только так, и никак иначе.

Спросите, а откуда возьмется #RampTMP = 0? Элементарно!
2Б. Смотрим цепь №1. Расчет #RampTMP там - "завязан" на EN/ENO, тут они используются в качестве логики.
Вход EN блока MOVE - не подключен никуда. И будет (в Сименсе) воспринят как 0. Соответственно, ни эта команда MOVE не выполнится, ни все остальные команды MOVE (ENO ее тоже будет равен 0) - не выполнятся.
С хеша (#) у Сименса начинаются имена локальных переменных. Которые при вызове процедуры - обнуляются операционкой.
Результат - #RampTMP будет гарантированно всегда равен 0

А во второй цепи - мы на этот ноль и поделим.
Отличный примерчик в учебнике, не правда ли?


Как нужно?
Никогда и ни при каких обстоятельствах - не использовать EN/ENO для какой-либо логики. А исключительно для обработки ошибок!

3. Что делать, если нам попалась-таки программа на FBD? И ее нужно отладить или изменить?
Хинт: (в Step7 или TIA Portal) переключаем вид на STL. Это можно сделать всегда (а вот обратно - далеко не всегда). Сразу EN/ENO исчезнут, и останутся от них только условные переходы вокруг каждой команды.


К счастью, есть умные люди, которые все вышеизложенное понимают. Например, разработчики системы проектирования Codesys. Там в большинстве применений никаких EN/ENO в FBD нету. Хоть это и не соответствует стандарту IEC.
Стало быть, и накосячить с ними невозможно.

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

Оригинал на fixik_papus.dreamwidth.org
Tags: байки наладчика
Subscribe
promo antonprok 11:32, yesterday 29
Buy for 20 tokens
Друзья, обращаюсь к коллективному разуму. В работе нашей курьерской службы Марафон 2.0 столкнулся со следующей проблемой. Мы застряли. В последнее время продажи практически не растут. Последний год примерно. Да, есть объективные причины-общий экономический кризис. 80% продаж на рынке BTB. Есть…
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 167 comments
Previous
← Ctrl ← Alt
Next
Ctrl → Alt →
Previous
← Ctrl ← Alt
Next
Ctrl → Alt →