ГлавнаяАкадемияДатчики и входы: нормализация сигналов → Практика: Чтение данных с датчика освещенности и отправка в люксах

Практика: Чтение данных с датчика освещенности и отправка в люксах

Урок 6 · Датчики и входы: нормализация сигналов · 30 мин · theory

Введение: от сырых данных АЦП к физическим величинам

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

> 🔗 Связанный материал: Этот урок является практическим применением концепций, рассмотренных в уроках по масштабированию и расширению контракта сообщения для аналоговых данных.

Любой аналоговый датчик в системе автоматизации является частью единого конвейера обработки данных:

  • Датчик: Физический элемент (например, фоторезистор) реагирует на изменение внешнего параметра (освещенность) и изменяет свои электрические характеристики (сопротивление).
  • Электронная обвязка: Схема датчика преобразует это изменение в стандартизированный аналоговый сигнал, например, напряжение в диапазоне от 0 до 10 Вольт.
  • АЦП контроллера: Наш контроллер HI считывает это аналоговое напряжение и преобразует его в дискретное цифровое значение. Это значение часто называют "сырыми" данными (raw data). Например, для 12-битного АЦП напряжению в 0В будет соответствовать значение 0, а напряжению в 10В — значение 4095.
  • Контроллер (Node-RED): Программная логика на контроллере получает эти "сырые" данные и выполняет их нормализацию и масштабирование — преобразование безразмерного числа (0-4095) в осмысленную физическую величину (например, 2500 люкс).
  • Без последнего шага — нормализации — данные с датчика бесполезны. Ни один сценарий автоматизации не может работать с абстрактными "попугаями" от АЦП; ему нужны конкретные, измеряемые величины.

    Цель этого практического урока — собрать с нуля полный, работающий сценарий для датчика освещенности. Мы пройдем все этапы: от физического подключения датчика к универсальному входу контроллера до создания потока в Node-RED, который считывает "сырые" данные, преобразует их в люксы и публикует в систему мониторинга по протоколу MQTT.

    ---

    Секция 1: Подключение датчика освещенности к универсальному входу

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

    > ⚠️ Внимание: Соблюдайте полярность! Неправильное подключение питания (VCC/GND) может повредить как сам датчик, так и универсальный вход контроллера. Всегда сверяйтесь с документацией на датчик и маркировкой клемм.

    ### Выбор и настройка универсального входа (UI)

    Контроллер HI оснащен универсальными входами, которые могут работать в нескольких режимах. Для нашей задачи нам нужен режим аналогового входа, способного измерять напряжение.

  • Выберите свободный универсальный вход: Для примера мы будем использовать вход `UI-08`.
  • Настройте режим входа: В веб-интерфейсе контроллера или с помощью специальной утилиты конфигурации переведите вход `UI-08` в режим "Аналоговый, 0-10В". Это настроит внутреннюю схему входа на корректное измерение напряжения в данном диапазоне.
  • Задокументируйте подключение: Сразу же внесите в проектную документацию, что вход `UI-08` теперь используется для датчика освещенности в гостиной. Маркировка `UI-08: LIGHT-SENS-LIVINGROOM` является хорошей практикой.
  • ### Схема подключения

    Большинство датчиков освещенности с аналоговым выходом 0-10В имеют три или четыре клеммы. Рассмотрим типовую схему подключения трехпроводного датчика.

    // Схема WIRING-SENS-LIGHT-001
    

    // Подключение датчика освещенности 0-10В

    [PSU: 24VDC] [CTRL:HI-Core] (SENS:Light:0-10V)

    +24V ------(Красный)---------------------------------- VCC

    GND ------(Черный)----+------------------------------ GND

    |

    +---- GND (на колодке UI)

    UI-08 -------------------- Signal

    (Оранжевый)

    ### Особенности монтажа датчика

    От правильного расположения датчика зависит адекватность всей системы автоматического управления освещением.

    | Место установки | Преимущества | Недостатки | Рекомендация |

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

    | На потолке, в центре комнаты | Измеряет среднюю, интегральную освещенность. | Может быть затенен высокими предметами. Сложность в обслуживании. | Оптимально для общего управления светом в помещении. |

    | На стене, напротив окна | Хорошо реагирует на естественный свет. | Может быть "ослеплен" прямыми солнечными лучами. | Подходит для сценариев "управление жалюзи/шторами". |

    | На стене, вдали от окон | Отражает освещенность в "темной" зоне. | Неадекватно реагирует на изменение естественного света. | Используется для локального управления подсветкой. |

    | Рядом с управляемым светильником | Прямая обратная связь от источника света. | Запрещено! Создает паразитную петлю обратной связи (включили свет -> датчик "видит" свет -> выключили свет -> датчик "не видит" -> включили...). | Избегайте любой ценой. |

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

    ---

    Секция 2: Чтение 'сырых' значений с АЦП в Node-RED

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

    Для работы с аналоговыми входами контроллера HI используется специальная нода `hi-analog-in`.

    ### Настройка потока для чтения данных

  • Откройте редактор Node-RED вашего контроллера.
  • Добавьте ноду `hi-analog-in`: Найдите ее в палитре в секции "HI Platform" и перетащите на рабочее поле.
  • Добавьте ноду `Debug`: Найдите ее в палитре и соедините с выходом ноды `hi-analog-in`.
  • Ваш начальный поток будет выглядеть предельно просто:

    `[hi-analog-in] -> [Debug]`

    ### Конфигурация ноды `hi-analog-in`

    Дважды кликните по ноде `hi-analog-in`, чтобы открыть ее настройки.

    После сохранения настроек и развертывания потока (кнопка Deploy), вы начнете видеть сообщения в окне отладки (вкладка Debug справа).

    ### Анализ 'сырых' данных

    Каждые 30 секунд нода `hi-analog-in` будет генерировать сообщение. Если вы кликнете на него в окне отладки, вы увидите его структуру. Содержимое `msg.payload` будет представлять собой простое число.

    2048
    

    Что это за число? Это и есть "сырое" значение от 12-битного АЦП. Оно пропорционально напряжению на входе `UI-08`.

    На данный момент мы подтвердили, что:

  • Датчик подключен правильно и получает питание.
  • Универсальный вход контроллера настроен и работает.
  • Поток Node-RED успешно считывает данные.
  • Теперь мы готовы к самому интересному — преобразованию этих абстрактных чисел в реальные люксы.

    ---

    Секция 3: Принцип масштабирования с помощью ноды Range

    Для преобразования "сырых" данных в физические величины мы будем использовать стандартную ноду `Range`. Как мы уже рассматривали ранее, эта нода выполняет простое линейное преобразование одного числового диапазона в другой.

    > 💡 Подсказка: Всегда изучайте документацию на датчик (datasheet). Ключевые параметры, которые вам нужны: диапазон измерения (в люксах) и соответствующий ему диапазон выходного напряжения (например, 0-10В). Эти данные — основа для правильной калибровки.

    ### Определение входного и выходного диапазонов

    Работа ноды `Range` основана на двух ключевых параметрах:

  • Входной диапазон (Source range): Это диапазон "сырых" значений, которые мы получаем от АЦП. Для 12-битного АЦП, используемого в контроллере HI, этот диапазон всегда будет от 0 до 4095.
  • * `Source min`: 0 (соответствует 0В на входе)

    * `Source max`: 4095 (соответствует 10В на входе)

  • Выходной диапазон (Target range): Это диапазон физических величин, в которые мы хотим преобразовать наши данные. Эти значения мы должны взять из документации на наш датчик освещенности. Допустим, мы используем датчик, у которого:
  • * Выходное напряжение 0В соответствует освещенности 0 люкс.

    * Выходное напряжение 10В соответствует освещенности 5000 люкс.

    * Таким образом, наш целевой диапазон: от 0 до 5000.

    * `Target min`: 0

    * `Target max`: 5000

    ### Допущение о линейности

    Используя ноду `Range`, мы делаем важное допущение: мы считаем, что зависимость выходного напряжения датчика от измеряемой освещенности является линейной. Это означает, что увеличению освещенности на 100 люкс всегда соответствует одинаковое изменение напряжения, вне зависимости от того, происходит это в темноте или при ярком свете.

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

    На текущем этапе мы остановимся на линейной модели, так как она покрывает 95% всех практических кейсов и идеально подходит для нашего уровня "Installer".

    ---

    Секция 4: Настройка ноды Range для преобразования в люксы

    Теперь, когда у нас есть все необходимые данные, мы можем добавить и настроить ноду `Range` в нашем потоке Node-RED.

  • Найдите ноду `Range` в палитре (обычно в секции "function") и перетащите ее на рабочее поле.
  • Вставьте ее в поток: Разорвите связь между `hi-analog-in` и `Debug`, а затем вставьте ноду `Range` между ними.
  • Ваш поток должен теперь выглядеть так:

    `[hi-analog-in] -> [Range] -> [Debug]`

    ### Практический пример конфигурации

    Дважды кликните по ноде `Range`, чтобы открыть ее настройки. Заполните поля следующим образом:

    После сохранения настроек и развертывания потока, посмотрите на сообщения, которые теперь приходят в окно отладки.

    ### Проверка результата

    Раньше, при "сыром" значении `2048`, мы видели в `msg.payload` просто число `2048`. Теперь, после прохождения через ноду `Range`, `msg.payload` будет содержать число с плавающей точкой.

    `msg.payload` до ноды `Range`:

    2048
    

    `msg.payload` после ноды `Range`:

    2500.6105006105006
    

    Нода `Range` выполнила линейное преобразование: `(2048 / 4095) * 5000 ≈ 2500.6`. Теперь это не абстрактное значение, а вполне конкретная величина — освещенность в люксах (лк).

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

    ---

    Секция 5: Форматирование и отправка данных в MQTT

    Наш поток уже выдает правильные значения, но для совместимости с другими системами (например, панелями визуализации или системами сбора данных) мы должны передавать данные в стандартизированном формате, соблюдая "Контракт сообщения".

    > 🔗 Связанный материал: Мы используем расширенный контракт сообщения, который подробно описан в уроках, посвященных работе с данными. Стандартный формат включает само значение и единицу его измерения.

    Стандартный формат объекта для телеметрии:

    {
    

    "value": 2500.61,

    "unit": "lx"

    }

    ### Использование ноды `Change` для форматирования

    Для преобразования нашего числового `msg.payload` в структурированный JSON-объект мы будем использовать ноду `Change` с выражением JSONata.

  • Добавьте ноду `Change` после ноды `Range`.
  • Добавьте ноду `mqtt out` после ноды `Change`.
  • Переподключите ноду `Debug` к выходу ноды `Change`, чтобы видеть финальный результат.
  • Ваш финальный поток должен выглядеть так:

    `[hi-analog-in] -> [Range] -> [Change] -> [mqtt out]`

    ` |`

    ` +--> [Debug]`

    Дважды кликните по ноде `Change` и настройте одно правило:

    Это выражение JSONata берет текущее значение `msg.payload` (которое является числом после ноды `Range`), помещает его в поле `value` нового объекта и добавляет поле `unit` со строковым значением `"lx"`.

    ### Настройка ноды `mqtt-out`

    Последний шаг — публикация данных в MQTT. Дважды кликните по `mqtt-out`.

    Теперь, после развертывания, наш поток каждые 30 секунд выполняет полный цикл:

  • Считывает "сырое" значение с входа `UI-08`.
  • Масштабирует его в люксы.
  • Форматирует в стандартный JSON-объект.
  • Публикует в MQTT-топик.
  • В окне отладки вы увидите финальный, правильно отформатированный объект:

    {
    

    "value": 2500.6105006105006,

    "unit": "lx"

    }

    ---

    Заключение: Полный сценарий и дальнейшие шаги

    В рамках этого практического урока мы с нуля создали полноценный и надежный сценарий для работы с аналоговым датчиком освещенности. Мы прошли весь путь: от зачистки провода и закручивания клеммы до настройки MQTT-топика и проверки JSON-объекта.

    Мы успешно:

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

    ### Что дальше?

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