Автомат света и музыки АСИМ-АУ-2-6

в 12:20, , рубрики: Без рубрики

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

Но это вполне вписывалось в схему естественного поведения дома. Т.е. мы за собой дверь в ванную закрываем и стараемся друг другу не мешать. К тому же, санузел не такой уж большой, и вдвоем там объективно довольно тесно. Что в схему не вписывалось, так это гости. Они нажимали на обычный выключатель, даже если несколько раз сказать, что свет — автоматический. Они не закрывали дверь и лезли друг к другу.

С этим надо было что-то делать.

image

Из аббревиатуры АСИМ-АУ-2-6 легко понять, что это Автомат света и музыки автономный управляемый, второй аппаратной версии и шестой — программной. Основа устройства — плата Arduino Pro Mini, исполнительные устройства — выключатели света Livolo, радиореле с протоколом, реализованном в библиотеке RC-Switch для Arduino.

АСИМ-АУ-2-6 предназначен для автоматического включения и выключения освещения и музыкального сопровождения в контролируемом помещении.

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

Однако отсутствие КЦДВ никак не влияет на основную функциональность — автоматическое управление светом и музыкой. Ну разве что автофункции будут работать все время, а не, скажем, по графику.

Т.е. в целом АСИМ-АУ-2-6 представляет собой автономное, с небольшим исключением, изделие. Исключение состоит в том, что автомат способен управлять периферией, которая использует протоколы выключателей света Livolo и/или подобные, реализованным в библиотеке RC-Switch. Если такой периферии нет, то и автомат бесполезен.

Предыстория

Если честно, я очень не хотел использовать в ванной отдельный контроллер, но это какие-то мои заморочки. Мне почему-то безумно жалко использовать такую штуку для решения какой-то одной частной задачи. Хотя, к примеру, PERCo это нисколько не волнует. Короче, в итоге смирился, потому что все равно особых вариантов не видел. Т.е. да, можно было бы попробовать изобразить что-то из комбинации беспроводного датчика двери и беспроводного же датчика движения внутри ванной.

. вот так все выглядит издалека
image

Я даже об этом думал. Например: если после открытия двери датчик движения фиксирует это самое движение, то свет надо включить. Это уже лучше, чем просто датчик двери, но если кто-то внутри, то датчик движения будет сигналить при каждом шорохе. А так как у меня все управление по радиоканалу, причем буфер команд и разруливание конфликтов не предусмотрены протоколом, то это, понимаете, не лучший вариант. Всего один датчик движения положит весь «удобный дом» на раз-два.

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

В запасах оставался последний контроллер Arduino Pro Mini, пачка приемников/передатчиков (АМ, 433 МГц) и несколько датчиков движения HC-SR501. Простой анализ ситуации показывал, что с учетом выключателей без обратной связи из датчиков мне также потребуется датчик света, чтобы знать, что в ванной со светом. Потом я подумал о душевой кабине. Ведь всем известно, что стекло для датчика движения — что стена. Следовательно, даже если бы я разместил его напротив дверей кабины, он бы не фиксировал движение внутри. Но я и напротив дверей не планировал.

Отсюда третий датчик — датчик закрытых дверей душевой кабины.

Алгоритм работы

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

Датчик движения. При срабатывании включает свет, если он был выключен или сбрасывает таймер выключения света, если свет уже включен (т.е. в ванной кто-то таки шевелится).

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

Выключение. Если датчик движения «молчит» до срабатывания таймера выключения света, то свет выключается, при условии, что открыты двери душевой кабины. В противном случае алгоритм перезапускается в режиме «кто-то включил свет».

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

Как не надо делать датчик света из светодиода

Грамотные люди используют в качестве датчика света обычный фоторезистор. И, вероятно, имеют под руками пачку этих самых фоторезисторов. Разумеется, у меня их не было. Зато был интернет, который говорил, что в качестве датчика света можно использовать обычный светодиод: дескать, что выходит, то и входит.

Теория была проста: подключаем диод к аналоговому входу Arduino, и читаем значения. По идее, значения в темноте и на свету различаются достаточно, чтобы это можно было применить на практике. Я быстро собрал тестовый стенд из первого попавшегося светодиода (из радиозвонка) и Arduino Mega 2560, загрузил простой скетч и понял, что таки да, все работает.

Так что взял в руки паяльник и собрал первую версию контроллера света для ванной. Запуск на столе показал, что все снова работает, как положено. Но стоило повесить контроллер на место, как стала происходить какая-то ерунда. Музыка (которая как раз привязана к свету) включалась и выключалась в совершенно хаотическом порядке.

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

Таким образом я сходил с ума несколько дней — направлял светодиод в разные стороны, менял светодиоды, вешал ферритовые кольца на кабель питания. Все без толку, и я сдался.

Вы, наверное, думаете, что я купил фоторезистор. А вот и нет. Месяц из Китая ждать не хотелось. Платить здесь 250 рублей за доставку тоже. Я просто вспомнил, что на балконе валяется несколько садовых фонариков на солнечных батареях. Не сказать, что особый прорыв — и раньше была мысль использовать их как датчики света (они же дешевые, как не знаю что), но особой потребности не возникало, и я забыл.

. такой вот фонарик, это уже без рассеивателя и опорного штыря
image

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

. актуальны черный и белый провода, остальное можно смело оторвать
image

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

. примерно в таком разрезе. Когда мне перестанет быть лень, воспарю гордым орлом с клеевым пистолетом в клюве. И ликвидирую всю эту порнографию с изолентой. Но может и не ликвидирую. А может, и не орлом.
image

Что не нужно делать с датчиком движения

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

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

Т.е. сигнал передатчика на выключение света провоцировал реакцию датчика движения, а это, в свою очередь, приводило к включению света. Такой уж алгоритм.

Разнести датчик движения и передатчик, как в случае с центральным контроллером, я не мог — в корпусе оказалось недостаточно места. Так что я поступил малодушно: выставил задержку в 3 секунды после любой команды передатчика. Напоминаю, что это из-за специфики датчика движения: «из коробки» минимальное время активации (т.е. высокого уровня на выходе датчика) после срабатывания — 2.5 секунды.

Таким образом, пауза в 3 секунды гарантирует, что датчик придет в себя после «ложного» срабатывания. Это также означает, что в течение 3 секунд после включения или выключения света датчик (и контроллер в целом) вообще ни на что не реагирует. Я посчитал это некритичным, а практика подтвердила, что и неудобств никаких не возникает.

Чувствительность датчика выставил на 3/4 от максимума. А в целом рекомендация — максимум без ложных срабатываний при немного приоткрытой двери. Или по вкусу.

Проблема сферического коня в душевой кабине

Как я упоминал, датчик движения не позволяет определить движение за стеклом. Как же в таком случае узнать, есть ли кто в домике? В комментариях к тексту об Удобном доме мне предложили несколько вариантов: тепловизор из какой-нибудь камеры, дополнительный водосчетчик в душевой кабине, шумомер.

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

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

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

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

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

Железо

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

Итак, состав контроллера света и музыки (ссылки — для примера):

1) Arduino Pro Mini, ATmega328p, 16 МГц, 5В.

2) Комплект приемника и передатчика 433 МГц с амплитудной модуляцией (снова напоминаю — если купите без антенн, не забудьте про то, что они все равно нужны). Приемник не потребуется, если не планируете пользоваться дистанционным управлением контроллером.

3) Датчик движения HC-SR501

4) Солнечная панель, например, из садового фонаря

5) Герконы для контроля дверей душевой кабины

6) Корпус по вкусу

7) Разъемы для датчиков, питания и соединительные/макетные провода

8) Источник питания

Для музыкального модуля также потребуется:

1) Любой MP3-плеер с динамиком, который не жалко (я взял китайскую мини-колонку) и который автоматически начинает воспроизведение при включении и запоминает трек при выключении

2) Радиореле

Принцип сборки АСИМ-АУ-2-6, как обычно, очевиден из кода. Подключение питания периферии к пинам Arduino обусловлено тем, что я в процессе экспериментировал с отключением/включением передатчика и датчика движения.

Сборка в текущей конфигурации:

1) Датчик движения

DATA — цифровой пин 10 Arduino
VCC — цифровой пин 11 Arduino (можно к плюсу питания)
GND — к общей земле

2) Датчик света

Плюс солнечной панели — пин A1 Arduino
Минус солнечной панели — к общей земле

3) Датчик двери

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

4) Передатчик

DATA — цифровой пин 8 Arduino
VCC — цифровой пин 9 Arduino (можно к плюсу питания)
GND — к общей земле

5) Приемник

DATA — цифровой пин 2 Arduino
VCC — плюс питания
GND — к общей земле

Софт

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

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

Для компиляции кода потребуются следующие дополнительные библиотеки:

1) RS-Switch для управления розетками, радиореле и обмена с метео- и сервисными датчиками.

2) Livolo для управления одноименными выключателями света.

3) SimpleTimer для отсчета интервалов времени.

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

// 14.01.2014 - добавлен контроль герконов дверей душевой кабины. Если оба замкнуты - свет не выключать
// 17.01.2014 - пауза после включения света, чтобы стабилизировались показания датчика света. Датчик света - солнечная батарея.
// 20.01.2014 - паузы после каждой передачи кроме включения света, чтобы исключить ложные срабатывания датчика движения. Отключени приемника
// на время передачи. Пищалка для сигнализации срабатывания датчика движения.
// 26.01.2014 - исправлено переключение авторежимов музыки. Признак включенной музыки внутри условия automusic, так что теперь если включение автомузыки
// происходит при включенном свете, музыка должна включиться сразу же, а не на следующем цикле включения света.
// 27.01.2014 - убрал лишнее - prevlight

#include <livolo.h>
#include <RCSwitch.h>
#include <SimpleTimer.h>


int lightLevel; // уровень освещения
#define sensorPin 7 // пин датчика света А1
#define PIRPin 10 // пин датчика движения цифровой
#define PIRPowerPin 11 // пин питания датчика движения
#define lightTreshold 55     // порог срабатывания датчика света
#define txPin 8 // пин передатчика
#define txPowerPin 9 // пин питания передатчика
#define  doorPin 6 // пин герконов дверей душевой кабины. Второй контакт на минус!
boolean musicOn=false; // признак включенной музыки
boolean autoLight = true; // признак разрешения автосвета
boolean autoMusic = true; // признак разрешения автомузыки
int bathLightID; // идентификатор таймера света
boolean timerSet = false; // признак запущенного таймера

SimpleTimer myTime; // объект таймера
Livolo livolo(8); // объект управления Livolo
RCSwitch mySwitch; // объект управления RC-Switch

void setup() {
mySwitch.enableTransmit(txPin); // инициализация передатчика RCSwitch
mySwitch.enableReceive(0);  // инициализация приемника RCSwitch  

pinMode(PIRPin, INPUT); // пин датчика движения

pinMode(txPowerPin, OUTPUT); // пин питания передатчика
digitalWrite(txPowerPin, LOW); // выключаем передатчик - он на старте не нужен

pinMode(PIRPowerPin, OUTPUT); // пин питания датчика движения
digitalWrite(PIRPowerPin, HIGH); // включаем датчик движения

pinMode(doorPin, INPUT); // пин датчика двери
digitalWrite(doorPin, HIGH); // включаем подтягивающий резистор, а сам датчик подключаем к минусу. Датчика нет - 1, датчик есть - 0, чтобы не было ложных срабатываний при "висящем" проводе

pinMode(sensorPin, INPUT); // пин датчика света

delay(3000); // небольшая пауза, чтобы датчик движения немного пришел в себя
}

void loop() {
  
  if (mySwitch.available()) { // управление автофункциями по радио
    int value = mySwitch.getReceivedValue();
    if (value != 0) {
      switch (mySwitch.getReceivedValue()) {
 	  
      case 1486220: // выключение автосвета
       autoLight = false; // ставим признак
       if (timerSet == true) { // выключаем таймер отключения света, если он (таймер) активен
       myTime.deleteTimer(bathLightID); }
      break;
      
      case 1486221: // включение автосвета
       autoLight = true; // ставим признак
      break;
    
      case 1486230: // выключение автомузыки
       autoMusic = false; // ставим признак
       switchTX(1); // включаем передатчик - и дальше по тексту так же
       mySwitch.send(386100, 24); // выключаем музыку
       switchTX(0); // выключаем передатчик
       musicOn = false;
      break;
      
      case 1486231: // включение автомузыки
       autoMusic = true; // ставим признак
      break;    
    
     }

    } 
      mySwitch.resetAvailable();
  }
  
  if (autoLight == true) { // если автосвет разрешен
 
  myTime.run(); // проверка таймера
  
  delay(50);
  lightLevel=analogRead(sensorPin);

// ВКЛЮЧЕНИЕ МУЗЫКИ, ЕСЛИ ВКЛЮЧЕН СВЕТ И УСТАНОВКА ТАЙМЕРА НА ВЫКЛЮЧЕНИЕ СВЕТА

  if (lightLevel > lightTreshold) { // кто-то включил свет
    if (musicOn == false) { // если музыка выключена - включаем
     if (autoMusic == true) {
       switchTX(1);
       mySwitch.send(386101, 24);
       switchTX(0);
       musicOn = true; // и устанавливаем признак включенной музыки
     }  
    }
    if (timerSet == false) { // заводим таймер, если он еще не заведен
      bathLightID = myTime.setTimeout(180000, turnOff); // пытаемся все выключить через 3 минуты
      timerSet = true;
    }
  }
  
  // ВЫКЛЮЧЕНИЕ МУЗЫКИ, ЕСЛИ ВЫКЛЮЧИЛСЯ СВЕТ И ВЫКЛЮЧЕНИЕ ТАЙМЕРА (А ЗАЧЕМ ОН ТОГДА НУЖЕН?)
  
  if (lightLevel < lightTreshold && musicOn == true) { // кто-то вышел и выключил свет (или сработал таймер) - выключаем музыку
      switchTX(1);
      mySwitch.send(386100, 24);
      musicOn = false; // сбрасываем признак музыки
      switchTX(0);
    if (timerSet == true) {
    myTime.deleteTimer(bathLightID);
    timerSet = false;
    }
  }
  
  // ВКЛЮЧЕНИЕ СВЕТА ПО ДАТЧИКУ ДВИЖЕНИЯ
  
  if (digitalRead(PIRPin) == 1) { // сработал датчик движения
    if (lightLevel < lightTreshold) { // если свет выключен -
         switchTX(1);
         livolo.sendButton(8500, 108); // включаем свет
         switchTX(0);
    } else {
            if (timerSet == true) {
            myTime.restartTimer(bathLightID);}                          
    }
   }             
  } 
    
}

// ВЫКЛЮЧЕНИЕ СВЕТА ПО ТАЙМЕРУ, ЕСЛИ НЕ СРАБОТАЛ ДАТЧИК ДВЕРИ ДУШЕВОЙ КАБИНЫ

void turnOff() {
  if (lightLevel > lightTreshold) { // если свет горит -
       if (digitalRead(doorPin) == 1) { // и если двери открыты
         switchTX(1);
         livolo.sendButton(6400, 108); // выключаем свет
         switchTX(0); 
       }
    }
    timerSet = false;
 }
 
 // ПЕРЕКЛЮЧЕНИЕ ПЕРЕДАТЧИКА И ДАТЧИКА ДВИЖЕНИЯ
 
 void switchTX(byte OnOff) {
 
  if (OnOff == 1) {
    mySwitch.disableReceive();
    digitalWrite(txPowerPin, HIGH);
    delay(50);
  }
 
  if (OnOff == 0) {
    digitalWrite(txPowerPin, LOW);
    delay(3000);
    mySwitch.enableReceive(0);
  }
 }
   
Музыкальный модуль

В завершение пару слов о музыкальном модуле, который я сначала хотел назвать Аппарат музыкальный цифровой пассивный управляемый (АМЦ-ПУ), но передумал.

Идеей АМЦ-ПУ я обязан жене. Она, в очередной раз покрутив пальцем у виска оглядев всю эту автоматику предположила, что если чего и не хватает, так это музыки в, так сказать, WC. Ну как в этих ваших торговых центрах. Идея овладела разумом, и далее по тексту.

. вот с таким материалом работаем
image

В свою очередь, конструкция АМЦ-ПУ оказалась в зависимости от моего нежелания использовать контроллеры для таких пустяковых задач. Я считал, что логично управлять музыкой из центрального контроллера, а саму колонку просто оснастить радиореле для дистанционного ее включения. Здесь мне очень помогла особенность самой колонки: при наличии в слоте или USB-разъеме карты памяти или флешки с музыкой, воспроизведение начинается автоматически. Причем колонка запоминает последний воспроизведенный трек, так что нет риска все время слушать одно и то же.

Отсюда элементарный принцип работы: по команде контроллера реле включает или выключает колонку. И все.

. открываем колонку и подключаем к ней внешнее питание и контакты реле. Кабеля КСПВ с четырьмя жилами как раз хватает. Так сложно потому, что я хотел сохранить рабочим выключатель колонки. Иначе достаточно и двух проводов. Встроенную батарейку отключил — во избежание.
image

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

.
image

В итоге по концепции АМЦ-ПУ полностью повторяет Аппарат кормления котов управляемый, пассивный АКК-ПУ-1, т.е. это уже готовое устройство (плеер-колонка), дополненное радиореле. В связи с этим не вижу смысла дважды описывать одну и ту же конструкцию, и просто показываю фоточки.

. и закрываем все
image

Что касается железа, то вы уже догадались, что подойдет любая китайская колонка-плеер, которая автоматически начинает воспроизведение музыки с подключенного к ней носителя и запоминает воспроизводимый трек при выключении. Или, разумеется, любой аналог.

Автор: spc

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js