ГлавнаяАкадемияИсполнительные устройства: интерлоки, таймауты → Использование концевых выключателей (Limit Switches)

Использование концевых выключателей (Limit Switches)

Урок 2 · Исполнительные устройства: интерлоки, таймауты · 30 мин · theory

Введение в концевые выключатели: назначение и принцип работы

Концевой выключатель (также известный как limit switch) — это электромеханический датчик, предназначенный для физического определения положения движущегося объекта. Его основная задача — подать электрический сигнал в систему управления, когда механизм достигает заранее определённой крайней точки своего хода. В отличие от программных таймеров или энкодеров, которые рассчитывают или измеряют положение, концевой выключатель обеспечивает прямое, неопровержимое физическое подтверждение достижения конечной позиции.

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

Основные типы контактов

Концевые выключатели оснащаются как минимум одной группой контактов, которые могут быть двух основных типов:

  • Нормально открытый (NO - Normally Open): В состоянии покоя (когда на выключатель нет механического воздействия) электрическая цепь разомкнута. При срабатывании выключателя контакты замыкаются, пропуская ток. Этот тип удобен для сигнализации о достижении цели, например, для включения индикаторной лампы "Ворота полностью открыты".
  • Нормально закрытый (NC - Normally Closed): В состоянии покоя контакты замкнуты, и через них протекает ток. При срабатывании выключателя цепь размыкается. Этот тип является предпочтительным для цепей безопасности. Его главное преимущество — отказоустойчивость. Если произойдёт обрыв провода, идущего к такому выключателю, система управления интерпретирует это как срабатывание (размыкание цепи), что приведёт к безопасной остановке механизма.
  • Многие промышленные концевые выключатели имеют комбинированную контактную группу (SPDT - Single Pole Double Throw), включающую в себя общий контакт (COM), один NO и один NC контакт. Это даёт гибкость в проектировании схем управления и безопасности.

    | Тип контакта | Состояние в покое (нет нажатия) | Состояние при срабатывании (нажат) | Типовое применение |

    | :--- | :--- | :--- | :--- |

    | NO | Цепь разомкнута | Цепь замкнута | Сигнализация о достижении точки, запуск сценария |

    | NC | Цепь замкнута | Цепь разомкнута | Аварийная остановка, цепи безопасности, отсечка питания привода |

    > 💡 Подсказка: Для критически важных сценариев безопасности (например, остановка ворот) предпочтительнее использовать NC-контакты. В состоянии покоя цепь замкнута, и ее обрыв (из-за срабатывания или неисправности провода) гарантированно будет зафиксирован контроллером как событие.

    Области применения в автоматизации зданий

    На платформе HI концевые выключатели являются неотъемлемой частью систем, управляющих механизмами с линейным или поворотным движением.

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

    ---

    Схемы подключения к дискретным входам контроллеров HI

    Физическое подключение концевых выключателей к контроллеру HI осуществляется через его универсальные или дискретные входы (DI). Стандартной и наиболее надёжной является схема "сухой контакт". В этой схеме сам выключатель не имеет собственного источника питания; он лишь коммутирует цепь, создаваемую внутренними компонентами контроллера.

    Типовая схема подключения "сухой контакт"

    Контроллер HI предоставляет на своих клеммах слаботочное напряжение (обычно 3.3V или 5V) и общий провод (GND). Концевой выключатель включается в разрыв этой цепи.

  • Один контакт выключателя подключается к клемме DI (например, `UI-05`) контроллера.
  • Второй контакт выключателя подключается к клемме GND контроллера.
  • > ⚠️ Внимание: Всегда проверяйте соответствие напряжения, подаваемого на дискретный вход, спецификации контроллера HI. Подача внешнего высокого напряжения (например, 12V, 24V или 230V) на входы, предназначенные для "сухого контакта", может необратимо повредить устройство.

    Ниже представлена типовая ASCII-схема подключения двух концевых выключателей (для положений "открыто" и "закрыто") к контроллеру.

    //========= WIRING-LIMIT-SW-001: Gate Limit Switches =========
    
    

    [CTRL:HI-Core] (LIMIT-SW-OPEN)

    UI-05 ----------------------------------o/ o---- COM

    GND ------------------------------------------ NO/NC

    [CTRL:HI-Core] (LIMIT-SW-CLOSED)

    UI-06 ----------------------------------o/ o---- COM

    GND ------------------------------------------ NO/NC

    Программная настройка входов и логика работы

    После физического подключения необходимо правильно настроить порты контроллера. Логика работы входа зависит от типа используемого контакта (NO или NC) и конфигурации внутреннего подтягивающего резистора.

    * Логика: Когда выключатель не нажат (контакт замкнут), он "притягивает" вход к земле (GND). Контроллер считывает низкий уровень сигнала (логический `0` или `false`). При срабатывании выключателя (контакт размыкается), pull-up резистор "подтягивает" вход к высокому уровню (+V), и контроллер считывает высокий уровень сигнала (логический `1` или `true`). * Логика: Когда выключатель не нажат (контакт разомкнут), pull-down резистор удерживает на входе низкий уровень (логический `0`). При срабатывании (контакт замыкается), вход подключается к линии питания (если используется внешняя схема) или к специальному выходу контроллера, и на нём появляется высокий уровень (логический `1`). Для схемы "сухой контакт" с замыканием на GND эта логика инвертируется.

    В большинстве случаев, для обеспечения отказоустойчивости, рекомендуется использовать NC-контакты с включенным Pull-up резистором.

    Чтение состояния входа через MQTT

    Контроллер HI публикует состояние своих входов в системные топики MQTT. Это основной способ получения данных в Node-RED. Формат топика стандартизирован.

    Для отслеживания состояния концевого выключателя, подключенного к входу `UI-05`, необходимо в Node-RED подписаться на топик `/devices/wb-gpio/controls/UI-05`. Сообщение в этом топике будет меняться с `0` на `1` (или наоборот) в момент срабатывания выключателя.

    ---

    Практика: Интеграция с логикой управления приводом в Node-RED

    Теперь объединим полученные знания для создания безопасного потока управления приводом. Мы будем использовать сигналы с концевых выключателей для предотвращения отправки "лишних" команд и защиты мотора.

    > 🔗 Связанный материал: Данный урок базируется на схемах, рассмотренных в уроке `COURSE-05-M06-L02 'Схема управления двумя реле: Открыть/Закрыть'`. Убедитесь, что вы освоили материал предыдущего урока, в частности, логику интерлока (взаимной блокировки) реле открытия и закрытия.

    Создание потока с логикой блокировки

    Наша задача — модифицировать поток управления приводом так, чтобы он учитывал состояние концевых выключателей.

    Логика блокировки:
  • Если сработал концевой выключатель "Полностью открыто", система должна игнорировать все последующие команды "Открыть".
  • Если сработал концевой выключатель "Полностью закрыто", система должна игнорировать все последующие команды "Закрыть".
  • Поток Node-RED будет выглядеть следующим образом:
    // --- Входы с концевых выключателей ---
    

    [mqtt in: .../UI-05] (Открыто) --> [change: set flow.gate_open=true]

    [mqtt in: .../UI-06] (Закрыто) --> [change: set flow.gate_closed=true]

    // --- Логика обработки команд ---

    [mqtt in: .../gate/set] (Команды "OPEN", "CLOSE")

    |

    +--> [switch: msg.payload] --("OPEN")--> [switch: flow.gate_open?] --(false)--> [Команда на реле "Открыть"]

    | |

    | +--(true - заблокировано)--> [debug: "Уже открыто"]

    |

    +--> [switch: msg.payload] --("CLOSE")-->[switch: flow.gate_closed?]--(false)--> [Команда на реле "Закрыть"]

    |

    +--(true - заблокировано)--> [debug: "Уже закрыто"]

    Реализация в Node-RED

  • Подписка на состояние концевиков:
  • Добавьте два узла `mqtt in` для подписки на топики ваших концевых выключателей.

    * Узел 1: `Topic: /devices/wb-gpio/controls/UI-05` (Концевик "Открыто")

    * Узел 2: `Topic: /devices/wb-gpio/controls/UI-06` (Концевик "Закрыто")

  • Сохранение состояния:
  • После каждого узла `mqtt in` поставьте узел `change`. Его задача — сохранить состояние концевика в контексте потока (flow context).

    * Для концевика "Открыто": `set` `flow.isFullyOpen` `to` `msg.payload == "1"` (преобразуем "1"/"0" в `true`/`false`).

    * Для концевика "Закрыто": `set` `flow.isFullyClosed` `to` `msg.payload == "1"`.

  • Блокировка управляющей команды:
  • В основном потоке управления, после получения команды `"OPEN"` или `"CLOSE"` (например, из топика `hi/commands/gate1/set`), необходимо проверить соответствующий флаг в контексте. Для этого идеально подходит узел `switch`.

    * После узла, который фильтрует команду `"OPEN"`, поставьте узел `switch`.

    * Настройте его на проверку `Property`: `flow.isFullyOpen`.

    * Правило: `is false`. Только если это условие выполняется, сообщение проходит дальше на узел управления реле. Если `is true`, команда блокируется.

    * Аналогичная логика настраивается для команды `"CLOSE"` и переменной `flow.isFullyClosed`.

    Пример JSON-сообщения, которое мы блокируем:

    {
    

    "payload": "OPEN",

    "topic": "hi/commands/gate1/set",

    "qos": 1,

    "retain": false

    }

    Если в этот момент `flow.isFullyOpen` равно `true`, это сообщение не должно дойти до реле `RL-01`.

    Эта простая схема уже значительно повышает надёжность, но у неё есть недостаток: она не знает о промежуточных состояниях привода.

    ---

    Пример: Реализация машины состояний для привода

    Простая блокировка команд — это хорошо, но профессиональная система должна всегда знать, в каком состоянии находится управляемый ею объект. Находится ли он в движении? Остановлен на полпути? Для этого реализуется конечный автомат, или машина состояний (State Machine).

    Состояния привода

    Определим все возможные состояния для нашего привода (например, ворот):

    Текущее состояние мы будем хранить в переменной контекста `flow.driveState`.

    Реализация с помощью узла `function`

    Центром нашей машины состояний будет один узел `function`, который будет получать на вход все события (команды пользователя, сигналы с концевиков) и на основе текущего состояния принимать решение о переходе в новое состояние и отправке команд на реле.

    Входы узла `function`: Выходы узла `function`: Пример кода для узла `function`:
    // Получаем текущее состояние или инициализируем его
    

    let state = flow.get("driveState") || "CLOSED";

    // Определяем тип входящего сообщения

    const topic = msg.topic;

    const payload = msg.payload;

    let command_relay_open = null;

    let command_relay_close = null;

    let new_state = null;

    // Главный switch, обрабатывающий логику переходов

    switch (state) {

    case "CLOSED":

    if (topic === 'command' && payload === 'OPEN') {

    state = "OPENING";

    // Посылаем команду на реле открытия

    command_relay_open = { payload: true };

    // Посылаем команду на выключение реле закрытия (на всякий случай)

    command_relay_close = { payload: false };

    }

    break;

    case "OPEN":

    if (topic === 'command' && payload === 'CLOSE') {

    state = "CLOSING";

    command_relay_close = { payload: true };

    command_relay_open = { payload: false };

    }

    break;

    case "OPENING":

    // Если пришла команда СТОП или сработал концевик ОТКРЫТО

    if ((topic === 'command' && payload === 'STOP') || (topic === 'limit_switch_open' && payload === true)) {

    // Останавливаем движение

    command_relay_open = { payload: false };

    // Определяем новое состояние

    state = (topic === 'limit_switch_open') ? "OPEN" : "STOPPED";

    }

    break;

    case "CLOSING":

    // Если пришла команда СТОП или сработал концевик ЗАКРЫТО

    if ((topic === 'command' && payload === 'STOP') || (topic === 'limit_switch_closed' && payload === true)) {

    command_relay_close = { payload: false };

    state = (topic === 'limit_switch_closed') ? "CLOSED" : "STOPPED";

    }

    break;

    case "STOPPED":

    // Из остановленного состояния можно двигаться в любую сторону

    if (topic === 'command' && payload === 'OPEN') {

    state = "OPENING";

    command_relay_open = { payload: true };

    } else if (topic === 'command' && payload === 'CLOSE') {

    state = "CLOSING";

    command_relay_close = { payload: true };

    }

    break;

    }

    // Если состояние изменилось, сохраняем его и отправляем уведомление

    if (state !== flow.get("driveState")) {

    flow.set("driveState", state);

    new_state = {

    payload: {

    state: state,

    timestamp: Date.now()

    },

    topic: "hi/status/gate1/state" // Топик для статуса

    };

    node.status({fill:"blue", shape:"dot", text: `State: ${state}`});

    }

    // Отправляем команды на реле и сообщение о статусе на разные выходы

    // Выход 1: команда на реле открытия

    // Выход 2: команда на реле закрытия

    // Выход 3: сообщение о новом статусе

    node.send([command_relay_open, command_relay_close, new_state]);

    Этот код представляет собой каркас. Его нужно подключить к соответствующим узлам `mqtt in` (для команд и датчиков) и `mqtt out` (для реле и статуса).

    ---

    Обработка нештатных ситуаций и таймауты

    Надёжная система должна быть готова к отказам. Что если один из концевых выключателей сломается или его провод будет повреждён? Мотор будет работать бесконечно, пока не сгорит сам или не сломает механизм. Для предотвращения этого вводится сторожевой таймер (watchdog).

    > ⚠️ Внимание: Таймаут безопасности должен быть немного больше (на 10-15%) максимального реального времени полного открытия или закрытия. Слишком короткий таймаут приведет к ложным срабатываниям.

    Использование узла `trigger` для реализации watchdog

    Узел `trigger` идеально подходит для этой задачи. Он может отправлять одно сообщение сразу, а другое — по истечении заданного времени, если не будет сброшен.

    Логика работы таймера:
  • При отправке команды "Открыть" или "Закрыть" мы также отправляем сообщение на вход узла `trigger`.
  • `trigger` немедленно пропускает это сообщение дальше (чтобы не задерживать команду на реле) и одновременно запускает внутренний таймер (например, на 35 секунд).
  • Если за эти 35 секунд приходит сигнал от соответствующего концевого выключателя, мы отправляем на `trigger` специальное сообщение для сброса (`msg.payload = "reset"`). Таймер останавливается.
  • Если сигнал от концевика не пришёл, `trigger` по истечении 35 секунд отправляет второе сообщение. Это сообщение будет содержать команду "Стоп" и информацию об ошибке.
  • Пример потока с watchdog:
    // Запуск движения
    

    [...Логика FSM...] --("OPEN")--> [trigger: 35s] --(немедленно)--> [Команда на реле "Открыть"]

    |

    +--(через 35с)--> [function: Формирование ошибки] --> [Команда "Стоп" + MQTT-уведомление]

    // Сброс таймера

    [mqtt in: концевик "Открыто"] --(true)--> [change: set msg.payload="reset"] --> [Вход сброса trigger'а]

    Обработка невозможных состояний

    Ещё одна нештатная ситуация — одновременное срабатывание обоих концевых выключателей. Физически это почти невозможно и почти всегда свидетельствует о проблеме:

    Машина состояний должна уметь обрабатывать такое событие. В узле `function` можно добавить проверку:

    let isOpen = flow.get("limitOpen") || false;
    

    let isClosed = flow.get("limitClosed") || false;

    if (isOpen && isClosed) {

    // Переход в состояние ОШИБКА

    state = "ERROR";

    flow.set("driveState", state);

    // Гарантированно остановить оба реле

    let stop_open = { payload: false };

    let stop_close = { payload: false };

    // Создать сообщение об ошибке

    let error_msg = { payload: { error: "Both limit switches are active!", state: "ERROR" } };

    node.status({fill:"red", shape:"dot", text:"ERROR: Both switches active"});

    node.send([stop_open, stop_close, error_msg]);

    return; // Прервать дальнейшее выполнение

    }

    Этот блок должен выполняться в самом начале, до основной логики `switch`, и переводить систему в безопасное состояние "Ошибка", требующее вмешательства инженера.

    ---

    Итоги и лучшие практики

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

    Ключевые выводы:

    Что дальше?

    Освоив принципы управления направлением и позиционированием с помощью концевых выключателей, вы готовы к более сложным задачам. В следующих уроках мы рассмотрим, как интегрировать эту логику с системами безопасности (например, фотоэлементами), как реализовать точное позиционирование с помощью энкодеров и как управлять скоростью приводов с помощью аналоговых сигналов или Modbus.