Собственно, метеодатчик — это, наверное, второе что все делают после того, как помигают светодиодом на Arduino. А раз уж этой участи не избежать, то надо разобраться с ней как можно быстрее, чтобы уже двигаться дальше.
Я изначально не планировал смотреть температуру и влажность локально, поскольку большую часть времени в течение недели провожу, во-первых, вне дома, а, во-вторых — со смартфоном. Поэтому вариантов было два: получать погоду по почте или же выгружать в какой-нибудь подходящий онлайновый сервис.
Честно скажу: сначала я хотел делать добро и бросать его в воду отправлять погоду на Openweathermap.org и даже какое-то время делал это. Но потом началось — то сервис внезапно откажет, а я сижу и гадаю, что случилось, то его IP поменяется, и мне надо снова лезть в код центрального контроллера.
В общем, от OWM я отказался, а полученный опыт использовал для адаптации датчика к другому онлайновому сервису. Он, хотя и не использует данные для прогноза, для меня оказался очень удобным, чтобы смотреть и текущую погоду, и статистику.
Назначение
ПИ-ТВ-2 предназначен для измерения текущих значений влажности и температуры, и передачи их центральному домашнему контроллеру КЦДВ-2-12 по радиоканалу.
Других назначений пока не имеет, хотя сетевое питание и контроллер Arduino Pro Mini на борту как бы намекают, что можно еще чего-нибудь добавить. Чем я, вероятно, когда-нибудь и займусь.
. вот так он выглядит в интерьере. Ну а расчет на то, что несовершенство дизайна постоянно прикрывает штора
Принцип работы
ПИ-ТВ-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В было более актуально.
. примерно так вы будете все соединять для заливки скетча
Приобретение датчика температуры и влажности DHT21 определено тем, что я как-то на DX заказал очень простые, но симпатичные часы жене. Только после оплаты магазин отписался, что часов уже на складе нет, а деньги они могут вернуть на счет в магазине, то есть под будущие покупки. Короче, взял почти не глядя.
Параметры подбирал с учетом того, что датчик, скорее всего, будет уличным, поэтому не DHT11, а DHT21 у которого минимальная температура измерения составляет -40С. Сразу скажу: это для Москвы, а если у вас другие минимумы, то датчик тоже будет совсем другой. Например, сверхпопулярный DS18B20, который измеряет до -55C и что-то еще для влажности.
. подходит
Аналоговый передатчик необходим для связи с аналоговым же приемником центрального контроллера с помощью протокола, реализованного в библиотеке 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% нужно его открыть
2. Передатчик
GND — к минусу питания;
VCC — к плюсу питания (от 3В до 12В), также можно к пину VCC Arduino или к любому цифровому пину Arduino в режиме OUTPUT/HIGH для возможности экономии энергии при батарейном питании (по коду это пин 8);
DATA — к пину 6 Arduino.
. примерно так это выглядит в процессе
. в расчете на батарейки
3. Arduino
Если у вас источник 5В, тогда его плюс можно подключить к пину VCC.
Если источник питания выдает заметно больше 5В (но не больше 12В), тогда — к пину RAW. При этом на пинах VCC будет 5В, что можно использовать для датчика DHT21 и другой периферии.
Минус источника питания, соответственно, к GND Arduino.
Немного «возможности экономии энергии при батарейном питании». Дело в том, что Arduino-то мы отправим спать, а что делать с периферией, которая постоянно подключена к питанию? Городить ключи на питающие цепи? Совсем необязательно. Ведь цифровые пины Arduino можно использовать для питания маломощных устройств — передатчиков, приемников, некоторых сенсоров.
А это, в свою очередь, позволяет легко включать и выключать периферию по мере необходимости. Для включения просто переводим пин в режим OUTPUT, пишем в него HIGH и получаем +5В питания. А для выключения пишем в тот же пин LOW.
Вот и все с логикой.
Физически сборка усложнена тем, что я, во-первых, разместил все в корпусе от беспроводного звонка, поскольку надеялся воспользоваться его батарейным отсеком. Кстати, так получилось, что индикаторный светодиод Arduino оказался рядом с окошечком «светомузыки» бывшего звонка, так что через него можно было наблюдать за активностью контроллера, поскольку код предполагает периодическое мигание (да-да, и здесь оно!).
. пока я не выпаял светодиод питания — было видно и его
Во-вторых, подключил датчик DHT21 через штекерный разъем для простоты обслуживания метеодатчика. Провод датчика я удлиннил так, чтобы его можно было без проблем вытянуть за окно.
А в третьих — выпаял светодиод питания, когда еще был одержим идеей питания от батареек. Ведь при включенном питании светодиод горит постоянно, а зачем это нужно метеодатчику?
Для крепления датчика за окном приклеил на него небольшой магнит. В таком виде датчик «прилипает» козырьку или «подоконнику». Креплю я его снизу, чтобы не заливало водой и не перегревало солнцем.
Для питания всего ПИ-ТВ-2 в финальной версии использовал кусочек провода с разъемом под имеющийся сетевой адаптер.
Ну и сам метеодатчик висит на окне на тех же магнитах: один магнит на датчике, другой — на окне. Они, кстати, очень удачно стыкуются гранями (толщина магнита порядка миллиметра), что заметно уменьшает громоздкость: датчик как будто бы просто приклеен к раме.
. тоже не очень эстетично, но зато — спина
Софт
Особенность текущей версии кода в том, что она осталась в наследство от попыток сделать автономный метеодатчик. Поэтому здесь вы можете во всей красе наблюдать энергосберегающую библиотеку, а при желании — попробовать запитать от датчик от батареек. Нужно ему не менее 5В, при этом батареек 14500 емкостью 900 китайских мАч хватает примерно на неделю непрерывной работы.
Обратите внимание: одной батарейки 14500 мало, поэтому нужно две. А две — это 7.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 тока есть масса текстов в интернете. Отдельным личностям удавалось снижать потребление до единиц микроампер, но это, в основном, на «чистых» контроллерах безо всяких там встроенных регуляторов напряжений, светодиодов и проч., и проч. Вот, например.
И, снова, если я где-то ошибся — говорите, буду исправлять.
Автор: spc