Обзор универсальных входов/выходов контроллера
Введение в универсальные входы/выходы (UI/UO)
ведение в универсальные входы/выходы (UI/UO)
В основе гибкости контроллеров платформы HI лежат универсальные входы/выходы (UI/UO). Это физические порты, которые, в отличие от специализированных интерфейсов типа DALI или CAN-шины, могут быть программно сконфигурированы для выполнения различных задач. Каждый из 22 универсальных портов контроллера может работать либо как вход для получения данных от внешнего мира, либо как выход для управления исполнительными механизмами.
Архитектурное отличие универсального порта от специализированного заключается в его многозадачности. Если порт DALI предназначен исключительно для управления освещением по одноименному протоколу, то универсальный порт может быть сегодня входом для кнопки, завтра — выходом для управления приводом клапана, а послезавтра — входом для аналогового датчика давления. Эта гибкость позволяет инженеру-интегратору адаптировать один и тот же контроллер под совершенно разные задачи на объекте, будь то умный дом, гостиничный номер или небольшой производственный цех.
> 📋 Ключевые понятия:
> * Универсальный Вход (UI - Universal Input): Порт, сконфигурированный на приём сигнала.
> * Универсальный Выход (UO - Universal Output): Порт, сконфигурированный на передачу управляющего сигнала. На нашем контроллере выходы являются релейными, но мы также рассмотрим концепцию аналоговых выходов, реализуемых через внешние модули или специализированные порты.
Универсальные порты контроллера HI поддерживают несколько ключевых режимов работы, покрывающих до 80% типовых задач автоматизации.
Обзор поддерживаемых режимов
* Кнопок и выключателей (в том числе типа "сухой контакт").
* Датчиков движения с релейным выходом.
* Герконов (датчиков открытия окон/дверей).
* Датчиков протечки воды.
* Датчики температуры, влажности, давления.
* Датчики освещённости.
* Датчики уровня 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"}`.
[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 обычно выдает объект, содержащий как "сырое" значение, так и отмасштабированное.
- `raw`: Значение АЦП (Аналого-цифрового преобразователя), например, 0-4095.
- `volts`: Измеренное напряжение, например, 5.34 В.
- `value`: Отмасштабированное значение, например, 25.5 (°C).
// Пример кода для узла 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`.
[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-драйверами 0-10В.
- Управление приводами клапанов систем отопления и вентиляции.
- Задание скорости вращения для частотных преобразователей.
Представим, что у нас есть модуль расширения с аналоговыми выходами. Мы хотим управлять яркостью света, отправляя в `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В - закрыт, 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)
- Поток в Node-RED:
// [Inject: 10s] -> [hi-ui-in: Датчик T°] -> [Function: Логика термостата] -> [hi-mod-ao-out: Привод клапана]
// ^ |
// |------------<----[link in: setpoint]----[ui_slider: Уставка T°]----------+
В этом потоке мы добавили возможность менять уставку (setpoint) с панели управления (dashboard).
- Код для узла `Function: Логика термостата`:
// Получаем уставку из контекста потока.
// Она устанавливается другим потоком, например, от слайдера в 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.
Краткий обзор режимов:- DI (Дискретный вход): Для кнопок, герконов, датчиков с выходом "сухой контакт". Дает ответ `true`/`false`.
- AI (Аналоговый вход): Для датчиков с выходом 0-10В. Позволяет измерять физические величины (температура, влажность). Требует масштабирования.
- DO (Дискретный выход): Для управления реле, контакторами, индикаторами. Управляется командами `true`/`false`.
- AO (Аналоговый выход): Для плавного управления диммерами, приводами. Управляется числом (0-10В).
> 🔗 Связанный материал: Данные, полученные с универсальных входов, особенно после форматирования в стандартный JSON-контракт, идеально подходят для публикации в топики MQTT, как мы изучали в уроке `COURSE-06-M04-L02: Работа с MQTT`. Это позволяет интегрировать показания локальных датчиков с облачными сервисами, панелями мониторинга и другими контроллерами.
Частые ошибки при работе с универсальными портами:
Что дальше?
Освоив работу с базовыми входами и выходами, вы готовы к следующему шагу — интеграции с более сложными устройствами по цифровым промышленным шинам. В следующем уроке мы подробно разберем протокол Modbus, который является стандартом де-факто для взаимодействия с профессиональным инженерным оборудованием: счетчиками электроэнергии, модулями ввода-вывода, чиллерами и вентиляционными установками.