Я никогда бы не рискнул написать статью об очередной реализации умного дома с подключением датчиков утечек воды в ванной и системами слежения за проделками кота в квартире. Слава богу, кот под контролем собаки, вода вроде тоже не течёт. Но всё же мы больше находимся на работе, в различных офисах, где не всегда удается создать оптимальную рабочую среду. Статья посвящена системе экологического мониторинга рабочего пространства в офисе и тем мероприятиям, которые мы провели после месяца её (на удивление) стабильной работы. Конечно, все данные отправляем в облака, смотрим на них со своих смартфонов, полезности в этом никакой, зато повод похвалиться перед близкими и знакомыми, да и в офисе стало покомфортней. Реализовано всё на ESP8266, а как — милости просим под кат)
Где мониторим?
Не скажу, что мы работаем прям в невыносимых условиях. Офисы в компании замечательные, в комнатах по три человека, много цветов. Само здание окружено лесом. В общем панорама офиса, где развернута система мониторинга прилагается.
Что мониторим?
Ничего оригинального. Снимаем температуру в офисе, влажность, давление и уровень CO2. Конечно, в систему добавлен сенсор освещенности. Уровень освещенности рабочих мест даже подлежит контролю и должен в нашем случае быть на уровне 300-400 Лк. Пожалуй, это самый важный параметр для комфортной работы. И самый динамично изменяющийся в течение дня.
Температуру и влажность получаем с датчика DHT22. Описание датчика.
Давление забираем с датчика BMP180. Описание датчика.
За уровнем CO2 следит оптический датчик MH-Z14. Описание датчика.
Ну и за качеством освещения следит сенсор TSL2561 в виде шильдика для Arduino серии GROVE. Описание здесь.
И, наконец, рулит всем этим контроллер ESP8266 в виде платки для быстрого прототипирования NodeMcu (по имени прошивки), который в моем случае прошивается из стандартной Arduino IDE.
Собираем коробочную версию
Итак, все датчики разложены на столе — пора собирать устройство. Однако, для начала проанализируем некоторые тонкости. Принципиальную схему набросал для наглядности.
Здесь все датчики запитываются от +3.3 В, которые мы возьмем с платы NodeMcu, благо их выведено на плате аж три. Но датчик углекислого газа придется запитать отдельно, ему требуется 4-6 вольт питания и при этом производитель настоятельно рекомендует обратить на это особое внимание. Так как я планирую питать устройство от отдельного блока питания на +5V — проблем не возникнет. Подаём питание на вывод 1 датчика MH-Z14 (либо 15, так как они продублированы). При включении датчик пару минут выдает всякий мусор в порт при передаче по линии TX/RX, поэтому полезный сигнал с этого датчика я беру с PWM выхода на 6 ноге. Вообще данный датчик мне понравился. Он достаточно стабильный, имеет цифровые и аналоговый выход, но может работать только с микроконтроллерами с трехвольтовой логикой, поэтому запустить его, к примеру, на UNO без танцев с бубнами согласования логических уровней не получится. В нашем же случае ESP работает на трехвольтовой логике, как и все остальные сенсоры. При этом особо привередлив к качеству питания сам ESP, но на платке, которую я использовал в этой поделке, собрана нормальная схема стабилизации входного питания до +3.3 В, но все-же питать плату я бы не советовал от всяких сомнительных ИП и вообще не подавал бы больше 5 вольт. Не будем также отлаживать полностью собранную схему, запитывая её только от USB порта. Так как датчик углекислого газа имеет большое потребление из-за наличия в его конструкции лампочки накаливания (как источника ИК, наверное), это может подсаживать порт. А оно нам надо?). Поэтому заливаем прошивку с включенным сторонним блоком питания, или через USB, но отключив датчик углекислого газа.
Без паяльника не обошлось…
Как видно из схемы, я использую два датчика на линии i2c. Это датчик давления и датчик освещенности. Как известно, на последовательной шине можно «повесить» до 127 всяких сенсоров и устройств. В реализации протокола должна быть выполнена подтяжка линий SDA/SCL к питанию, но только один раз. А если мы навесим N датчиков, в каждом из которых имеются подтяжки — можно посадить линию. Наверное, от двух датчиков ничего бы и не случилось — но я всегда последователен в проектировании. Не должно быть зуба — извините… Поэтому избавляемся от резисторов подтяжки в одном из сенсоров. Удобнее было выдрать резисторы из сенсора давления. На рисунке показано.
После всех этих допилов — собираем нашу коробочную версию. В коробке из-под бумаги)
Что удивительно — заработало сразу. Не к добру это, но всё-же.
Усваиваем данные
Итак, идеология такова. Собираем данные с датчиков и, к примеру, каждые 10 минут, скидываем их в облачное хранилище через офисный Wi-Fi. Строим красивые графики и анализируем полученные результаты из Thingspeak.com. Сервис бесплатный, достаточно устойчивый и простой в понимании. О нем много написано. Регистрируем канал, получаем API-key, и сбрасываем данные с любых датчиков методом POST.
// Место для важной херни, чтобы это все заработало #include <Wire.h> #include <ESP8266WiFi.h> // будем вещать инфу в интернет, чего уж там float index_comfort=0; // индекс комфорта //+++++++++++++++++++++++++++++++++++++++++++++++++++ //Объявим библиотеки и переменные, будь они не ладны // Начнем с влажности #include "DHT.h" #define DHTTYPE DHT22 // тип датчика - Grove DHT22 #define DHTPIN 14 // на 14 порту ESP (на плате нога D5) повесим датчик. // объявим глобальные переменные влажности и температуры float humidity_room = 0.0; // глобальная переменная влажность в офисе // запрос humidity_room = dht.readHumidity(); float temp_room = 0.0; // глобальная переменная температура в офисе // запрос temp_room = dht.readTemperature(); // Инициируем датчик влажности. С него будем снимать влажность // и температуру в офисе DHT dht(DHTPIN, DHTTYPE); //++++++++++++++++++++++++++++++++++++++++++++++++++++ // библиотека для датчика освещенности #include <Digital_Light_TSL2561.h> // объявим глобальную переменную по освещенности float light_room=0.0; // запрос light_room=TSL2561.readVisibleLux(); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Теперь C02 датчик int CO2; // Объявим переменную концентрации углекислого газа int pin_CO2 = 13; // порт 13, на плате 7 нога // измерение СО2 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Теперь датчик давления добавим. #include <Adafruit_BMP085.h> Adafruit_BMP085 bmp; float pressure =0.0; // глобальная переменная давления // запрос pressure=bmp.readPressure(); // давление в паскалях! // 1013.25 millibar = 101325 Па = 760 мм рт.ст. Кто это придумал? Пипец... // будем выводить в мм ртутного столба, так привычней //+++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Объявим все необходимое для передачи инфы в интернет-облако // графики будем рисовать в thingspeak.com он, конечно, х..евый, но пойдет #define myPeriodic 300; // время в секундах на передачу новых данных const char* server = "184.106.153.149"; // сервак облака thingspeak.com String apiKey ="1K******************GM"; // АПИКЕЙ поставь свой const char* MY_SSID = "P********x"; // имя Wi-Fi сети вокруг const char* MY_PWD = ""; // пароль сети, если сеть без пароля, то "" int sent = 0; // количество актов (циклов) передачи инфы. Для чего? Не знаю, пусть будет... //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Ща как все отсетапим, чтобы заработало void setup() { Serial.begin(9600); // Откроем сом порт Serial.println("Go! Go! Go!"); Wire.begin(); dht.begin(); // запускаем датчик давления TSL2561.init(); // Запускаем датчик освещенности pinMode(pin_CO2, INPUT); // пин датчика CO2 инициируем // Запускаем датчик давления if (!bmp.begin()) { Serial.println("Promlem with sensor bmp180!"); while (1) {} } // подключаем wi-Fi connectWifi(); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++ // подключаемся к сети и проверяем параметры подключения void connectWifi() { Serial.print("Connecting to "+*MY_SSID); WiFi.begin(MY_SSID, MY_PWD); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } Serial.println(""); Serial.println("Connected"); Serial.println(""); Serial.print("SSID: "); Serial.println(WiFi.SSID()); // параметры сети IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // уровень сигнала сети long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.print(rssi); Serial.println(" dBm"); }//end connect //++++++++++++++++++++++++++++++++++++++++++++++++++++ // отправка данных на сервер void send_info(float temp_in, float temp_out, float humidity_in, int CO2_in, float light_in, float pressure_all ) { WiFiClient client; if (client.connect(server, 80)) { // use ip 184.106.153.149 or api.thingspeak.com Serial.println("WiFi Client connected "); // формируем строку передачи данных в облако String postStr = apiKey; // АПИ кей postStr += "&field1="; postStr += String(temp_in); // температура в комнате postStr += "&field2="; postStr += String(temp_out); // индекс комфорта postStr += "&field3="; postStr += String(humidity_in); // влажность в комнате postStr += "&field4="; postStr += String(CO2_in); // СО2 в комнате postStr += "&field5="; postStr += String(light_in); // свет в комнате postStr += "&field6="; postStr += String(pressure_all); // давление в атмосфере postStr += "\r\n\r\n"; // и закроем строку client.print("POST /update HTTP/1.1\n"); client.print("Host: api.thingspeak.com\n"); client.print("Connection: close\n"); client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n"); client.print("Content-Type: application/x-www-form-urlencoded\n"); client.print("Content-Length: "); client.print(postStr.length()); client.print("\n\n"); client.print(postStr); delay(1000); }//end if sent++; // прибавим счетчик client.stop(); Serial.println("transmition closed "); }//end send //+++++++++++++++++++++++++++++++++++++++++++++++++++++ // Ну и поехали, чего тянуть то? void loop() { delay(5000); // влажность dht.begin(); humidity_room = dht.readHumidity(); delay(500); // температура в комнате temp_room = dht.readTemperature(); delay(500); // солнышко и свет light_room=TSL2561.readVisibleLux(); delay(500); // CO2 длительность импульсов while(digitalRead(pin_CO2)==HIGH){;} float duration_h = pulseIn(pin_CO2,HIGH)/1000; CO2= int(5000*(duration_h-2)/(duration_h+(1004-duration_h)-4)); // по паспорту delay(500); // давление атмосферное bmp.begin(); pressure=bmp.readPressure(); pressure=int((pressure/101325)*760); delay(500); // расчитаем индекс комфорта if (temp_room<18) { index_comfort=(2*light_room/300)+(400/CO2)+humidity_room/40; } if (temp_room>25) { index_comfort=(2*light_room/300)+(400/CO2)+humidity_room/40; } index_comfort=1+(2*(light_room/300)+(400/CO2)+humidity_room/40); if (index_comfort>5){ index_comfort=5; } // отправляем данные в облако send_info(temp_room, index_comfort, humidity_room, CO2, light_room, pressure); //Перекур. Пауза между отправкой очередных данных int count = myPeriodic; while(count--) delay(1000); // фу, вроде все. Надо пиво выпить... // особенности, выводы // // Датчику давления подтягивающие резисторы к шине i2c надо удалить как гланды, чтобы шину не // прессовать. Хватит поддяжки у датчика освещенности. // зарабало с первого раза все. Удивительная херня. Лог передачи данных // очень устойчивый, сеть держит хорошо. Датчики опрашиваем не торопясь, делаем паузы полсекунды. // Полезно каждый раз инициировать датчики, особенно DHT22, хотя это не спортивно. // Бл--, коту опять забыл корма купить... // 15 февраля 2016 года. }
Для того, чтобы это всё заработало, понадобятся библиотеки для работы с выбранными датчиками и библиотека для работы с ESP8266 по Wi-Fi. Также необходимо добавить в список плат Arduino IDE плату NodeMcu, а чтобы комп её увидел — понадобиться USB-SERIAL CH340 драйвер, который легко найти и скачать в сети без особых проблем.
Библиотека для ESP8266 Скачать
Библиотека для работы с датчиком влажности. Скачать
Библиотека для работы с сенсором освещенности. Скачать
Библиотека для работы с сенсором давления. Скачать
Датчик СО2 в библиотеках не нуждается. Показания вычисляем по длительности приходящего с PWM выхода импульса и рассчитываем по формуле из описания датчика. Кстати, диапазон измерений не 2000 ppm, а 5000, о чем, кстати, тоже пишет пользователь Hellsy22 в своей недавней статье про схожий датчик углекислого газа.
Оргвыводы
1. Работает
2. Поделка достойна из коробки из под бумаги перебраться в приличный корпус.
3. В офисе вечером маловато света — добавили пару потолочных светильников. Стало лучше. 350 Лк.
4. Уборщица и правда работает. Приходит рано утром, включает свет, влажная уборка дает всплеск влажности в офисе на полчаса. Не густо, но всё же…
5. Через два часа работы (три человека натужно дышат) в офисе уровень СО2 зашкаливает. Пятиминутное проветривание исправляет ситуацию до нормальной (500 ppm). Совмещаем (при желании) проветривание с производственной гимнастикой)))
6. Очень сухо. Отопление зимой, конечно, тому прямая причина. Дотягивать до комфортных 40-50% влажность не удается. Однако, цветы в офисе реально дают плюс 10 процентов к влажности по сравнению с аналогичным помещением без цветов. Не забываем их поливать, конечно). Кстати, на полив цветов уходит 10-12 литров воды. В офисе 13 горшков с цветами. Поливаем два раза в неделю.
7. Полезности в этом во всём, прямо сказать, мало. Однако, к примеру, для школьных классов или поликлиники такие системы были бы, наверное, полезней.
Совсем умным офис называть не будем. Пусть будет не глупый. Посмотреть мониторинг в живую можно здесь.
Всем хорошего дня!
ссылка на оригинал статьи https://geektimes.ru/post/272162/
Добавить комментарий