Pull to refresh

Прибор измерительный температуры и влажности ПИ-ТВ-2

Reading time 9 min
Views 53K
Собственно, метеодатчик — это, наверное, второе что все делают после того, как помигают светодиодом на Arduino. А раз уж этой участи не избежать, то надо разобраться с ней как можно быстрее, чтобы уже двигаться дальше.

Я изначально не планировал смотреть температуру и влажность локально, поскольку большую часть времени в течение недели провожу, во-первых, вне дома, а, во-вторых — со смартфоном. Поэтому вариантов было два: получать погоду по почте или же выгружать в какой-нибудь подходящий онлайновый сервис.

Честно скажу: сначала я хотел делать добро и бросать его в воду отправлять погоду на Openweathermap.org и даже какое-то время делал это. Но потом началось — то сервис внезапно откажет, а я сижу и гадаю, что случилось, то его IP поменяется, и мне надо снова лезть в код центрального контроллера.

В общем, от OWM я отказался, а полученный опыт использовал для адаптации датчика к другому онлайновому сервису. Он, хотя и не использует данные для прогноза, для меня оказался очень удобным, чтобы смотреть и текущую погоду, и статистику.





Назначение

ПИ-ТВ-2 предназначен для измерения текущих значений влажности и температуры, и передачи их центральному домашнему контроллеру КЦДВ-2-12 по радиоканалу.

Других назначений пока не имеет, хотя сетевое питание и контроллер Arduino Pro Mini на борту как бы намекают, что можно еще чего-нибудь добавить. Чем я, вероятно, когда-нибудь и займусь.

. вот так он выглядит в интерьере. Ну а расчет на то, что несовершенство дизайна постоянно прикрывает штора
image

Принцип работы

ПИ-ТВ-2 предназначен для совместной работы с центральным домашним контроллером КЦДВ-2-12 или аналогичным устройством, способным принимать и интерпретировать принятые данные. Формат данных — ниже по тексту и также виден в скетче.

ПИ-ТВ-2 не отображает текущие показания и не имеет проводного подключения к каким-либо внешним устройствам, кроме датчика температуры/влажности и передатчика.

Показания температуры и влажности, измеренные датчиком DHT21, передаются центральному контроллеру по радиоканалу с интервалом в полчаса. Центральный контроллер выгружает показания по протоколу HTTP POST на сервис "Народный мониторинг" с интервалом в один час. Оба интервала никак не привязаны друг другу и не синхронизируются.

ДЕМО показаний датчика

При нормальной работе встроенный светодиод Arduino мигает с интервалом около 8 секунд.

Коррекция ошибок и контроль приема и целостности передаваемых данных не предусмотрены.

Железо

По конструкции ПИ-ТВ-2 очень прост и состоит всего из четырех основных компонентов (ссылки, как обычно — просто для примера):

1. Arduino Pro Mini 5В, 16 МГц с чипом ATmega328.
2. Комбинированный датчик температуры и влажности DHT21.
3. Передатчик 433 МГц с амплитудной модуляцией (из такого комплекта, например).
4. Резистор 4.7кОм, 0.125Вт
5. Источник питания 5В — 9В (опционально, можете поэкспериментировать с батарейками или аккумуляторами).
6. Для заливки кода в Arduino Pro Mini потребуется и вот такой (или аналогичный) конвертер COM-USB (опционально — возможно, он у вас уже есть).

Именно этот контроллер — потому что он компактный и уже лежал у меня в ящике для всяких самоделок. А купил я пачку этих контроллеров, потому что они были недорогие и встречались чаще, чем версия 3В. Да и не думал я, что буду питать это хозяйство от 3В, поэтому 5В было более актуально.

. примерно так вы будете все соединять для заливки скетча
image

Приобретение датчика температуры и влажности DHT21 определено тем, что я как-то на DX заказал очень простые, но симпатичные часы жене. Только после оплаты магазин отписался, что часов уже на складе нет, а деньги они могут вернуть на счет в магазине, то есть под будущие покупки. Короче, взял почти не глядя.

image

Параметры подбирал с учетом того, что датчик, скорее всего, будет уличным, поэтому не DHT11, а DHT21 у которого минимальная температура измерения составляет -40С. Сразу скажу: это для Москвы, а если у вас другие минимумы, то датчик тоже будет совсем другой. Например, сверхпопулярный DS18B20, который измеряет до -55C и что-то еще для влажности.

. подходит
image

Аналоговый передатчик необходим для связи с аналоговым же приемником центрального контроллера с помощью протокола, реализованного в библиотеке RC-Switch. Повторюсь, в центральном контроллере библиотеку я использую по двум назначениям: управление беспроводными розетками и периферией, а также обмен данными с сервисными контроллерами. Это позволяет обойтись минимумом оборудования и заодно экономит память, так как не нужны специализированные библиотеки для беспроводных коммуникаций.

Еще один выбор — автономное или сетевое питание. Опять же, я честно пытался использовать автономное питание: мне нравилась идея, что датчик будет просто где-то висеть без проводов. Но не получилось. По факту даже у Arduino Pro Mini довольно высокое потребление энергии, если не уметь отключать все и вся. А я не научился.

Максимум, что мне удалось выжать с различными библиотеками «сна» — около недели работы на аккумуляторах типа 14500. Два аккумулятора при этом умерли в течение пары недель по непонятной причине. По идее ведь защита должна была предотвращать чрезмерный разряд, но по факту — просто блокировала аккумулятора. Снятие защиты продлило срок работы аккумулятора еще на неделю, после чего она умерла окончательно.

Итог — сетевой бок питания и никаких волнений.

Логически сборка выглядит следующим образом:

1. Датчик DHT21

GND — к минусу питания;

VCC — к пину VCC Arduino или к любому цифровому пину Arduino в режиме OUTPUT/HIGH для возможности экономии энергии при батарейном питании (по коду это пин 7) или к выходу 5В блока питания (если у вас блок 5В). К 9В датчик подключать нельзя;

OUT — напрямую к пину 5 Arduino и через резистор 4.7 кОм — к плюсу питания (подтягиваем к плюсу).

. в принципе, и по проводам видно, но чтобы быть уверенным на 100% нужно его открыть
image

2. Передатчик

GND — к минусу питания;

VCC — к плюсу питания (от 3В до 12В), также можно к пину VCC Arduino или к любому цифровому пину Arduino в режиме OUTPUT/HIGH для возможности экономии энергии при батарейном питании (по коду это пин 8);

DATA — к пину 6 Arduino.

. примерно так это выглядит в процессе
image

. в расчете на батарейки (аккумуляторы)
image

3. Arduino

Если у вас источник 5В, тогда его плюс можно подключить к пину VCC.

Если источник питания выдает заметно больше 5В (но не больше 12В), тогда — к пину RAW. При этом на пинах VCC будет 5В, что можно использовать для датчика DHT21 и другой периферии.

Минус источника питания, соответственно, к GND Arduino.

Немного «возможности экономии энергии при батарейном питании». Дело в том, что Arduino-то мы отправим спать, а что делать с периферией, которая постоянно подключена к питанию? Городить ключи на питающие цепи? Совсем необязательно. Ведь цифровые пины Arduino можно использовать для питания маломощных устройств — передатчиков, приемников, некоторых сенсоров.

А это, в свою очередь, позволяет легко включать и выключать периферию по мере необходимости. Для включения просто переводим пин в режим OUTPUT, пишем в него HIGH и получаем +5В питания. А для выключения пишем в тот же пин LOW.

Вот и все с логикой.

Физически сборка усложнена тем, что я, во-первых, разместил все в корпусе от беспроводного звонка, поскольку надеялся воспользоваться его батарейным отсеком. Кстати, так получилось, что индикаторный светодиод Arduino оказался рядом с окошечком «светомузыки» бывшего звонка, так что через него можно было наблюдать за активностью контроллера, поскольку код предполагает периодическое мигание (да-да, и здесь оно!).

. пока я не выпаял светодиод питания — было видно и его
image

Во-вторых, подключил датчик DHT21 через штекерный разъем для простоты обслуживания метеодатчика. Провод датчика я удлиннил так, чтобы его можно было без проблем вытянуть за окно.

А в третьих — выпаял светодиод питания, когда еще был одержим идеей питания от аккумуляторов. Ведь при включенном питании светодиод горит постоянно, а зачем это нужно метеодатчику?

Для крепления датчика за окном приклеил на него небольшой магнит. В таком виде датчик «прилипает» козырьку или «подоконнику». Креплю я его снизу, чтобы не заливало водой и не перегревало солнцем.

Для питания всего ПИ-ТВ-2 в финальной версии использовал кусочек провода с разъемом под имеющийся сетевой адаптер.

Ну и сам метеодатчик висит на окне на тех же магнитах: один магнит на датчике, другой — на окне. Они, кстати, очень удачно стыкуются гранями (толщина магнита порядка миллиметра), что заметно уменьшает громоздкость: датчик как будто бы просто приклеен к раме.

. тоже не очень эстетично, но зато — спина
image

Софт

Особенность текущей версии кода в том, что она осталась в наследство от попыток сделать автономный метеодатчик. Поэтому здесь вы можете во всей красе наблюдать энергосберегающую библиотеку, а при желании — попробовать запитать от датчик от аккумуляторов. Нужно ему не менее 5В, при этом аккумуляторов типа 14500 емкостью 900 или 1000 китайских мАч хватает примерно на неделю непрерывной работы.

Обратите внимание: одного аккумулятора 14500 мало, поэтому нужно два. А два — это суммарно 7.4В по характеристикам на борту аккумуляторов (и около 8.4В сразу после полной зарядки), поэтому нужно подключать к пину RAW Arduino, чтобы ее не убить. И датчик DHT21, соответственно только к пину VCC Arduino или к питающему цифровому пину.

Так как используемая энергосберегающая библиотека усыпляет контроллер не более чем на 8 секунд, то ее вызов живет в цикле, который обеспечивает около получаса не совсем здорового, но все же сна.

В том же цикле мигает встроенный светодиод-индикатор Arduino. При работе от аккумуляторов это позволяло быстро и просто понять жив контроллер, или уже пора перезаряжаться. Сейчас это просто индикатор активности.

В результате показания датчика передаются в центральный контроллер с интервалом в полчаса. Такой интервал выбран сразу по нескольким причинам: максимальная экономия батареек (когда это было актуально) при более-менее достоверных данных и экономия ресурсов центрального контроллера, у которого и другие дела есть, кроме как постить погоду в интернет.

Для передачи показаний я использую, так сказать, проприетарный протокол, работающий поверх RC-Switch. Выглядит он следующим образом: датчик передает числа вида 161HSXXX, где H — признак влажности, S — знак температуры, XXX — значение климатического параметра с точностью до десятых, умноженное на 10.

Если H = 1, контроллер считает, что переданы показания влажности. Если H = 0, контроллер думает, что получил температуру. Если S = 0 температура считается положительной, если S = 1, то — отрицательной.

Оба параметра передаются метеодатчиком с небольшим интервалом, чтобы гарантированно обеспечить время на обработку на стороне центрального контроллера, который затем оформляет все виде HTTP POST-запроса для передачи в интернет. Хранение и визуализация параметров осуществляется с помощью "Народного мониторинга". Вы, разумеется, можете выбрать любой другой подходящий ресурс или собственный сервис, но тогда не забудьте исправить код центрального контроллера или же свой сервис для получения данных в существующем формате.

Не забудьте, что для компилляции этого кода вам потребуются три нестандартные библиотеки:

1. DHT22 для датчика.
2. LowPower для энергосберегающего режима.
3. RC-Switch для передачи показаний.

Скетч беспроводного метеодатчика
// 23.11.2013 - питание передатчика и датчика от цифровых пинов, библиотека сна Low Power

#include <LowPower.h> // https://github.com/rocketscream/Low-Power
#include <DHT22.h> // для датчика https://github.com/nethoncho/Arduino-DHT22
#include <RCSwitch.h> //   http://code.google.com/p/rc-switch/



// Необходимо подключить резистор 4.7К между VCC и пином Out DHT22

#define DHT22_PIN 5 // DHT21 подключается к цифровому пину 5 Arduino

// Создаем объект DHT22
DHT22 myDHT22(DHT22_PIN);

#define txPIN 6 // пин передатчика
#define sensorPower 7 // питание датчика
#define txPower 8 // питание передатчика

// Создаем объект RCSwitch
RCSwitch meteoSwitch = RCSwitch();

byte param = 0; // тип данных (температура/влажность)
unsigned long myData; // данные к отправке


void setup()
{
pinMode(sensorPower, OUTPUT); // инициализация пина питания датчика 
pinMode(txPower, OUTPUT); // инициализация пина питания передатчика
meteoSwitch.enableTransmit(txPIN); // инициализация передатчика
meteoSwitch.disableReceive();
getWeather(); // отправка погоды на старте, чтобы сразу понять работает датчик, или нет
pinMode(13, OUTPUT); // инициализация пина со встроенным светодиодом Arduino
}

// ПОЛУЧЕНИЕ И ОТПРАВКА ПОГОДЫ
void getWeather()

{
digitalWrite(sensorPower, HIGH); // включаем датчик
digitalWrite(txPower, HIGH); // включаем передатчик

delay(3000); // пауза для инициализации датчика
  
  DHT22_ERROR_t errorCode; // читаем данные и получаем код ошибки
  errorCode = myDHT22.readData();

  if (errorCode == 0) { // если ошибок нет

// сначала отправляем температуру

      	if (myDHT22.getTemperatureCInt()>30000) {
	    myData = 16101000 + abs((myDHT22.getTemperatureCInt()-32768));} // температура = код датчика + признак температуры + знак температуры + температура
        else {
            myData = 16100000 + myDHT22.getTemperatureCInt();} // температура = код датчика + признак температуры + знак температуры + температура 

	    meteoSwitch.send(myData, 24); // отправляем температуру
	    meteoSwitch.send(myData, 24); // отправляем температуру (дубль)
            
            delay(1000);

// теперь отправляем влажность

            myData = 16110000 + myDHT22.getHumidityInt(); // влажность = код датчика + признак влажности + влажность
            meteoSwitch.send(myData, 24); // отправляем влажность
            meteoSwitch.send(myData, 24); // отправляем влажность
            lightsOn();
  }
digitalWrite(sensorPower, LOW); // выключаем датчик
digitalWrite(txPower, LOW); // выключаем передатчик
}
  
void loop ()
{ 

for (byte i=0;i<=225;i++){
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); // уходим спать
lightsOn(); // мигаем при каждом пробуждении
}
getWeather(); // отправляем погоду после сна

}

void lightsOn() {
  
    digitalWrite(13, HIGH); // мигаем светодиодом
    delay(500);
    digitalWrite(13, LOW);
}




Заключительное слово

Самая большая проблема после энергоэффективности — надежность радиоканала. То ли я что-то не так делаю, то ли просто дома какая-то удивительно плохая обстановка с помехами, но датчик более-менее заработал на расстоянии в 5-6 метров от контроллера только если к обычному передатчику была прикручена немаленькая телескопическая антенна, или если я использовал более дорогой передатчик.

Еще одна особенность в том, что мой экземпляр DHT21 фактически перестает измерять влажность при ее высоких значениях. В какой-то момент его просто клинит на 99.9%, и пока влажность не уменьшится до некоторого порога, значение не меняется.

И раз уж это ко мне привязалось, то по поводу потребяемого Arduino тока есть масса текстов в интернете. Отдельным личностям удавалось снижать потребление до единиц микроампер, но это, в основном, на «чистых» контроллерах безо всяких там встроенных регуляторов напряжений, светодиодов и проч., и проч. Вот, например.

И, снова, если я где-то ошибся — говорите, буду исправлять.
Tags:
Hubs:
+29
Comments 33
Comments Comments 33

Articles