Делаем погодную станцию на ESP8266
В этой статье я расскажу о том, как делал погодную станцию для своей «умной дачи». Первые попытки сделать ее были еще лет 5 назад, и только примерно 3 года назад я наконец-то собрал работающий прототип. Хотя это совсем не сложное устройство, но просто до него всегда руки не доходили. Погодная станция крайне полезна при посадке рассады. Имея статистику по температуре и освещенности, можно подобрать оптимальную дату посадки в конкретном регионе. Для этого температура не должна опускаться ниже 10 градусов как минимум в течение 14 суток, и длина светового дня должна быть как минимум 10..12 часов.
Собран девайс на микроконтроллере ESP8266 в виде отладочной платы NodeMCU. Она очень дешевая, даже дешевле Arduino Nano. При этом обладает неплохими характеристиками: 4 мб флэш-памяти (по сравнению с 32 кб у Atmeta 328) и встроенной поддержкой WiFi. В прошлом году я подключил на даче интернет по оптоволокну (технология GPON) со скоростью 50 мбит/с, что стало стимулом довести до ума всю «умную дачу». Ранее там был доступен только мобильный интернет, но ввиду удаленности от базовой станции, он был крайне медленным и не стабильным. Даже с применением антенны типа «волновой канал» на 24 dbi мне удавалось получить максимум 1 мбит/с, но самым неприятным было то, что сигнал периодически пропадал.
На дачу я отдал старый роутер Asus WL-500g Premium V2, который просто валялся без дела уже года три после покупки гигабитного на два диапазона. В качестве протокола передачи данных между погодной станцией и сервером, был выбран MQTT. Это очень простой, удобный и открытый протокол, разработанный как раз для таких применений. Более подробно о нем можно узнать по этой ссылке. Как установить MQTT-брокер Mosquitto на Ubuntu, доступно и подробно описано в этой статье.
В принципе можно воспользоваться одним из многочисленных готовых MQTT-брокеров. Но я, как робот Бендер, решил построить свой, с сервером и базой данных. Никто также не мешает сделать веб-сервер и смотреть погоду сразу на NodeMCU: 4 мб должно хватить всем (с). Но поскольку погодная станция — не самоцель, а она является частью более сложного устройства, то использование отдельного сервера вполне оправдано.
Сервером у меня служит мини-компьютер (SFF — Small Form Factor) Fujitsu-Siemens ESPRIMO Q5020, который идеально подходит для моих целей, да и стоил около $50. Кроме погодной станции, на нем также управление автополивом, охранные функции (датчики движения) и видеонаблюдение с одной WiFi камеры. Операционная система у меня Ubuntu 20 LTS сервер, без графической оболочки. Процессора Intel Core 2 Duo T7250 и 4 Гб DDR2 с головой хватает для всего. Также здесь установлен LAMP стэк для веб-интерфейса и управляющих скриптов. Более продвинутые люди используют для этих целей Python или NodeJS, но я не умею ни того, ни другого. Хотя мог бы. Но лень.
Первую версию погодной станции для дачи я собрал примерно три года назад. Там NodeMCU и датчики располагались в одном корпусе и находились на улице. Однако атмосферная влага весьма вредна для электронных схем. И спустя некоторое время, девайс устал. Из-за окисления закоротило питание, и NodeMCU умер.Датчики использовались DHT22 для температуры и влажности, и BMP180 для давления. Датчики освещенности и дождя отсутствовали.
Во второй версии я решил сделать модуль датчиков отдельным выносным блоком. Он размещается под выносом крыши дачного домика, и соответственно, находится на улице, но при этом на него не попадает дождь. К блоку датчиков двумя проводами длиной около метра подключен датчик дождя, который находится на крыше. Блок датчиков прикреплен с северной стороны дома, чтобы на него не попадали солнечные лучи. В противном случае показания температуры будут в несколько раз выше реальных.
Я решил заменить DHT22 с BMP180 одним датчиком BME280, который умеет температуру, влажность и атмосферное давление. Он имеет интерфейс I²C. Также, здесь есть датчик дождя на LM393, который отсутствовал в первой версии. Он подключен к аналоговому входу А0 NodeMCU. Здесь же размещен датчик освещенности BH1750, также с интерфейсом I²C. Он находится за небольшим окошком из акрила, чтобы на него попадал свет. Изначально я хотел взять модуль с фоторезистором, коих у меня валяется ез дела аж три штуки. Но потом отказался из-за его низкой точности.
Модуль датчиков соединяется с NodeMCU кабелем «витая пара» длиной около метра. Он пропущен в отверстие в раме окна и имеет на конце разъем DIN 41524 (он же СШ-5) просто для удобства. В последнее время я полюбил эти разъемы и довольно часто использую в своих поделках, поскольку они простые, надежные и довольно компактные. А кроме того, легко разбираются и паяются.
Я уже довольно давно выбрал, что желтый провод — это SDA, а белый — SCL. Аналоговый сигнал — синий, цифровой — зеленый. Красный и черный, согласно общепринятому стандарту — это питание и земля. В случае с витой парой, я использую провода следующим образом (за неимением в ней, к примеру, желтого, черного и красного). Оранжевый — +3.3v, синий — земля, коричневый — SDA, бело-оранжевый — SCL, бело-синий — аналоговый сигнал, бело-зеленый — цифровой сигнал. В разъеме DIN (справа налево): питание — 5 (крайний правый), SDA — 4, цифровой сигнал — 1, SCL — 2, аналоговый сигнал — 3, земля — корпус разъема. Почему именно так, я уже не помню — возможно, у меня просто был набор проводов таких цветов.
Подключаемся к NodeMCU. SDA — D2, SCL — D1, земля, питание, аналоговый вывод датчика дождя к A0. Также к D5 припаял кнопку с подтягивающим резистором на 10к. Единственной функцией этой кнопки на данный момент является сборс настроек WiFi, чтобы можно было выбрать и подключить другую сеть.
Также, мне хотелось иметь возможность смотреть температуру, влажность, атмосферное давление и состояние дождя прямо на внутреннем блоке. Изначально я собирался поставить небольшой OLED экранчик на 0.98″ с интерфейсом I²C. Но к сожалению, когда собирал устройство, то случайно этот экранчик раздавил, а другого такого на тот момент у меня не было. Поэтому решил его заменить модулем из восьми 7-сегментных индикаторов. Их вполне достаточно для отображения информации о погоде. Кроме того, они значительно крупнее и ярче OLED. У меня был такой модуль на MAX7219 с интерфейсом. нет, SPI 🙂 Чтобы особо не мудрствовать, я взял уже ранее использованную в других проектах библиотеку LedControl. Она довольно примитивная: может только выводить цифры и некоторые символы в заданную колонку, по одному за раз.
Снял короткое видео с демонстрацией работы устройства. Все датчики на момент съемки находятся рядом, поэтому показывают температуру, влажность, давление, освещение в комнате. При запуске устройства на экране показывается приветствие HELLO. Если WiFi сеть еще не была настроена, то на экране отображается надпись «n 0000». Это означает, что устройство находится в режиме настройки сети. Берем в руки телефон, и ищем среди беспроводных сетей «WeatherStation», пароль к которой «12345678». Телефон на Андроиде автоматически откроет страницу настроек. Если этого не произошло, то можно в браузере вручную ввести адрес http://192.168.1.4/. Для настроек сети я взял готовую библиотеку WiFiManager. Интерфейс интуитивно понятный, поэтому я не буду писать к нему инструкцию. Она есть в репозитории.
После того, как мы подключимся к WiFi сети, устройство перейдет в обычный режим работы. Чтобы сбросить настройки WiFi, нужно нажать и удерживать кнопку в течение 8 секунд. При этом на экране отобразится «00000000», устройство перезагрузится и перейдет в режим настройки WiFi.
Если подключение уже настроено, то в левой части экрана отобразится «n 01», что означает, что девайс успешно подключился к сети. Если возникла ошибка, то отобразится «n 00». В правой части экрана точно так же показывается статус подключения к MQTT-брокеру (01 — успешно, 00 — ошибка). Адрес брокера жестко прописан в скетче (192.168.1.127). В дальнейшем я собираюсь добавить возможность изменить этот адрес в настройках сети.
При работе, устройство показывает в левой части экрана температуру, в правой — влажность, в течение 5 секунд. Затем следующие 5 секунд в левой части отображается атмосферное давление, в правой — состояние датчика дождя.
Если при включении устройства нет отклика от каких-то датчиков (например, забыли подключить провод), то на экране отображается E280 для датчика BME280, и E175 для датчика BH1750. Датчик дождя аналоговый, поэтому сообщение об ошибке для него не выводится. Тогда значение, которое он выдает, будет 1024. В коде есть баг, из-за которого если подключить разъем датчиков уже в процессе работы устройства, то по-прежнему будет показывать ошибку. Нужно подключать датчики либо до включения устройства, либо после подключения перезагрузить девайс, кратковременно отключив питание.
Чтобы не перегружать статью исходниками, я выложил все в свой репозиторий на GitHub. Клонируем всё в /var/www/dacha. Если выберете другой путь, то необходимо заменить /var/www/dacha/ на ваш в weather-station/weather-station.service. Далее запускаем sudo install-service.sh — он создаст сервис weather-station. Также, необходимо задать параметры подключения в weather-station/weather-station.php. После чего перезапускаем сервис: sudo service weather-station restart. Можно не устанавливать сервис, а запускать скрипт напрямую: php /var/www/dacha/weather-station/weather-station.php. Но это гораздо менее удобно, чем сервисом.
// ваш адрес MQTT-брокера define('MQTT_HOST', '192.168.1.127'); define('MQTT_PORT', 1883); // имя пользователя и пароль MQTT-брокера define('MQTT_USER', 'raven'); define('MQTT_PASS', 'bynthytn'); // строка-идентификатор клиента для брокера define('MQTT_CL_ID', 'weather-station-8112'); // параметры подключения к базе MySQL define('DB_USER', 'raven'); define('DB_PASS', 'bynthytn'); define('DB_NAME', 'dacha');
В firmware находится скетч для ESP8266. Код весьма сырой, но тем не менее рабочий. Веб-интерфейс в процессе разработки и скоро появится в репозитории. Старый интерфейс я уже выкинул, т.к. он был довольно топорным и глючным. Я не фронтэнд, поэтому никаких Vue, Angular и прочих React’ов. Только jQuery, только хардкор.
Следующую статью постараюсь написать о том, как я делал автоматический полив. Или охрану с датчиками движения и видеонаблюдением. Или что-то еще. Пока не решил. Хотелось бы услышать ваши комментарии. Что можно улучшить, что изменить, какие функции добавить, и т.д.