Что может система: сигнализирует на дисплей и через пищалку о факте открытия калитки, ворот, дверей в бане. Также посылает данные о температуре в бане на экран. По факту открытия дверей помимо сигнализации срабатывает реле, которое включает дежурный свет над нужными воротами.
Итого имеем пять устройств на esp8266:
Ворота номер 1. на контакты D5 и G цепляем геркон.
Ворота номер 2. та же ситуация: два провода с герконом
Дверь в баню: к геркону добавляется датчик температуры dallas ds18b20 в герметичном исполнении. Его цепляем синий провод на ногу D7, питаем от трех вольт с самой nodemcu (красный плюс, черный минус). Не забываем воткнуть сопротивление между ногой D7 и 3.3В, иначе не заведется. У меня вроде 10КОм, но где-то рекомендовали меньше.
Блок сигнализации: к нему подключен по i2c экран 2004А, четырехстрочный (ноги D1,D2), пищалка (на D5), и реле (D0,D3,D6,D7). По идее, надо было туда еще часы RTC поставить, но не получилось.
Роутер: да, его тоже сделал на esp8266. Почему? Во-первых, чтобы не открывать доступ потенциальным хакерам во внутреннюю сеть. Во-вторых - по приколу. Надо сказать, работает очень стабильно почти неделю, не выключаясь. В качестве прошивки для него я брал https://github.com/martin-ger/esp_wifi_repeater Внутренности роутера выглядят так:
По сути, заполняете блок AP Settings и все работает. Где-то слышал, что роутеры на ESP8266 поддерживают максимум 5 устройств. У меня работало 6. Технически, можно подключить его к вашей основной точке доступа, и тогда у ваших умных устройств появится интернет для NTP (точное время).
Честно говоря, я сначала думал, что смогу обойтись без роутера, но не смог.
В качестве основной прошивки на остальные устройства я использовал ESPEasy, чтобы не тратить время на лишнее программирование.
Связывал esp8266 друг с другом через протокол ESPEasy P2P Networking. Он достаточно прост в использовании - в Controllers добавляем его и ставим галочку Enabled (других настроек просто нет), и во вкладке Tools нажимаем кнопку Advanced, находим UDP port и пишем там любое значение от 2000 до 65535. У меня стоит порт 5000. Порт у всех должен быть одинаковый. Имена устройств тоже должны быть одинаковые (Unit Name), меняется только номер (Unit Number), это вкладка Config. Если все сделали правильно, то вкладка Main везде будет выглядеть примерно так:
Для геркона на "воротах" в Devices добавляем Switch input - Switch
Из настроек пишем имя, ставим Enabled, Internal PullUp и выбираем GPIO-14 (нога номер 5).
Во вкладке Rules для геркона прописываем правила для отправки данных на блок сигнализации, который у меня имеет Unit Number 5. Приходтся вставлять картинками, уж извинте.
Разберем команду SendTo 5,event,relay0on:
5 - номер моего устройства сигнализации
event - "пунктом назначения" в устройстве сигнализации будет "событие", по сути это просто процедура
relay0on - название этого самого события
Командой gpio,15,0 мы включаем встроенный светодиод, командой gpio,15,1 - выключаем.
Вот как на устройстве сигнализации выглядит обработчик включения и выключения по реле:
Когда срабатывает команда relay0on, мы включаем реле (gpio,12,0), пиликаем (rtttl,14:d=4,o=5,b=112:8a,8a,8a) и принудительно выключаем пищалку (gpio,14,1) после чего запускаем таймер, который раз в секунду выводит на экран строчку на первую строку, в 4-ю позицию. Поскольку раз в секунду экран обновляется автоматически, то получается мигание.
А когда контакты геркона разомкнуты, он посылает сигнал на отключение. Мы останавливаем таймер командой timerSet,2,0 и выключаем реле.
Датчик температуры у меня подключен к устройству с номером три, выглядит страничка с параметрами так:
Если с выбором ноги (GPIO) все понятно, то адрес у вас появится (возможно) только после нажатия кнопки submit. Если не появился - значит, либо забыли сопротивление между синим и красным проводом (данными и +3.3 вольт) либо ошиблись ногой. Эти датчики "из коробки" не требуют калибровки, лично проверил его и в кипятке и в льдо-водяной смеси - температура четкая. Правда, у него ощутимая инерция, но это фигня.
Температуру на устройство сигнализации передаем так:
Для начала, по факту соединения с WiFi, на устройстве запускается таймер с отправкой температуры и таймер телеметрии.
Температура передается на пятое устройство в событие dtemp, которому мы присваиваем значение, полученное от датчика температуры. Вот как выглядит это на устройстве сигнализации:
Команда TaskValueSet отправляет полученный по сети параметр %eventvalue% (он может быть только один) на Generic - Dummy Device. Это такой оригинальный способ хранить переменные в ESPEasy. Цифра 2 - это номер этого Generic - Dummy Device в общем списке, а 1 - номер параметра. Вот так выглядит это устройство изнутри:
Зачем это надо? Потому что вот так выглядит настройка нашего LCD экрана (вы сами все поймете):
Вот она, эта баня, в строке с названием Line 4....
Настройка LCD оказалась одновременно простой и нетривиальной.
Во-первых, работать дисплей захотел только на "родных", то есть предлагаемых по-умолчанию GPIO, это ноги D1 и D2. Перенаправление не сработало.
Во-вторых, если писать значение переменной напрямую в экран командой LCD, то я столкнулся с тем, что LCD в какой-то момент перестал отвечать. Как будто уснул, но только экран не потушил. Если же обновлять температуру через этот экран настройки, то он работает нормально.
Display button - кстати, как раз кнопка, которая должна включать подсветку, которая автоматически вырубается по таймеру в поле Display Timeout. У меня он не выключается совсем, чтобы в глаза бросалось моргание при открытии двери.
А вот тут и лайфхак: моргание у меня получилось благодаря тому, что раз в секунду (поле Interval) у меня полностью обновляются все четыре строки, и раз в секунду же в нужной строке рисуются решетки через таймер. Вот тебе и моргание.
Теперь поговорим о телеметрии. Устройство сигнализации должно не только говорить, когда открыта дверь, но и когда отваливается какой-то датчик.
Тут пришлось повозиться, в итоге для надежности на три устройства я расходовал еще три таймера (если что, то в ESPEasy их всего 8), и пришлось заводить еще один Dummy Device где хранилось бы состояние удаленных устройств.
Логика такова: когда "ворота" включаются, они начинают раз в 9 секунд посылать сигнал на устройство сигнализации о том, что "ворота на связи", устанавливая соответствующую переменную в Dummy Device.
Устройство сигнализации, в свою очередь, раз в 50 секунд проверяет, все ли датчики на связи. Если какие-то ворота не послали сигнал о своей готовности, то запускается соответствующий таймер. На всякий случай, задержку таймеру даем 10 секунд, чтобы у "ворот" был последний шанс послать информацию о своей готовности. После этого мы принудительно сбрасываем все "ворота" в состояние "не на связи", поскольку если "ворота" сломались - то сами они об этом не скажут.
Таймер еще раз смотрит состояние "ворот", и если ворота не на связи - выводит надпись на экран и самоперезапускается. Как только ворота отсылают информацию о готовности, таймер отключается.
Вот код:
Все трое "ворот" не влезли, но по аналогии понятно. Обратите внимание, что при срабатывании аварийного сигнала я также выключаю реле и останавливаю таймер моргания открытых ворот.
Кому-то такое решение может показаться неграмотным, мол, каждую секунду посылать один и тот же импульс, почему бы не сделать более умно и т.п.
Ответ тут прост: esp8266 это прежде всего ПЛК, а не компьютер. Ему не сложно повторить самое простое для себя задание (управление ногой и таймером), esp создано для этого.
А вот писать разветвленный код с "грамотными" решениями - это как раз лишняя нагрузка на процессор, поскольку никакой внутренней оптимизации у него не предусмотрено.
Да и вообще, у вас всего 2048 символов под скрипт (поэтому комментарии кода отсутствуют - они считаются!).
Вот так выглядит дисплей, когда "не работает" два из трех:
Заметьте, что значение температуры все равно высвечивается, несмотря на то, что отвечающее за нее устройство уже "умерло". Это вполне логично, ведь просто перестало перезаписываться значение переменной.
Забыл еще один момент: при задании номеров устройствам (Unit number) не пользуйтесь нулем: оно появляется в общем списке, это как бы легальное число, но послать командой sendTo на "ноль" у вас не выйдет. Наверное, глюк прошивки.
Смета этого проекта в ценах алиэкспресс:
5 х NodeMCU ESP8266 = 1100
Реле на 4 канала = 250 рублей
Пищалка = 50 рублей
Экран = 280 рублей
Датчик Dallas DS18b20 влагоустойчивый (-55...+125) с метровым проводом = 100 рублей
Итого - 1780 рублей.
В следующей, третьей части, я вам покажу, наконец, как автоматически открывается дверь при приближении хозяина )
Пишите комментарии, задавайте вопросы! Переходите на мой телеграм-канал, чтобы общаться вживую: https://ttttt.me/roboruchka