ГлавнаяАкадемияNode-RED: установка, flows, msg/JSON, отладка → Обзор универсальных входов/выходов контроллера

Обзор универсальных входов/выходов контроллера

Урок · Node-RED: установка, flows, msg/JSON, отладка · 30 мин · theory

Введение в универсальные входы/выходы (UI/UO)

ведение в универсальные входы/выходы (UI/UO)

В основе гибкости контроллеров платформы HI лежат универсальные входы/выходы (UI/UO). Это физические порты, которые, в отличие от специализированных интерфейсов типа DALI или CAN-шины, могут быть программно сконфигурированы для выполнения различных задач. Каждый из 22 универсальных портов контроллера может работать либо как вход для получения данных от внешнего мира, либо как выход для управления исполнительными механизмами.

Архитектурное отличие универсального порта от специализированного заключается в его многозадачности. Если порт DALI предназначен исключительно для управления освещением по одноименному протоколу, то универсальный порт может быть сегодня входом для кнопки, завтра — выходом для управления приводом клапана, а послезавтра — входом для аналогового датчика давления. Эта гибкость позволяет инженеру-интегратору адаптировать один и тот же контроллер под совершенно разные задачи на объекте, будь то умный дом, гостиничный номер или небольшой производственный цех.

> 📋 Ключевые понятия:

> * Универсальный Вход (UI - Universal Input): Порт, сконфигурированный на приём сигнала.

> * Универсальный Выход (UO - Universal Output): Порт, сконфигурированный на передачу управляющего сигнала. На нашем контроллере выходы являются релейными, но мы также рассмотрим концепцию аналоговых выходов, реализуемых через внешние модули или специализированные порты.

Универсальные порты контроллера HI поддерживают несколько ключевых режимов работы, покрывающих до 80% типовых задач автоматизации.

Обзор поддерживаемых режимов

  • Дискретный вход (DI — Digital Input): Самый простой режим. Порт определяет два состояния сигнала: "есть напряжение" (логическая `1`, `true`) или "нет напряжения" (логический `0`, `false`). Идеально подходит для подключения:
  • * Кнопок и выключателей (в том числе типа "сухой контакт").

    * Датчиков движения с релейным выходом.

    * Герконов (датчиков открытия окон/дверей).

    * Датчиков протечки воды.

  • Аналоговый вход (AI — Analog Input): В этом режиме порт измеряет уровень напряжения в определённом диапазоне, чаще всего 0–10 Вольт (0-10V). Это позволяет получать не просто факт события, а количественное значение. Типовые применения:
  • * Датчики температуры, влажности, давления.

    * Датчики освещённости.

    * Датчики уровня CO₂.

    В контексте контроллера HI, его 22 универсальных входа предназначены именно для режимов DI и AI, а также для специализированных цифровых протоколов, таких как 1-Wire.

    Связь с Node-RED: Программные ноды

    Чтобы физический сигнал превратился в данные в Node-RED, используются специализированные ноды. В зависимости от аппаратной реализации это могут быть стандартные ноды `rpi-gpio` (для Raspberry-совместимых платформ) или брендированные ноды (например, `hi-controller-input` / `hi-controller-output`). Программная нода выступает «мостом», который преобразует электрический уровень на порту в объект `msg.payload`, с которым вы будете работать в своих потоках.

    Электрические характеристики

    Понимание электрических характеристик портов критически важно для предотвращения выхода оборудования из строя.

    | Характеристика | Режим DI ("сухой контакт") | Режим AI (0-10V) | Режим DO (дискретный выход) |

    | ------------------------------ | -------------------------- | --------------------- | ----------------------------- |

    | Тип сигнала | Дискретный ("замкнуто/разомкнуто") | Аналоговый, напряжение | Дискретный (вкл/выкл) |

    | Диапазон напряжения | Определяется внутренне | 0 - 10 В DC | До 250 В AC / 30 В DC |

    | Максимальный ток | Неприменимо (сигнальный) | Неприменимо (вход) | Зависит от реле (например, 5А) |

    | Типовое устройство | Кнопка, геркон | Датчик температуры | Реле, контактор, лампа |

    | Пример на контроллере HI | Универсальный вход (UI) | Универсальный вход (UI)| Релейный выход (RELAY) |

    В нашем контроллере 22 универсальных входа (UI) и 22 релейных выхода. Хотя входы можно считать UI, а выходы — DO, мы будем использовать общую терминологию для понимания концепции в целом, так как на рынке существуют модули расширения с аналоговыми выходами (AO).

    Конфигурация портов в режиме входа (DI, AI)

    Для работы с физическими портами контроллера в Node-RED используется специальная палитра узлов, например, `node-red-contrib-hi-io`. Эти узлы позволяют читать состояние входов и управлять выходами.

    Настройка порта как дискретного входа (DI)

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

    > 💡 Подсказка: Для корректной работы "сухих контактов" часто требуется внешний подтягивающий резистор (pull-up resistor), который обеспечивает стабильное состояние `true` или `false` при разомкнутой цепи. Однако в большинстве промышленных контроллеров, включая HI, внутренние подтягивающие резисторы уже встроены и активируются программно при выборе режима DI. Всегда сверяйтесь со схемой подключения конкретного датчика.

    Практический пример: чтение состояния кнопки и передача в MQTT Задача: При нажатии на настенную кнопку (подключена к универсальному входу №5) отправлять в MQTT-топик `hi/living_room/button/state` сообщение `{"state": "pressed"}`.
  • Физическое подключение: Кнопка без фиксации подключается к клеммам `UI-05` и `GND` контроллера согласно схеме `WIRING-SENS-007`.
  • Создание потока в Node-RED:
  •     [hi-ui-in: Кнопка в гостиной] --(msg)--> [change: Формат payload] --(msg)--> [mqtt out: Публикация состояния]

  • Конфигурация узлов:
  • * Узел `hi-ui-in` (Универсальный вход):

    * `Name`: `Кнопка в гостиной`

    * `Port`: `5`

    * `Mode`: `Digital Input (Dry Contact)`

    * `Debounce`: `50 ms` (защита от дребезга контактов)

    * Узел `change` (Изменение):

    * `Name`: `Формат payload`

    * Правило: `Set` `msg.payload` to (JSON) `{"state": "pressed"}`

    * Узел `mqtt out`:

    * `Topic`: `hi/living_room/button/state`

    * `QoS`: `1`

    * `Retain`: `false`

    Входящее сообщение от узла `hi-ui-in` в режиме DI будет иметь очень простой контракт сообщения:

    {
    

    "payload": true,

    "topic": "hi/ui/5"

    }

    Где `payload` равен `true` при замкнутом контакте (кнопка нажата) и `false` при разомкнутом.

    Настройка порта как аналогового входа (AI)

    Режим AI используется для измерения непрерывного сигнала, например, от датчика температуры с выходом 0-10В. Датчик преобразует физическую величину (например, температуру от -20 до +80 °C) в напряжение (от 0 до 10 В). Задача контроллера — измерить это напряжение и преобразовать его обратно в понятную величину.

    Формат `msg.payload` для AI:

    Узел `hi-ui-in` в режиме AI обычно выдает объект, содержащий как "сырое" значение, так и отмасштабированное.

    Пример обработки сигнала с аналогового датчика:
    // Пример кода для узла Function после hi-ui-in в режиме AI (0-10V)
    

    // Датчик температуры: -20°C = 0V, +80°C = 10V

    const volts = msg.payload.volts; // Предположим, узел выдает напряжение

    // Валидация

    if (typeof volts !== 'number' || volts < 0 || volts > 10.1) {

    node.error("Некорректное напряжение: " + volts, msg);

    return null;

    }

    // Масштабирование: линейная интерполяция

    const minTemp = -20;

    const maxTemp = 80;

    const minVolts = 0;

    const maxVolts = 10;

    const temperature = minTemp + ( (volts - minVolts) * (maxTemp - minTemp) / (maxVolts - minVolts) );

    // Формирование сообщения по стандартному контракту

    msg.payload = {

    value: parseFloat(temperature.toFixed(2)), // Округляем до 2 знаков

    unit: "°C",

    source: "temp-sensor-boiler-room",

    ts: Date.now()

    };

    node.status({fill:"green", shape:"dot", text: msg.payload.value + " °C"});

    return msg;

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

    ---

    Управление портами в режиме выхода (DO, AO)

    Контроллер HI оснащен 22 независимыми релейными выходами, которые работают в режиме дискретного выхода (DO). Они действуют как управляемые выключатели.

    > ⚠️ Внимание: Никогда не превышайте максимально допустимый ток для дискретных выходов (реле). Для коммутации мощной нагрузки (двигатели, насосы, группы розеток) всегда используйте промежуточное мощное реле или контактор. Реле контроллера управляет катушкой контактора, а контактор уже коммутирует силовую цепь. Это защищает контроллер от высоких пусковых токов и электромагнитных помех.

    Настройка порта как дискретного выхода (DO)

    Управление релейным выходом сводится к отправке на соответствующий узел Node-RED сообщения с `payload`, равным `true`/`false` или `1`/`0`.

    Пример: Управление светом по MQTT команде Задача: Включать/выключать свет в коридоре (реле №12) по команде из топика `hi/corridor/light/set`.
  • Физическое подключение: Фазный провод, идущий к лампе, подключается в разрыв через клеммы `C` (общий) и `NO` (нормально-открытый) реле `RL-12`.
  • Поток в Node-RED:
  •     [mqtt in: hi/corridor/light/set] --(msg)--> [hi-uo-out: Реле света в коридоре]

  • Конфигурация узлов:
  • * Узел `mqtt in`:

    * `Topic`: `hi/corridor/light/set`

    * Узел `hi-uo-out` (Универсальный/Релейный выход):

    * `Name`: `Реле света в коридоре`

    * `Port`: `12`

    * `Mode`: `Digital Output (Relay)`

    Чтобы включить свет, достаточно отправить в топик `hi/corridor/light/set` сообщение `true` или `1`. Чтобы выключить — `false` или `0`. Узел `hi-uo-out` поймет оба формата.

    Контракт сообщения для управления DO:
    {
    

    "payload": true

    }

    Или

    {
    

    "payload": 1

    }

    Настройка порта как аналогового выхода (AO)

    Хотя встроенные выходы контроллера HI — релейные (DO), концепция аналогового выхода (AO) 0-10В широко распространена в автоматизации для плавного управления. Она реализуется через модули расширения, подключаемые по RS-485. AO позволяет задавать уровень выходного напряжения от 0 до 10 Вольт.

    Типовые применения AO: Пример: Плавное диммирование LED-драйвера

    Представим, что у нас есть модуль расширения с аналоговыми выходами. Мы хотим управлять яркостью света, отправляя в `msg.payload` число от 0 до 100 (проценты).

    // Код в узле Function перед узлом аналогового выхода (hi-mod-ao-out)
    
    

    // Входное сообщение, например, от слайдера в dashboard

    // msg.payload = 80;

    let brightness = parseInt(msg.payload, 10);

    // Валидация

    if (isNaN(brightness) || brightness < 0) {

    brightness = 0;

    }

    if (brightness > 100) {

    brightness = 100;

    }

    // Преобразуем проценты (0-100) в вольты (0-10)

    const outputVolts = brightness / 10;

    // Формируем сообщение для узла аналогового выхода

    msg.payload = outputVolts;

    node.status({fill:"blue", shape:"dot", text: `Output: ${outputVolts.toFixed(1)} V`});

    return msg;

    Отправив на такой узел сообщение с `payload: 7.5`, мы установим на выходе AO напряжение 7.5В, что заставит LED-драйвер выставить яркость на 75%.

    ---

    Пример: создание логики климат-контроля

    Рассмотрим канонический пример замкнутой системы автоматизации: поддержание заданной температуры в комнате.

    Задача: Поддерживать температуру в помещении на уровне 22°C. Если температура падает ниже 21.5°C, плавно открывать клапан на радиаторе отопления. Если поднимается выше 22.5°C, плавно закрывать. * Аналоговый датчик температуры 0-10В (диапазон 0-50°C), подключен к `UI-01`.

    * Привод клапана отопления 0-10В (0В - закрыт, 10В - полностью открыт), подключен к аналоговому выходу `AO-01` (через модуль расширения).

        //========= WIRING-CLIMATE-001: Simple Thermostat =========
    
    

    // Analog Input (Temperature Sensor)

    (SENS:Temp:0-10V) [CTRL:HI-Core]

    +24V --------------- +24V (БП)

    GND --------------- GND (БП)

    Out --------------- UI-01

    GND --------------- GND (CTRL)

    // Analog Output (Valve Actuator via Extension Module)

    [EXT-MOD:AO-04]

    +24V --------------- +24V (БП)

    GND --------------- GND (БП)

    In --------------- AO-01 (Out)

    GND --------------- GND (Module)

        // [Inject: 10s] -> [hi-ui-in: Датчик T°] -> [Function: Логика термостата] -> [hi-mod-ao-out: Привод клапана]

    // ^ |

    // |------------<----[link in: setpoint]----[ui_slider: Уставка T°]----------+

    В этом потоке мы добавили возможность менять уставку (setpoint) с панели управления (dashboard).

    // Получаем уставку из контекста потока.
    

    // Она устанавливается другим потоком, например, от слайдера в dashboard.

    const setpoint = flow.get("climateSetpoint") || 22.0;

    // Диапазон температур датчика: 0..50 °C -> 0..10 V

    const currentVolts = msg.payload.volts;

    const currentTemp = currentVolts * 5.0; // Простое масштабирование: 10V = 50C -> 1V = 5C

    // --- Логика P-регулятора ---

    const error = setpoint - currentTemp; // Разница между желаемой и текущей температурой

    // Гистерезис (зона нечувствительности) для предотвращения частых переключений

    const hysteresis = 0.5; // °C

    let valvePosition = flow.get("lastValvePosition") || 0; // Текущее положение клапана

    if (error > hysteresis) {

    // Слишком холодно, нужно открывать клапан

    // Пропорциональный коэффициент (P). Подбирается экспериментально.

    const p_coeff = 20.0; // 1 градус ошибки = 20% открытия клапана

    valvePosition = error * p_coeff;

    } else if (error < -hysteresis) {

    // Слишком жарко, клапан нужно закрыть

    valvePosition = 0;

    }

    // Если температура внутри зоны гистерезиса, ничего не меняем.

    // Ограничиваем выходное значение в пределах 0-100%

    if (valvePosition > 100) valvePosition = 100;

    if (valvePosition < 0) valvePosition = 0;

    // Сохраняем последнее положение для следующего цикла

    flow.set("lastValvePosition", valvePosition);

    // Преобразуем проценты в вольты для аналогового выхода

    const outputVolts = valvePosition / 10.0;

    msg.payload = outputVolts;

    // Визуальный статус для отладки

    node.status({

    text: `T: ${currentTemp.toFixed(1)}°C | Set: ${setpoint}°C | Valve: ${valvePosition.toFixed(0)}%`

    });

    return msg;

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

    ---

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

    В этом уроке мы изучили фундаментальную концепцию универсальных входов/выходов (UI/UO), которая является основой для подключения большинства периферийных устройств к контроллеру HI.

    Краткий обзор режимов:

    > 🔗 Связанный материал: Данные, полученные с универсальных входов, особенно после форматирования в стандартный JSON-контракт, идеально подходят для публикации в топики MQTT, как мы изучали в уроке `COURSE-06-M04-L02: Работа с MQTT`. Это позволяет интегрировать показания локальных датчиков с облачными сервисами, панелями мониторинга и другими контроллерами.

    Частые ошибки при работе с универсальными портами:

  • Неправильное подключение "сухого контакта": Подключение к `+24V` вместо `GND` может вывести порт из строя. Всегда используйте клеммы `UI` и `GND`.
  • Превышение тока на релейном выходе (DO): Подключение мощной нагрузки напрямую к реле контроллера приводит к его быстрому износу и "залипанию". Используйте промежуточные контакторы.
  • Шумы и наводки на аналоговых входах (AI): Прокладка сигнального кабеля от датчика 0-10В в одном лотке с силовыми кабелями 230В приведет к нестабильным, "скачущим" показаниям. Используйте экранированный кабель и физически разделяйте трассы.
  • Ошибка в логике масштабирования: Неправильно указанные диапазоны (min/max) для датчика и напряжения приводят к неверным показаниям. Всегда дважды проверяйте документацию на датчик.
  • Что дальше?

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