Привет, Хабр!

В этой статье я хочу описать свой опыт разработки такого простого, но в тоже время самого используемого элемента «Умного дома». Речь пойдет о модуле управления освещением. Забегая вперед, хочу сказать, что данный проект был реализован еще в 2021 году, но в настоящее время потребовалась реализация еще одного модуля. Я решил совместить приятное с полезным, дополнительно обновить прошивку устройства и «перепроектировать» данный модуль с помощью современного ПО и само собой — поделиться с вами. Если стало интересно, то добро пожаловать под кат.

Небольшая предыстория


Домашней автоматизацией я занимаюсь давно и застал те времена, когда еще не было доступных микроконтроллеров с беспроводной коммуникацией на борту (типа ESP8266), в основном использовались проводные решения на базе 1-Wire. И мой «Умный дом» не стал исключением.

Каждый начинающий «строитель» «Умного дома» понимает, что первым делом нужно научиться включать и выключать свет, чтобы эффектно удивлять друзей, управляя освещением со смартфона. В те времена это казалось магией :) Вот и я, закупившись на Алиэкспрессе поддельными двухканальными 1- Wire свичами DS2413P, решил реализовать управление светом. В итоге была собрана плата управления на базе купленных свичей и симисторным управлением нагрузкой. Данное устройство надежно проработало аж до 2021 года. Но летом того же года была жуткая гроза и по витой паре интернет провайдера прилетел мощный разряд, который унес в электронный рай сетевую карту сервера, USB 1-Wire адаптер, ну и плату управления освещением с эффектным взрывом симистора. Тогда я подумал, что пора завязывать с проводными решениями ибо гирлянда сгоревших устройств ни на секунду меня не радовала и я принялся за разработку беспроводного модуля управления освещением.

Проектируем аппаратную часть


Условно мы можем разделить модуль на три сегмента:

  • Система питания;
  • Контроллер управления;
  • Система силового управления.

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

Краткая информация о LNK306GN
LNK306GN — это понижающий преобразователь с наименьшим количеством внешних элементов.
Серия микросхем LinkSwitch-TN специально разработана для замены всех неизолированных источников питания с линейным питанием и питанием от конденсаторов в диапазоне выходного тока менее 360 мА при равной стоимости системы, обеспечивая гораздо более высокую производительность и энергоэффективность.
Устройства LinkSwitch-TN объединяют в монолитной IC силовой полевой МОП-транзистор с напряжением до 700 В, генератор, простую схему управления включением/выключением, высоковольтный импульсный источник тока, генератор частот, схему ограничения тока и схему отключения при перегреве.

В качестве «мозга» нашего устройства, будем использовать микроконтроллер от компании Espressif Systems ESP8266. А для силового управления нагрузкой, то есть нашими лампочками, будем использовать связку оптопары MOC3052M и симистора BT136-600. Почему не реле? — спросите вы, ну не люблю я реле, они щелкают и габаритные. Ниже можно видеть результат разработки принципиальной схемы устройства. Для разработки схем и печатных плат я использую открытое ПО KiCAD.

Принципиальная схема модуля:


Как я уже говорил ранее, источник питания реализован на высоковольтном импульсном преобразователе LNK306GN, который позволяет максимально упростить схему источника питания. На выходе источника формируется напряжение в 3,3 В, данное напряжение устанавливается обратной связью, которая организована с помощью резистивного делителя напряжения R4 и R5. Данная схема питания не имеет гальванической развязки с сетью, поэтому нужно обеспечить эффективную изоляцию платы для исключения поражения электрическим током. Первоначальный запуск устройства должен выполняться с последовательно подключенной нагрузкой (лампа накаливания 60 Вт) в цепи питания, чтобы исключить повреждения в случае ошибки при монтаже компонентов.

Трассировка платы:


Визуализация печатной платы:


Хочется добавить, что данная плата разрабатывалась с учетом современных реалий, здесь изменен форм-фактор микросхемы LNK306GN на SOP-7 в старой версии модуля используется тип корпуса DIP-7.

Изготовление печатной платы


На тот момент, плата изготавливалась по канонам DIY, с помощью фоторезиста и фотошаблона. Но в настоящее время я пользуюсь для изготовления прототипов плат лазерным методом.

Активация фоторезиста с помощью фотошаблона:


Плата прототипа модуля после монтажа электронных компонентов:


Разработка корпуса


Разработка корпуса устройства выполнялось в открытом ПО FreeCAD. Корпус довольно тривиальный и не содержит сложных элементов.

Визуализация корпуса с моделью платы:


Далее модель корпуса распечатывается на 3D принтере, в качестве материала печати используется HIPS пластик.

Устройство в собранном виде:


AirTag для сравнения габаритов устройства:


Разработка прошивки и описание интерфейса


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

  • Captive portal;
  • Multicast DNS;
  • MQTT Auto Discovery;
  • SSDP.

Captive portal — это сервис, на который принудительно перенаправляется пользователь, который выполнил подключение к устройству. Данный сервис работает только в режиме «точки доступа» при первоначальной конфигурации устройства. При отсутствии сетевого соединения или при первоначальной настройке, устройство создает беспарольную точку доступа с именем CYBEREX-Light. При подключении к данной точке доступа, пользователь автоматически будет перенаправлен на страницу авторизации для выполнения первоначальной конфигурации устройства. Для конфигурации устройства необходимо ввести пароль по умолчанию "admin".

Ниже приведены несколько скриншотов веб интерфейса устройства.

Страница входа:


Главная страница с элементами управления:


Конфигурация обмена по MQTT протоколу:



Multicast DNS — данный сервис используется для поиска устройств по доменному имени в локальной сети без использования предварительно настроенного DNS сервера. Другими словами, пользователь может получать доступ к устройству без необходимости ввода IP адреса. Ниже пример использования данного сервиса, где доступ к устройству выполняется с помощью его локального имени 11395386.local.

Страница конфигурации управления устройством через API:


Как вы можете видеть на скриншоте, в устройстве реализован доступ управления каналами модуля по API. Данная функция необходима для прямого взаимодействия с устройством без посредников в виде MQTT сервера или системы «Умного дома». Эту функцию можно использовать для подключения беспроводных выключателей, пример реализации в одном из моих проектов:


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

А еще функция данного API применяется в моей «умной колонке» (статья первая, статья вторая) для управления освещением. Ниже пример кода для реализации прямого управления с помощью «умной колонки»:

Код управления по API | Python
    elif cmd == 'lightON':
        try:
           contents = urllib.request.urlopen("http://11395386.local/?page=status&apikey=UkFA7").read()
           response0 = json.loads(contents)
           if response0['c1'] == 'Off1' and response0['c2'] == 'Off2':
               text = "Включила свет"
           if response0['c1'] == 'On1' and response0['c2'] == 'Off2':
               text = "Первый светильник уже включен, включила второй!"
           if response0['c1'] == 'Off1' and response0['c2'] == 'On2':
               text = "Второй светильник уже включен, включила первый!"
           if response0['c1'] == 'On1' and response0['c2'] == 'On2':
               text = "Свет уже включен! Но я могу выключить, если попросите!"
           if response0['c1'] == 'Off1':
               response2 = requests.get('http://11395386.local/?page=control&apikey=UkFA7&switch=1')
           if response0['c2'] == 'Off2':
               response2 = requests.get('http://11395386.local/?page=control&apikey=UkFA7&switch=2')
           tts.va_speak(text)
        except:
             tts.va_speak("Сожалею, но возникла ошибка, попробуйте позже!")
        

    elif cmd == 'lightOFF':
        try:
           contents = urllib.request.urlopen("http://11395386.local/?page=status&apikey=UkFA7").read()
           response0 = json.loads(contents)
           if response0['c1'] == 'Off1' and response0['c2'] == 'Off2':
               text = "Свет уже выключен! Но я могу включить, если попросите!"
           if response0['c1'] == 'On1' and response0['c2'] == 'Off2':
               text = "Второй светильник уже выключен, выключила первый!"
           if response0['c1'] == 'Off1' and response0['c2'] == 'On2':
               text = "Первый светильник уже выключен, выключила второй!"
           if response0['c1'] == 'On1' and response0['c2'] == 'On2':
               text = "Выключила свет!"
           if response0['c1'] == 'On1':
               response2 = requests.get('http://11395386.local/?page=control&apikey=UkFA7&switch=1')
           if response0['c2'] == 'On2':
               response2 = requests.get('http://11395386.local/?page=control&apikey=UkFA7&switch=2')
           tts.va_speak(text)
        except:
             tts.va_speak("Сожалею, но возникла ошибка, попробуйте позже!")


Интеграция в «Умный дом»


Интеграция устройства в систему «Умного дома» реализована с помощью MQTT Auto Discovery.
MQTT Auto Discovery — сервис, позволяющий максимально упростить интеграцию нашего устройства в систему «Умного дома». В моем случае, в качестве системы «умного дома», я использую Home Assistant, поэтому сервис MQTT Auto Discovery адаптирован именно под неё. Ниже код реализации MQTT Auto Discovery в микро ПО устройства:

Код реализации MQTT Auto Discovery | С++
void send_mqtt(String tops, String data, String subscr){
     // Анонсируем объекты для Home Assistant [auto-discovery ]
     // Анонсируем объекты один раз при успешном подуключении и при запуске устройства
    // if(!annonce_mqtt_discovery){
           mqqt_d_annonce("CL1", "c1", "On1", "Off1");
           mqqt_d_annonce("CL2", "c2", "On2", "Off2");
           mqqt_d_annonce("CL3", "c3", "On3", "Off3");

           annonce_mqtt_discovery = true;
    // }
    // Отправляем данные 
    client.publish(tops.c_str(), data.c_str());
    client.subscribe(subscr.c_str());
}

void mqqt_d_annonce(String namec, String cn, String on_d, String off_d){

          String top      = String(settings.mqtt_topic) +"/jsondata";
          String control  = String(settings.mqtt_topic) +"/control";
          char jsonBuffer[1024] = {0};
          
          DynamicJsonDocument chan1(1024);
                              chan1["name"]                 = namec;
                              chan1["state_topic"]          = top;
                              chan1["command_topic"]        = control;
                              chan1["payload_on"]           = on_d;
                              chan1["payload_off"]          = off_d;
                              chan1["state_value_template"] = "{{ value_json."+cn+" }}";
                              
           serializeJson(chan1, jsonBuffer, sizeof(jsonBuffer));
           String top_to = "homeassistant/light/"+cn+"/config";
           client.publish(top_to.c_str(), jsonBuffer, true);
}


После успешного подключения устройства к сети и настройки MQTT соединения, в «объектах» Home Assistant появятся объекты нашего устройства, пользователю останется только настроить карточку объектов на панели управления, чтобы иметь возможность управлять данным модулем. Ниже приведен пример кода карточки объектов:

Пример кода карточки объектов
type: horizontal-stack
cards:
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: toggle
    entity: light.cl1
    name: Свет 1
    show_state: true
    hold_action:
      action: more-info
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: toggle
    entity: light.cl2
    name: Свет 2
    show_state: true
    hold_action:
      action: more-info
  - show_name: true
    show_icon: true
    type: button
    tap_action:
      action: toggle
    entity: light.cl3
    name: LED
    show_state: true
    hold_action:
      action: more-info


В результате карточка объектов будет выглядеть следующим образом:


Осталось упомянуть о последнем сервисе SSDP.
Чтобы как-то «повелевать» всем зоопарком моих умных устройств, был реализован данный сервис.

SSDP (Simple Service Discovery Protocol) — сетевой протокол, основанный на наборе протоколов Интернета, служащий для объявления и обнаружения сетевых сервисов. SSDP позволяет обнаруживать сервисы, не требуя специальных механизмов статической конфигурации или действий со стороны серверов, таких как DHCP или DNS.
Для моего удобства, я написал мобильное приложение, которое позволяет в три нажатия обнаружить и сконфигурировать устройство без лишних хлопот и похода в роутер. Ниже представлены скриншоты приложения, ссылка на приложение будет размещена в конце статьи.

Приложение для поиска устройств в сети:


Использование аппаратного выключателя


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

Итоги


Ну что ж, давайте подведем итоги. В итоге у нас получилось простое, но эффективное и относительно компактное устройство для управления освещением, с возможностью работы как в автономном режиме, так и в составе «Умного дома». Данное устройство разрабатывалось, прежде всего, для управления светодиодным освещением, но примененные силовые симисторы позволяют коммутировать осветительную нагрузку до 300Вт на канал, без ощутимого нагрева силовых элементов.

На этом можно и завершить статью. Надеюсь, мой опыт будет вам полезен. Если у вас есть замечания, предложения или вы хотите поделиться подобным опытом, то добро пожаловать в комментарии! Если статья вам понравилась, то поддержите её стрелочной вверх. Всем добра, здоровья и спасибо за внимание!

Ссылки к статье:





? Читайте также:

Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram-канале

Комментарии (24)


  1. Kill_Voice
    12.08.2024 13:34
    +2

    Интересно, но при огромной количестве на рынке готовых модулей, совершенно непонятно зачем...


    1. CyberexTech Автор
      12.08.2024 13:34
      +6

      Творчество и удовольствие от разработки


      1. Soorin
        12.08.2024 13:34

        Возможно, тогда следовало-бы назвать эту статью "Ещё одно беспроводное реле"? Ничего особо "умного" я в этом "велосипеде" не увидел - ни хитрой логики и датчиков, ни кастомных сценариев умного дома.. Много времени потрачено на разработку/прототипирование, много слов силы изучено. Следующий шаг - питание по одной фазе, без нейтрали, и следствие - ZigBee, как у массы подобных микрореле (Sonoff ZBMINI-L).


        1. Kononvaler
          12.08.2024 13:34
          +1

          Таки лучше чем статьи как ктото подключил зигби или еще какую готовую ни шагу вбок фигню. А тут человек поработал головой.

          Ничего плохого в статье нет, вполне имеет место быть. Тут сто путей может быть.

          Среди которых зигби я в конец имхо поставил бы.


    1. Kononvaler
      12.08.2024 13:34

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


      1. Kill_Voice
        12.08.2024 13:34

        Так есть и проприетарные решения, есть и на стандартных протоколах ZigBee, Matter, KNX, и тп. Заводите всё в home assistant и никакого "одеяла"


        1. Kononvaler
          12.08.2024 13:34

          Ну мне вот абсолютно не уперся хоумассистанс, предпочитаю делать своё на node-red без чужих лоскутов.


          1. Kill_Voice
            12.08.2024 13:34

            node-red это только среда исполнения сценариев, она устройствами не управляет, вам в любом случае нужен координатор HA это или какие-то другие "лоскуты" уже на ваш вкус


            1. Kononvaler
              12.08.2024 13:34

              устройства цепляются к NR через mqtt, для NR есть модули как с алисой и ха, так и телеграм и т.п.


  1. zeblong
    12.08.2024 13:34

    Интересно где это и как установлено? Я когда то тоже делал подобное но пытался подразетник запихнуть. Ну и еще не понятно вот что - столь развесистая программная часть а нет диммера. Почему?


    1. CyberexTech Автор
      12.08.2024 13:34

      Установлено снаружи, эстетику не портит. Диммер в данном случае ни к чему, модуль управляет светодиодным освещением.


  1. gudvinr
    12.08.2024 13:34
    +1

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


    1. CyberexTech Автор
      12.08.2024 13:34

      Наверное вы правы, но по моему опыту каких-то ухудшений качества сигнала я не наблюдал.


    1. okhsunrog
      12.08.2024 13:34

      Да, тоже только что хотел написать про это. Ещё и толстая дорожка практически под антенной идёт. Антенну выносить надо на край платы, и автору посоветую смотреть Hardware Design Guidelines от Espressif: https://www.espressif.com/sites/default/files/documentation/esp8266_hardware_design_guidelines_en.pdf


  1. Kononvaler
    12.08.2024 13:34

    Почему не реле спросите вы...

    Почему не сразу оптическое твердотельное реле без оптопары и симистора.спрошу я.

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

    И почему не esp32? С вифи на борту


    1. Unit20
      12.08.2024 13:34

      Почему не обычный симистор по типичной схеме стиральных машин, когда БП генерирует отрицательное напряжение относительно Т1 вывода симистора?

      Нет предела совершенству, поэтому лучше сделать несколько версий, чем увязнуть в бесконечной разработке одной имхо


      1. Kononvaler
        12.08.2024 13:34

        Посмотрите AQH3213
        на выкл/вкл за глаза хватит. один резистор от GPIO esp к ней и больше ничего вообще


    1. CyberexTech Автор
      12.08.2024 13:34

      И почему не esp32? С вифи на борту

      Стараюсь считать экономику проекта, в данном проекте применение esp32 избыточно и не целесообразно по ряду причин.


  1. smoluks4096
    12.08.2024 13:34

    У меня все устройства с LNK30* трещат катушкой, ибо у них топология Simple Switcher - они не ШИМ, не умеют изменять скважность, а просто выход с заданной скважностью либо включен, либо нет - и если нагрузка не очень велика, они включаются и выключаются с какой-то частотой, что создает слышимый шум. Увести его по частоте ниже или выше слышимости человеком не удалось, заливка и изоляция катушки сделали звук тише, но ночью все равно слышно.
    Немного помогает взять микросхему на меньший ток - например LNK304 - токовая защита там таки может уменьшить скважность.
    Получилось ли решить эту проблему?


    1. CyberexTech Автор
      12.08.2024 13:34

      Попробуйте использовать CDRH74NP они не шумят.


  1. CyberexTech Автор
    12.08.2024 13:34

    Попробуйте использовать CDRH74NP они не шумят.


  1. BigBeaver
    12.08.2024 13:34

    Выглядит интересно, но клеммы не хлипковаты?

    Платы без маски не страшно использовать в таком приборе? Я бы залачил.


    1. CyberexTech Автор
      12.08.2024 13:34

      Клеммники отличные, разъёмные XY2500FB-5.08-2P рассчитаны на ток 12 А. Что касается маски, да, в последних версиях я наношу на плату паяльную маску. Но как показывает многолетняя практика использования, без паяльной маски тоже надёжно работает.


      1. BigBeaver
        12.08.2024 13:34

        Поидее, все кабели и соединения должны иметь номинальный ток не менее, чем у автомата отключения.