[personal profile] notes4myfamily
Оригинал взят у [livejournal.com profile] 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
This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

notes4myfamily

April 2017

S M T W T F S
      1
23 4 5 6 78
9 10 11 12 13 1415
16 17 18 19 20 2122
23 24 25 26 27 2829
30      

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 13th, 2025 12:32 pm
Powered by Dreamwidth Studios