Авторизация
Регистрация

Напомнить пароль

Безумный радиошлюз для контроля освещения и многого другого

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

Как уже было упомянуто в статье, «сенсорность» не то чтобы нужна этим выключателям, так что все сенсоры были заменены на кнопки. Это позитивно отразилось и на эстетике, и на удобстве использования, а число ложных срабатываний снизилось до нуля. Но основная часть выключателя осталась почти незадействована — радиореле.

Проект

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

Да и заведены на удаленный сервер. А я привык к локальному управлению через сервер HomeAssistant, так что буду делать свой с нуля!

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

Поскольку с прошивкой уже понятно, смотрим, что надо по железу. Для управления устройствами хватит и дешевого китайского передатчика 433 FS1000A — это будут «руки» нашего устройства. 

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

Чтобы управлять светом, необходимо «увидеть», кто находится в помещении. «Глазами» выступит LD2420 — 25 ГГц микроволновый датчик присутствия. Довольно полезный модуль, который, ко всему позволяет определить расстояние до ближайшего объекта. и стоит около 130 рублей за штуку.

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

Мозгом шлюза выступит дешевый модуль D1 Mini на основе ESP8266, который я недавно брал по 100 рублей с АлиЭкспресс. Несмотря на дешевизну он совсем не немощный, и легко заткнет за пояс обычную «ардуинку» по возможностям.

Хотя после недавней скидки в ДНС я бы не назвал его таким уж дешевым — там я накупил полноценных умных лампочек на ESPHome-совместимом контроллере CB2S. За 80 рублей в них еще и корпус, и светодиоды, и питание… О приключениях с этими штуками я расскажу чуть попозже.

Итак, вернемся к нашим баранам. У нас есть «глаза», «уши», «руки», «мозг». Казалось бы, уродец готов! Но нет, ему необходимо «сердце», а им выступит блок питания на 5V от какой-то ненужной уже зарядки. 

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

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

С компонентами разобрались — переходим к пайке. Для соединения модулей (с малым потреблением тока) и антенн я использую провода IDE шлейфов. В свое время я не придумал, куда их применить. Теперь же не могу представить, что бы я без них делал!

Радиомодули соединяются тремя проводами — земля, плюс питания и сигнал (у приемника пин дублируется). Еще один провод длиной 17.3см (для 433 МГц; для 315 МГц нужен 23см), скрученный в катушку, используется как антенна. Можно антенну не паять, но дальность и качество приема не будет радовать.

Для датчика LD2420 необходимо минимум 3 провода, хотя можно подсоединить хоть 5. Два провода отвечают за питание 3.3В, два за общение модуля по UART и дополнительный бинарный вывод датчика (есть присутствие или нет). Таким образом, датчик может быть единожды откалиброван по UART даже без микроконтроллера, а затем приспособлен к реле и уже самостоятельно управлять освещением. Однако такой подход подходит скорее для уличного света, он не очень точен. 

Я решил использовать постоянное подключение по UART для получения значения расстояния до объекта и возможности калибровки «на лету». Да и для статистики в умном доме может пригодиться.

Можно также подключить все 5 проводов, но в прошивке использовать только бинарный вывод. В этом на самом деле тоже есть смысл. Датчик достаточно серьезно нагружает контроллер и, если в устройстве много сложной периферии, для стабильности лучше оставить бинарный выход, а по мере надобности конфигурировать LD2420 по UART.

Модуль D1 Mini уже оснащен всей необходимой периферией и просто подключается к остальным и к питанию. Общую схему прилагаю.

В корпусе модули распихал по углам и приклеил двусторонним скотчем. Главное в этом деле хорошо изолировать высоковольтную часть блока питания от низковольтной электроники. Делается это с помощью того же двустороннего скотча и воздушной прослойки. Но можно заморочиться и применить термоусадку. Я этого делать не стал.

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

Установка шлюза довольно простая — я просто прилепил его на двустороннюю ленту к крышке распределительной коробки. Провода соединил через клеммную колодку Подключаем питание и… Поехали!

 

Правда, поедем недалеко. Устройство появилось в сети, но еще ничего не умеет. Добавляем в конфигурацию радиоприемник и передатчик, а также датчик присутствия.

esphome:
 name: rf-bridge
 friendly_name: "RF Bridge"
# --- Платформа: подправьте под своё устройство (esp8266/esp32)
esp8266:
 board: D1 Mini
# --- Сеть: заполните свои данные
wifi:
 ssid: "YOUR_SSID"
 password: "YOUR_PASSWORD"
 # (опционально) static_ip, ap и т.п.
logger:
 level: DEBUG
api:
ota:
# --- Remote receiver (приёмник)
remote_receiver:
 - id: rf_rx
   pin:
     number: D3
     inverted: true
     mode:
       input: true
       pullup: true
   dump: [rc_switch, raw, pronto]   # дамп в логи (DEBUG)
   tolerance: 60%
   filter: 4us
   idle: 4ms
   # автоматически вызывается при декодировании RCSwitch
   on_rc_switch:
     - lambda: |-
         // Логируем сырые данные
         ESP_LOGI("rc_switch", "Received RCSwitch protocol=%d data='%s'", x.protocol, x.data.c_str());
         // публикуем в текстовый сенсор для отображения в HA
         id(last_rf).publish_state(x.data);
         // если 24 бита — пометим как EV1527-подобное (по описанию EV1527 часто 24 бита)
         if (x.data.size() == 24) {
           ESP_LOGI("rc_switch", "EV1527-like 24-bit code detected: %s", x.data.c_str());
         }
# --- Remote transmitter (передатчик)
remote_transmitter:
 pin: D4
 carrier_duty_percent: 100%   # для 433MHz модулей ставят 100%
# --- Текстовый сенсор: последний принятый код
text_sensor:
 - platform: template
   name: "Last RF Code"
   id: last_rf
uart:
 - id: ld2420_uart
   tx_pin: D2# LD2420 TX -> ESP RX
   rx_pin: D1# LD2420 RX <- ESP TX
   baud_rate: 115200  # или 256000 для старых прошивок
   parity: NONE
   stop_bits: 1
# --- Компонент LD2420
ld2420:
# Версия прошивки (текстовый сенсор)
text_sensor:
 - platform: ld2420
   fw_version:
     name: "LD2420 FW Version"
# Наличие цели (presence)
binary_sensor:
 - platform: ld2420
   has_target:
     name: "LD2420 Presence"
     id: ld_presence
# Расстояние до движущейся цели (приблизительно, в шагах по 0.7 м)
sensor:
 - platform: ld2420
   moving_distance:
     name: "LD2420 Moving Distance"
     id: ld_distance
# Параметры/калибровка (удобно менять из UI)
select:
 - platform: ld2420
   operating_mode:
     name: "LD2420 Mode"
number:
 - platform: ld2420
   presence_timeout:
     name: "LD2420 Presence Timeout"
button:
 - platform: ld2420
   apply_config:
     name: "LD2420 Apply Config"
   factory_reset:
     name: "LD2420 Factory Reset"
   restart_module:
     name: "LD2420 Restart Module"

А теперь собственно, суть дела. У меня три радиореле на первом этаже, а также люстра с двойным управляемым освещением (теплое  и холодное) и еще одно радиореле на втором. 

Реле будут управляться двумя сигналами — один на включение, один на выключение. Использование одного сигнала для вкл/выкл может привести к неприятным ситуациям. Скажем, сигнал на выключение не дошел (обратной связи-то нет) и свет будет считаться выключенным, а потом, когда его надо будет включить, сигнал его выключит. В общем, сделано это, чтобы сервер не гадал, что будет делать лампочка при передаче сигнала. На люстре, к сожалению, такой опции нет.

Поскольку все реле имеют режим сопряжения, я просто сгенерировал 10 24-битовых последовательностей, используя сайт (4 пары для реле с вкл-выкл сигналами, и 2 одиночных для люстры). Потом можно будет привязать их к соответствующим устройствам.

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

button:
 - platform: template
   name: "1F Relay 1 ON"
   on_press:
     - remote_transmitter.transmit_rc_switch_raw:
         code: '0110001011010100011010100'  # исходный + '0'
         protocol: 1
         repeat:
           times: 10
           wait_time: 10ms
 - platform: template
   name: "1F Relay 1 OFF"
   on_press:
     - remote_transmitter.transmit_rc_switch_raw:
         code: '0001100000011101000110100'
         protocol: 1
         repeat:
           times: 10
           wait_time: 10ms
 - platform: template
   name: "1F Relay 2 ON"
   on_press:
     - remote_transmitter.transmit_rc_switch_raw:
         code: '1010001000111001100100000'
         protocol: 1
         repeat:
           times: 10
           wait_time: 10ms
 - platform: template
   name: "1F Relay 2 OFF"
   on_press:
     - remote_transmitter.transmit_rc_switch_raw:
         code: '1001011100111100100111000'
         protocol: 1
         repeat:
           times: 10
           wait_time: 10ms
 - platform: template
   name: "1F Relay 3 ON"
   on_press:
     - remote_transmitter.transmit_rc_switch_raw:
         code: '0110101001000000001011000'
         protocol: 1
         repeat:
           times: 10
           wait_time: 10ms
 - platform: template
   name: "1F Relay 3 OFF"
   on_press:
     - remote_transmitter.transmit_rc_switch_raw:
         code: '1000001111011111110101100'
         protocol: 1
         repeat:
           times: 10
           wait_time: 10ms
 - platform: template
   name: "2F Relay ON"
   on_press:
     - remote_transmitter.transmit_rc_switch_raw:
         code: '0011010000110000010111100'
         protocol: 1
         repeat:
           times: 10
           wait_time: 10ms
 - platform: template
   name: "2F Relay OFF"
   on_press:
     - remote_transmitter.transmit_rc_switch_raw:
         code: '1001101101100110000111010'
         protocol: 1
         repeat:
           times: 10
           wait_time: 10ms
 - platform: template
   name: "Chandelier Warm"
   on_press:
     - remote_transmitter.transmit_rc_switch_raw:
         code: '1101110100101001001100100'
         protocol: 1
         repeat:
           times: 10
           wait_time: 10ms
 - platform: template
   name: "Chandelier Cold"
   on_press:
     - remote_transmitter.transmit_rc_switch_raw:
         code: '1111111001011101010001010'
         protocol: 1
         repeat:
           times: 10
           wait_time: 10ms

Знаю, что это не совсем «шлюз», ведь они зашиты в устройство. Но мне не нужно будет часто менять эти значения, потому что выключатели уже на местах, а ремонт не планируется. Можно, конечно, напрячься и сделать управление напрямую по строке, которую отсылает HomeAssistant, но это просто усложнит прошивку. Кроме того, зашитые коды могут быть использованы в локальных скриптах, если сервер, например, упадет.

Крайне внимательный читатель мог заметить, что коды, которые я вставил в прошивку со сгенерированными не совпадают. А совсем дотошный мог бы посчитать, что они 25-значные, а на конце каждого ноль. Но зачем? 

Путем научного тыка было выявлено, что при передаче «честного» 24-битного сигнала устройство почему-то шлет 23 бита. А реле не понимает 23 бита, и никак не реагирует. Можете себе представить, сколько я ломал голову, перебирал приемники и передатчики, уверенный, что китаец подсунул мне брак...

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

В итоге я просто решил добавлять «костыль» в виде дополнительного знака в каждый код. И это, как ни странно, сработало!

Теперь дело осталось за малым — сделать автоматизацию для включения-выключения света в прихожей. Тут как раз пригодилась информация о расстоянии. Это позволило включать свет только если человек в прихожей, а не в смежном туалете, куда датчик тоже частично «добивает». 

- id: ld2420_turn_on_light
  alias: "Включение света — LD2420 (distance < 400 1s)"
  description: "Включить свет, когда distance < 400 в течение 1 секунды"
  trigger:
    - platform: numeric_state
      entity_id: sensor.ld2420_moving_distance
      below: 400
      for: '1s'
  condition:
    - condition: state
      entity_id: light.hallway   # <- ЗАМЕНИТЕ на ваш entity_id
      state: 'off'
  action:
    - service: light.turn_on
      target:
        entity_id: light.hallway
  mode: single

- id: ld2420_turn_off_light
  alias: "Выключение света — LD2420 (presence off 5s)"
  description: "Выключить свет, когда датчик присутствия выключен 5 секунд"
  trigger:
    - platform: state
      entity_id: binary_sensor.ld2420_presence
      to: 'off'
      for: '5s'
  condition:
    - condition: state
      entity_id: light.hallway   # <- ЗАМЕНИТЕ на ваш entity_id
      state: 'on'
  action:
    - service: light.turn_off
      target:
        entity_id: light.hallway
  mode: single

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

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

По итогу этот проект показал, что «умный» функционал не обязательно должен быть дорогим, закрытым и завязанным на облачные сервисы. Простая комбинация ESP12 с прошивкой ESPHome, дешёвых 433-МГц модулей и микроволнового датчика LD2420 позволила на практике получить локальный шлюз, который одновременно остаётся дешевым, ремонтопригодным и гибким. Архитектура, основанная на взаимодействии более простых slave-устройств с одним шлюзом также неплохо удешевляет всю конструкцию. Есть потенциал для улучшения как вширь так и вглубь, последовательно улучшая интуитивность добавлением сценариев. Хотя конкретная реализация имеет недостатки, общая идея, на мой взгляд, имеет право на существование. Спасибо за чтение — буду признателен за ваше мнение и впечатления. Пишите в комментариях, что понравилось и что стоило бы сделать иначе.

 

Добавить в избранное
+13 +18
свернутьразвернуть
Комментарии (6)
RSS
+
avatar
-1
  • 00svd00
  • 26 августа 2025, 13:02
LD2420 не советую. Оно не сильно стабильно работает, постоянно то ложные срабатывания, то не видит когда надо. А после калибровки вообще слепнет. У меня самые лучшие результаты были с LD2412S, ну и старый добрый ld2410 тоже неплохо работал.
Если что, LD2412S очень хорошо эксплуатировать вместе с Esp32S2 mini — можно шлёпать прямо поверх платки, с вайваем не интерферирует, по ширине совпадает, ноги у S2 можно как угодно переназначать, удобный контроллер.
+
avatar
+2
Неплохо, главное — не отвлекаться и соблюдать ТБ
+
avatar
+1
  • aliex
  • 26 августа 2025, 13:18
Хм, насколько я помню, IDE-шлейфы отвратительно паялись, я тоже когда-то пытался. Это шлейфы разные или флюс волшебный какой?
+
avatar
+2
  • 00svd00
  • 26 августа 2025, 13:31
У меня до сих пор валяется бобина IDE шлейфа, от которой я эпизодически откусываю себе кусок. Паяется прекрасно. Предположу что со временем произошло удешевление и медь заменили на сталь или люминь.
+
avatar
+1
  • aliex
  • 26 августа 2025, 13:43
Да вроде они совсем древние были, ещё 40-контактные… ладно, сейчас не проверить — выбросил я их. Но в целом понятно. Раз у двух человек паяется нормально — значит, паяется. На меня они просто периодически валятся откуда-нибудь, а я выбрасывал. Теперь перестану, провода всегда пригодятся :-)
+
avatar
+1
  • al-open
  • 26 августа 2025, 13:58
LD2410B — содержит Bluetooth — нужно только 5в для работы. соответственно к HA можно подключить напрямую.
Устройства на основе Zigbee стоят дешево, нужен только один шлюз — usb свисток к HA
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.