СТАБУР
Образование· 8 мин чтения

В LD две катушки на один выход: приоритет сетей и неожиданное перезаписывание

Почему в LD две катушки на один выход дают неожиданное поведение: порядок сетей, latch, reset и поиск через cross-reference.

Насос должен включаться по команде автомата и гаснуть по аварии уровня. На схеме все красиво. В поле насос иногда не стартует, иногда не останавливается, а в онлайн-мониторинге катушка «Пуск» мигает, хотя выход уже в другом состоянии. Открываете LD - и находите вторую катушку на тот же %Q0.3 в сети «Ручной режим», которую никто не помнил. Две катушки на один физический выход - не редкость, а нормальная цена роста проекта. Проблема в том, что IEC 61131-3 не гарантирует «последнюю победившую» без понимания порядка сетей.

Здесь не учебник LD с нуля и не сравнение LD со ST. Разбираем конфликт двух катушек на один выход: дублирование, порядок выполнения сетей, latch и reset, поиск через cross-reference. Статья не повторяет базовую релейную логику - для нее есть отдельный материал по языку LD.

Короткий ответ

Если в LD две и более катушки пишут в один и тот же выход, итоговое состояние определяется порядком выполнения сетей (rungs) в текущем цикле ПЛК, а не «логикой по смыслу». Последняя выполненная запись перезаписывает предыдущую. Катушка с latch удерживает выход, пока не сработает reset в той же или другой сети. Чтобы найти конфликт, используйте cross-reference (перекрестные ссылки) по адресу выхода и просмотрите все POU, где он упоминается.

Симптом «неожиданного» поведения почти всегда означает: выход пишут из нескольких мест, и вы смотрите только одну сеть. Лечение - не перестановка проводов, а явное разделение команд (одна катушка - один выход) или промежуточная переменная с приоритетом в отдельной сети.

Как ПЛК выполняет LD: один цикл, много сетей

В каждом цикле ПЛК обходит сети сверху вниз (в пределах POU и задачи). Катушка - это присвоение булева значения выходу. Если две катушки в разных сетях адресуют %Q0.3, в конце цикла на выходе останется то, что записала последняя сработавшая катушка по порядку выполнения.

Это не OR и не AND «по проводам». Это последовательная перезапись. Сеть 1 включила выход. Сеть 15 ниже по списку его выключила - и оператор видит «автомат дал пуск, а насос мертвый». Или наоборот: аварийная сеть выше по списку сбросила выход, а ручная сеть ниже снова включила - и межблокировка обойдена без злого умысла.

Порядок сетей зависит от организации проекта: несколько POU, порядок вызова, приоритет задач. Подробнее про цикл и задачи - в материале «Цикл ПЛК: порядок выполнения и гонки в программе».

Latch, reset и «залипание»

Катушка latch (SET) удерживает выход после краткого импульса на входе. Reset (RST) сбрасывает. Если latch в сети «Автомат», а reset в сети «Аварии» - поведение предсказуемо, пока порядок сетей согласован. Если reset стоит выше latch и срабатывает каждый цикл по ошибочному условию - выход никогда не включится. Если latch ниже и перезаписывает reset - авария не гасит выход.

Типичная ошибка: дублировать latch на тот же выход в ручном режиме «для надежности». Две latch-катушки на один бит - гарантированный источник сюрпризов при смене режима.

Дублирование в разных POU

Проект растет: основная логика в MAIN, ручной режим в MANUAL, аварии в ALARMS. Cross-reference по %Q0.3 показывает три катушки в трех модулях. Порядок вызова POU в задаче решает, кто победит. Инженер смотрит только MAIN и не понимает, почему «наша катушка активна, а выход ноль».

Правило для сопровождения: один физический выход - одна точка записи в программе. Все остальные места пишут в промежуточную переменную CmdPump или InterlockPump, а одна финальная сеть формирует %Q0.3 по приоритету: авария > ручной > автомат.

Cross-reference: как найти всех, кто пишет в выход

В CODESYS и аналогах: правый клик по переменной выхода - «Перекрестные ссылки» / Cross Reference. Получите список всех сетей и POU, где адрес используется как coil (запись). Отдельно проверьте force, GVL и привязки HMI - иногда «катушка» на экране пишет в тот же тег.

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

Базовая механика LD и релейная модель - в «Язык LD (Ladder Diagram): как работает релейная логика».

Таблица: симптом, где еще пишут, как найти в LD

Симптом на выходе Где еще могут писать Как найти в LD
Катушка ON, выход OFF сеть ниже по списку сбрасывает cross-ref, мониторинг сетей по порядку
Авария не гасит выход latch в ручном режиме ниже reset найти все SET/RST на адрес
Выход мигает каждый цикл две сети поочередно 0/1 trace на 2-3 цикла, порядок POU
Работает только в AUTO отдельная логика в MANUAL POU cross-ref по всем задачам
После загрузки проекта иначе изменился порядок POU в task сравнить конфигурацию задачи

Явный приоритет вместо войны катушек

Вместо двух катушек на %Q0.3 делают одну выходную сеть:

IF Alarm THEN Out := FALSE ELSIF Manual THEN Out := ManualCmd ELSE Out := AutoCmd END_IF

В LD это выглядит как каскад контактов «разрешение аварии - разрешение ручного - автомат» и одна катушка в конце. Смысл тот же: приоритет задан явно, а не порядком случайных сетей.

Для насосов и клапанов полезно разделять команду (желание включить) и разрешение (можно ли). Тогда межблокировки не конкурируют с катушкой пуска на одном бите.


Типовые ошибки при сопровождении

Добавили ручной режим отдельной сетью «внизу файла» - он перезаписывает автомат каждый цикл, пока включен переключатель.

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

Reset только в AUTO - в MANUAL latch не сбрасывается аварией.

Исправили только мнемосхему - на HMI другой тег, в LD конфликт остался.

Пример из практики: насос и авария уровня

Сеть 10: автомат дает пуск насосу на %Q2.1. Сеть 45: авария уровня сбрасывает тот же %Q2.1 через обычную катушку. Сеть 80: ручной режим снова включает %Q2.1, если переключатель LOCAL. Порядок: 10, 45, 80. В AUTO при аварии уровня насос гаснет в сети 45. В LOCAL авария гасит в 45, ручная сеть 80 сразу зажигает снова - оператор видит «авария горит, насос крутится», мастер видит «межблокировка не работает». Cross-reference по %Q2.1 показывает три катушки; лечение - одна выходная сеть с приоритетом аварии над ручным.

Такие истории повторяются на каждом втором объекте с LD старше пяти лет. Не потому что LD плох, а потому что проект рос слоями без ревизии выходов.

LD, FBD и ST в одном проекте

Катушка в LD может писать в переменную, которую ST присваивает тому же %Q в конце цикла. В мониторинге LD «все правильно», а выход - из ST. Cross-reference обязан включать все языки. В CODESYS смотрят не только Coils, но и записи в ST и присвоения в FBD.

При рефакторинге часто выносят конфликтные выходы в отдельный POU OUTPUTS с одной задачей и одним проходом - туда сводят все команды. Остальная логика пишет только промежуточные разрешения. Это проще сопровождать, чем искать сеть 80 в файле на 3000 строк.

Ревью перед сдачей: правило «один выход - один writer»

Перед FAT полезно прогнать отчет: все физические выходы, у которых больше одной записи в проекте. Список согласуют с электросхемой. Для каждого «двойного» выхода - либо обоснование (например, аппаратное дублирование с OR в одной сети), либо исправление до пуска. На объекте такой отчет делают за полдня; на пуске исправление конфликта катушек может стоить смену простоя.

Force, HMI и «третья катушка»

Онлайн force на выходе в отладке - та же перезапись, только с панели. Оператор с правами наладчика может удерживать выход вопреки логике. Если force не сняли ночью - утром LD «врет» в мониторинге. Проверяют список активных force и записей в журнале отладки HMI.

Кнопка на мнемосхеме, привязанная напрямую к %Q, - еще один писатель. Граница «команда с экрана» и «катушка в LD» должна быть явной: экран пишет в HMI_CmdPump, LD решает, что пойдет на физический выход.

Связь с циклом ПЛК и временем реакции

Две катушки на один выход особенно коварны, когда одна сеть в быстрой задаче, другая - в медленной. Быстрая включает, медленная раз в 100 мс выключает - на осциллографе выход мерцает, в LD обе сети «правильные». Смотрят привязку POU к задачам и время цикла. Материал «Цикл ПЛК: порядок выполнения и гонки» дополняет картину: конфликт катушек - частный случай гонки записи.

При удлинении цикла из-за нагрузки порядок «кто последний» может теоретически сдвинуться, если изменили приоритеты задач. После оптимизации проекта перепроверяют спорные выходы.

Документирование выходов в as-built

В исполнительной документации к каждому физическому выходу полезна колонка «источник команды в ПЛК»: один POU, одна сеть, или явный каскад приоритетов. Тогда через три года никто не добавит «временную» катушку внизу файла, не заметив конфликта. Для новых проектов правило «один writer» закрепляют в стандарте кодирования команды - так же, как запрет на дублирование глобальных переменных без префикса участка.

Миграция legacy: не копировать сеть целиком

При переносе проекта с другого ПЛК часто копируют LD файл целиком. Адреса выходов совпадают с новой схемой «по номеру», но логика ручного режима с другого объекта остается. На старте все работает в AUTO; через полгода включают LOCAL на ремонте - и всплывает вторая катушка. При миграции делают отдельный проход: список всех %Q и %M, которые пишутся более одного раза, с пометкой «оставить / переписать / удалить».


Вопросы при работе

Можно ли запретить две катушки на один выход в среде?
Некоторые среды предупреждают при компиляции, многие - нет. Полагаться на дисциплину проекта и ревью cross-reference.

Почему на симуляторе OK, на объекте нет?
Другой порядок задач, другая версия библиотеки, force с панели, физический вход подтягивает цепь.

LD или ST для приоритетов?
Для каскада приоритетов ST читается проще; LD удобен, если команда одна финальная катушка после цепочки контактов.

TOPICS • ТЕМЫ#LD две катушки один выход#ladder diagram конфликт#порядок сетей ПЛК#latch reset LD#cross-reference CODESYS#перезапись выхода ПЛК#приоритет логики#релейная логика IEC 61131-3