Friday, June 14, 2013

Контроль влажности и температуры дома и не только DIY.

Детский кашель двигатель прогресса.

После очередной бессонной ночи и утреннего просмотра лекций д-ра Комаровского стало ясно что влажность, на которую я внимания никогда не обращал, имеет значение для здоровья моего маленького ребенка. Детский кашель очень тесно связан с уровнем влажности (humidity) воздуха, и желательно этот самый уровень отслеживать и им управлять. Собственно для управления уровнем влажности был включен уже давно валявшийся увлажнитель sharp kc-6500e. Но хотелось еще чего нибудь smart, да и увлажнитель один, а комнат много, надо решать где он больше востребован. Температурные показатели легко ощутить без дополнительных приборов. Холодно или тепло в комнате обычно определяешь без градусников, а вот влажность физически ощутить сложнее. Поэтому было принято решение купить/собрать (нужное подчеркнуть) датчики для мониторинга уровня влажности в комнатах.
Побродив по магазинам и просторам сети я понял что не могу купить просто метеостанцию в каком нибудь *Mart, т.к. предлагающиеся устройства никак не вписываются в современность. Ну не буду я бегать каждый час по всем комнатам и записывать показания с экранов метеостанций, хочу чтобы мне эти данные отправлялись куда нибудь, а я потом их проанализирую. На правильную мысль навела статья на Habrhabr. Короче нужно устройство с разъемом Ethernet или wifi или zigbee... Проводные сети я всегда считал более надежными, да и сеть дома проложена с запасом.

Arduino, PoE, DHT11/21/22, narodmon.ru


Постепенно выработались некие требования к решению:

  • сбор данных и передача их в какие либо сервисы (собственные или сторонние)
  • физический интерфейс RJ45 (ethernet) 
  • работа без батареек
  • приглядный внешний вид, отсутствие мотков с проводами вокруг.
  • возможность перетащить в другой дом (с другой сетью и провайдером) без доп настроек.
  • измерение уровня влажности и температуры. При необходимости добавление сенсоров.
  • если собирать самому, то без особых заморочек. Я не дружу с паяльником и программатором.


Исходя из требований к снижению количества проводов и работы без батареек я решил что лучшим решением будет использование PoE (Power over ethernet) для датчика. К тому же незадолго перед этим был заказан коммутатор с PoE под нужды видео-наблюдения. При необходимости, можно подключить и с помощью обычного блока питания.

На данный момент на рынке нашел чешский HWg-STE PoE, отечественный netping, оба вроде отвечают требованиям.

Сервис narodmon.ru предлагает кучу вариантов датчиков и неплохой сервис по отслеживанию их состояния. Средняя стоимость датчиков составляет в среднем 3000 руб., что в общем то меня уже не пугало так сильно как детский кашель. И все бы хорошо, но PoE ни у кого нет. Всем подавай отдельные блоки питания, а это куча лишних проводов, занятая розетка и вообще не интересно.
Самое простое решение которое пришло в голову - взять за основу решение на Arduino и чуть чуть его изменить под свои нужды. Если три платы заменить на одну, и добавить PoE, то получим то что нужно.

Для датчика были заказаны:


  1. Arduino Ethernet Rev3 WITH PoE (A000074)  = €54.90 + доставка  €9 (arduino.cc) В сумме на 2600 руб.
  2. DHT22 2302 Digital Temperature and Humidity Sensor Module = 11$ или 340 руб. (При заказе из Китая их лучше комплектовать с товарами погабаритнее чтобы по почте быстрее шло. Меньше посылка - дольше идет. В моем случае 60 дней).
  3. Как потом оказалось нужен еще USB 2 Serial Converter (A000059) для программирования Arduino, поскольку в этой модели нет USB разъема, его место занял Ethernet. Включать еще €10 в стоимость устройства или нет непонятно, т.к. он нужен только при программировании. В общем плюс еще 400 руб.
Итого требуется электроники на 3340 руб. Если закупать не Made in Italy, а клоны, то будет дешевле, но надо еще найти клоны с PoE модулем. При покупке всего этого добра в России увеличиваем бюджет до 4500 руб. Все элементы доставлялись почтой России, часть дошла за 30 дней, а часть до сих пор в пути, вместо DHT 22 пока установил DHT 11 - они дешевле, но менее точные. Пожалуйста не используйте DHT 11.
С сенсорами вообще вышла какая то неувязка. По идее это должны быть цифровые сенсоры, и распиновка по всем datashit с незадействованным третьим пином.

Но мне с Amperka.ru пришли сенсоры уже с резисторами, с разъемом и работали как аналоговые. При этом судя по пайке в этом варианте не использовался 4й пин (как на картинке справа).



Реализация на DHT 11/21/22 (пожалуйста не покупайте DHT11 - используйте DHT22)

Аналоговое подключение сенсоров.

Скетч который у меня заработал в итоге с аналоговым вариантом DHT11 с библиотекой от амперки (не забываем менять MAC адрес устройства на свой, большая часть кода взята отсюда, отсюда и отсюда ):





У этого решения множество багов:
1. DHT11 в таком исполнении всегда врал. Возможно бракованные сенсоры попались, но врали они безбожно. Влажность почти всегда на одном уровне 33%.
2. Результаты иногда странным образом задваивались, то есть вместо 33% влажности получалось 66%. В код  нужно добавлять контроль результата измерения в сравнении с последними данными.
3. Часть позволяющая устройству работать в качестве веб сервера закоментированна, поскольку я её после отладки не использовал, может надо кому.

Цифровое подключение сенсоров

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

 
Библиотека для DHT здесь  и теперь он поддерживает и DHT21.
Код:


Внимание апдейт - я пересмотрел свое отношение к коду - оказалось что датчик корректно отображал показания только при первом включении. Дальше показания не менялись до следующей перезагрузки. Поэтому исходный код я изменил, и новый вставил в статью на место старого. Кроме того, обращаю внимание - для работы скетча необходимо установить соответствующую библиотеку. Библиотека для DHT не входит в стандартный набор устанавливаемый вместе с IDE Adruino. Библиотеку я использовал не с Amperka.ru. 

готовое устройство:

В качестве корпуса использовал корпуса от FDD и CD.
метеостанция Arduino +DHT22

датчик Arduino + DHT22 в сборе

DHT22 с обвязкой

Кстати, есть новая версия скетча и инструкций.


11 comments:

  1. может кто подскажет более подходящий вариант корпуса?

    ReplyDelete
  2. а как сюда добавить ds18b20 ?

    ReplyDelete
    Replies
    1. на руках нет ds18b20 чтобы проверить, но сложного быть ничего не должно. Нужно именно добавить, или заменить DHT22 на ds18b20?
      на первую ногу ds18b20 нужно подать GND, на последнюю +5V, а среднюю подключить к Digital выходам Arduino, например к 2му. Дополнительно установить поттягивающий резистор 4.7k между +5V и средней ножкой ds18b20. Если лень соединять +5V для DHT и DS, то можно DHT переключить на +3, он продолжит работать.
      Схема для DS здесь http://bildr.org/2011/07/ds18b20-arduino/
      Что касается кода, то для начала устанавливаем библиотеку onewire ( http://www.pjrc.com/teensy/arduino_libraries/OneWire.zip копируем в папку с библиотеками Ардуино IDE).
      Затем вписать в начало кода и в часть loop все то что указано по ссылке bildr.org.
      Ну и затем - наша задача добавить в переменную replybuffer еще один сенсор (мак адрес + цифра) и значение.
      Нужно убедиться что в начале мы задали нужную длину переменной, например char replyBuffer[106];

      добавить перед httpRequest();
      :

      strcat(replyBuffer,"&");
      for (int k=0; k<6; k++)
      {
      int b1=mac[k]/16;
      int b2=mac[k]%16;
      char c1[2],c2[2];

      if (b1>9) c1[0]=(char)(b1-10)+'A';
      else c1[0] = (char)(b1) + '0';
      if (b2>9) c2[0]=(char)(b2-10)+'A';
      else c2[0] = (char)(b2) + '0';

      c1[1]='\0';
      c2[1]='\0';

      strcat(replyBuffer,c1);
      strcat(replyBuffer,c2);
      }
      strcat(replyBuffer,"03");

      strcat(replyBuffer,"=");

      strcat(replyBuffer,TemperatureSum);

      вроде все - должно бы работать.

      Delete
    2. хотя я вот думаю раз мак адрес так часто используется - надо его в eeprom хранить или цикл с вытаскиванием mac адреса вытащить отдельно. Но работать и так должно.

      Delete
  3. сделал как вы писали. вышло http://visualbooster.com/share/20140324011642013.png так, уже три айди видны. в инете тока два. (01,02 то DHT22 ,и 03 это 1820.) датчик 1820 не выходит в инет.
    странно как то 26,75 перенос идёт на строку ниже. а должно быть по идеи в одну строку?
    http://codepad.org/BiXsilsK скетч мой.
    обратите внимание на строки 71,74,77. там возникает ошибка http://visualbooster.com/share/20140324013317216.png я их за компилировал. //
    может я что не так вставил?

    ReplyDelete
  4. Для начала - ошибка unknown error. Она говорит о том что с DHT22 что то не так. До подключения DS такая ошибка возникала? На изменение температуры сенсоры реагируют?
    Хотя скорее всего просто не та библиотека dht используется что у меня. у меня ошибок на 70х строках нет. Сегодня скачаю новую версию https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib проверю.

    переноса на новую строку быть не должно - именно в этом скорее всего и проблема.
    судя по всему он выводит
    Serial.println(temperature);
    то есть в replybuffer ничего не попадает.

    вывод - ставим получение температуры в коде повыше и в replybuffer вводим temperature (только нужно сконвертить тип данных в стр и получить новую переменную)

    strcat(replyBuffer,"=");

    float temperature = getTemp();
    Serial.println(temperature);

    dtostrf(temperature, 4, 1, DStemp);

    strcat(replyBuffer,DStemp);

    httpRequest();

    }

    ссылка на код компилирующийся без проблем http://codepad.org/BF17CEmj (правда еще не значит что он работает :) )

    библиотеки используемые у меня https://drive.google.com/file/d/0BxxWiuadfEvdQnFXWTR2SGpDczA/edit?usp=sharing

    ReplyDelete
  5. в общем работает http://visualbooster.com/share/20140324200448140.png вывод в терминал есть.
    но в инете на сервере не видит. мак адреса прописаны мои.
    с вашей библиотекой не вылетает ошибка на 70-х строчках больше.

    ReplyDelete
    Replies
    1. попробуйте добавить перенос строки перед отправкой replybuffer

      client.println();
      client.println(replyBuffer);
      client.println();

      в моем коде это строки 290 и 294 - раскомментировать.

      Delete
  6. Есть, работает!!! http://visualbooster.com/share/20140324221529125.png
    кстати, можно без датчика провериться , просто подтянув ногу (7) через резистор до + пит. и тогда темп. будет -1000. ну хоть проверить можно будет.
    В общем спасибо Вам за помощь, код работает.

    хотя пока писал увидел. что один из 1820 не хотел работать. и показывал темп 85град. а если поставить другой. то темп. показывает нормально. датчик целый по тому как работал на улице на предыдущей прошивке. (ну для меня это не принципиально, так как у меня два 1820. ) Спасибо за помощь!!! если вдруг что получиться самому доработать ещё вставить какие то датчики. то сообщу Вам.
    Спасибо!

    ReplyDelete
  7. и ещё забыл спросить, что делает эта строчка. откуда она появилась dtostrf(temperature, 4, 1, DStemp);

    ReplyDelete
    Replies
    1. эта строчка переводит данные из значения float в значение string. Из переменной temperature в переменную dstemp.
      т.к. replybuffer у нас типа string - мы не можем просто так ей приплюсовать числа, не приведя к этому же формату.
      Welcome.

      Delete