Не глупый офис

от автора

Я никогда бы не рискнул написать статью об очередной реализации умного дома с подключением датчиков утечек воды в ванной и системами слежения за проделками кота в квартире. Слава богу, кот под контролем собаки, вода вроде тоже не течёт. Но всё же мы больше находимся на работе, в различных офисах, где не всегда удается создать оптимальную рабочую среду. Статья посвящена системе экологического мониторинга рабочего пространства в офисе и тем мероприятиям, которые мы провели после месяца её (на удивление) стабильной работы. Конечно, все данные отправляем в облака, смотрим на них со своих смартфонов, полезности в этом никакой, зато повод похвалиться перед близкими и знакомыми, да и в офисе стало покомфортней. Реализовано всё на 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *