Домашний климат контроль

Возможна ли переделка кондиционера в климат-контроль

Какая в этом нужда? Инверторная бытовая сплит-система производства Daikin или Mitsubishi Electric мало чем уступит системе климат-контроля. Она может поддерживать температуру на заданном уровне, регулировать влажность, проветривать помещение, задавать струе воздуха нужное направление, ионизировать, дезинфицировать воздух, удалять неприятные запахи и т.д. Причем все эти режимы могут быть заранее запрограммированы.

Инверторный кондиционер Daikin в интерьере

Надо признать, что японские ученые далёко продвинулись в деле реализации идеи «умного дома» или «умного офиса», причем облекли эту идею в малогабаритную и удобную форму бытовой сплит-системы.

Но, может, есть смысл сделать «климат» вместо кондиционера эконом-класса? Произвести, своего рода, ап-грейд?

Давайте прикинем объем работы.

Проведем анализ конструкций современных «умных домов». Что в них, как минимум, включает климат-контроль:

  • установка кондиционеров

Один из вариантов системного обеспечение климат-контроля в «умном доме»

  • подключение электрического теплого пола
  • управление 2-3 электрообогревателями
  • управление щелевыми проветривателями пластиковых окон, ионизатором, дезодоратором
  • а также необходимые датчики, контроллеры, интерфейс и т.д.

Один из проектов умного дома

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

Очевидно, слишком сложная это штука – погода в доме!

Недавно обнаружил удобный онлайн-сервис для ведения статистики любой числовой информации и отображение её в виде графиков. Немного подумав, решил на его основе сделать цифровой термометр.

Внимание! Содержимое данной статьи уже неактуально, так как сервис Pachube прекратил своё существование. Статья оставлена как есть просто для истории.
Необходимые компоненты:

  • Arduino (Freeduino, *duino);
  • Ethernet Shield;
  • цифровой датчик температуры DS18B20;
  • резистор 4.7 кОм;
  • прямые руки 🙂

Вот собственно сам цифровой датчик DS18B20:

И его распиновка:

Его мы будем подключать по шине 1-wire по схеме с паразитным питанием. При этом, можно использовать несколько таких датчиков (все они соединяются параллельно двумя проводами) и считывать с каждого отдельную температуру. Таким образом, при желании, можно контролировать температуру в каждом уголке комнаты 🙂
Напоминаю, что Ethernet Shield использует для своих нужд пины 10, 11, 12 и 13, поэтому использовать их нельзя.



Теперь зальём в ардуино следующий скетч:

#include <ERxPachube.h> #include <Ethernet.h> #include <SPI.h> #include <OneWire.h> #include <DallasTemperature.h> //************************************************************************************ byte mac = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC-адрес byte ip = { 192, 168, 1, 177 }; // IP-адрес #define PACHUBE_API_KEY «ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890″ // ВАШ PACHUBE_API_KEY #define PACHUBE_FEED_ID 00000 // ВАШ ID #define DATA_STREAM 1 //Номер PACHUME DATASTREAM #define ONE_WIRE_BUS 2 // Номер цифрового порта, к которому подключен термодатчик //************************************************************************************ ERxPachubeDataOut dataout(PACHUBE_API_KEY, PACHUBE_FEED_ID); OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); float SumTemp, CountTemp; unsigned long dt; void setup() { Serial.begin(9600); //для отладки Ethernet.begin(mac, ip); sensors.begin(); CountTemp = 0; SumTemp = 0; dt=millis(); dataout.addData(1); //добавляем поток данных } void loop() { //делаем синхронизацию и запрашиваем температуру sensors.setWaitForConversion(false); sensors.requestTemperatures(); sensors.setWaitForConversion(true); //разрешение датчика int resolution = 12; delay(750/ (1 << (12-resolution))); // получаем данные о температуре float fSensorData=sensors.getTempCByIndex(0); SumTemp=SumTemp+fSensorData; CountTemp++; //Раз в минуту усредняем данные и отправляем на сервер if (abs(millis()-dt)>=60000 ) { fSensorData=SumTemp/CountTemp; char test; //обновляем данные dataout.updateData(1, floatToString(test, fSensorData, 2, 7)); int status = dataout.updatePachube(); //для отладки выводим показания в консоль Serial.println(fSensorData); CountTemp = 0; SumTemp = 0; dt=millis(); } delay(5000); } //функция для перевода из десятичной дроби в строковый вид char * floatToString(char * outstr, double val, byte precision, byte widthp){ char temp; //increase this if you need more digits than 15 byte i; temp=’\0′; outstr=’\0′; if(val < 0.0){ strcpy(outstr,»-\0″); //print «-» sign val *= -1; } if( precision == 0) { strcat(outstr, ltoa(round(val),temp,10)); //prints the int part } else { unsigned long frac, mult = 1; byte padding = precision-1; while (precision—) mult *= 10; val += 0.5/(float)mult; // compute rounding factor strcat(outstr, ltoa(floor(val),temp,10)); //prints the integer part without rounding strcat(outstr, «.\0″); // print the decimal point frac = (val — floor(val)) * mult; unsigned long frac1 = frac; while(frac1 /= 10) padding—; while(padding—) strcat(outstr,»0\0»); // print padding zeros strcat(outstr,ltoa(frac,temp,10)); // print fraction part } // generate width space padding if ((widthp != 0)&&(widthp >= strlen(outstr))){ byte J=0; J = widthp — strlen(outstr); for (i=0; i< J; i++) { temp = ‘ ‘; } temp = ‘\0’; strcat(temp,outstr); strcpy(outstr,temp); } return outstr; }

Обратите внимание на следующие строки:
//************************************************************************************ byte mac = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // MAC-адрес byte ip = { 192, 168, 1, 177 }; // IP-адрес #define PACHUBE_API_KEY «ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890» // ВАШ PACHUBE_API_KEY #define PACHUBE_FEED_ID 00000 // ВАШ ID #define DATA_STREAM 1 //Номер PACHUME DATASTREAM #define ONE_WIRE_BUS 2 // Номер цифрового порта, к которому подключен термодатчик //************************************************************************************ Значения надо будет заменить своими данными. Вводим IP, который получит ардуина в локальной сети. С последним параметром (ONE_WIRE_BUS) надеюсь всё ясно — это номер цифрового порта Arduino, к которому подключен термодатчик. Рассмотрим остальные параметры, которые вы получите на сайте pachube.com :

1. Регистрируемся на сайте pachube.com.
2. Создаём новую ленту (feed) в которой будут отображаться показания термодатчика. Для этого в правом меню выбираем «Create a feed»:

Вводим название ленты, описание, теги, при необходимости указываем местоположение.

Можно ввести адрес своего сайта и e-mail для связи.
Указываем, расположен ли датчик внутри помещения (indoor) или снаружи (outdoor), фиксированный (fixed) или мобильный (mobile), а также является ли он реальным (physical) или виртуальным (virtual).
После этого добавляем поток данных (Add a datastream), где вводим числовой ID (это как раз и будет параметром DATA_STREAM), теги, единицу измерения (Celsius) и символ (°C). Не забываем сохранить данные, нажав на кнопку «Save».

3. Теперь в правом меню выбираем «My keys». Затем «create a new key here».


Придумываем название ключа. Выбираем пункт «Use specific feed(s)», в выпадающем левом списке выбираем созданный ранее feed (Номер этой ленты будет параметром PACHUBE_FEED_ID). Если вы хотите, чтобы ключ работал только для одного потока данных, то в правом выпадающем списке выбираем конкретный номер потока. В параметрах доступа (Access Privileges) ставим галочки READ и UPDATE.
После этого жмём кнопку «Create».

Видим созданный нами ключик (это будет параметр PACHUBE_API_KEY). Не сообщайте его никому, он даёт доступ к обновлению данных.

Прошиваем скетч с вашими параметрами в ардуину, подключаем Ethernet Shield, термодатчик, ethernet-кабель. Включаем!
Опрос термодатчика происходит каждые 10 секунд. Один раз в минуту значения усредняются и отправляются на сервер. Следить за температурой можно по ссылке https://pachube.com/feeds/00000 , где вместо 00000 подставьте свой ID.
У меня график выглядел так:

P.S. данный сервис можно применять не только для контроля температуры, но и многих других данных: влажность, скорость ветра, энергопотребление и т.д.

Файлы Скетч (3.43 KB)
Библиотеки:
DallasTemperature (22.27 KB)
ERxPachube (10.8 KB)
Ethernet (29.73 KB)
OneWire (8.54 KB)
SPI (7.49 KB)

Работа проверялась с Arduino IDE v0.22

Предупреждение! Автор не несёт ответственности за возможную порчу оборудования. Всё, что вы делаете — вы делаете на свой страх и риск! Комментарии

  1. Дмитрий, огромное спасибо Вам за такую подробную инструкцию!

    1. Рад, что смог чем-то помочь ??

  2. Спасибо! Очень интересный пример по работе с 18В20 и программирования Arduino.
    Я не большой знаток Си но видимо это оттуда, что значит звездочка * в объявлении символьной переменной «char * floatToString(char * outstr,…..»
    И зачем мы передаем пустую строку test в эту функцию??

    1. Звёздочка означает что это указатель.
      Функцию floatToString я не сам писал, этот массив там нужен для каких-то внутренних нужд, сильно в его работу я не вникал.

  3. Предлагаю присоединиться к отечественному проекту Народного мониторинга (http://narodmon.ru) для отображения на карте показаний датчиков с устр-в измерения в различных городах РФ и СНГ.
    На данный момент устр-в на базе Arduino нет, предлагаю стать первым!
    Для оперативной связи ICQ 98-068-235

  4. Судя по всему на у сервиса изменился интерфейс, что-то никак не получается отправить данные на pachube …

    1. Только что проверил. Данные отправляются. А вот про новое оформление сервиса надо бы мне написать статью…

  5. Данные уходят,но сайт их не принимает, на всякий случай пробовал без роутера, но увы. Проверил ip у портала не поменялись, скетч проходит без проблем. При создании устройства выбирал как обычный feed так и Arduino устройство. Ключи проверял, генерировал как ограниченные так и не ограниченные. На сайте смотрел примеры, сверял и вашими вариантом, вроде похоже. Возможно где-то я сделал не правильно, но увы пока не нашёл. Пытаюсь разобраться ,если получится, то напишу или может вы подскажете. (Arduino IDE v0.22 Ubuntu 10.04)

    1. Здравствуйте! Я сейчас в поездке, через неделю вернусь домой — проверю работу.

      1. Спасибо, надеюсь успею сам добить проблему, чувствую она рядом =)),но если не успею, буду признателен за ваш ответ.

Мониторинг температуры на Arduino и Cosmo GSM Connect

Разберем пример устройства позволяющего удаленно отслеживать показания сенсоров, например — датчиков температуры. В качестве аппаратной части устройства будем использовать — Arduino (Uno или другие версии), GSM-шилд «Cosmo GSM Connect», датчики температуры.

Основные возможности системы.

  • Получать СМС при понижении/повышении температуры, причем индивидуально для каждого датчика.
  • Получать СМС при возвращении температуры в заданный интервал.
  • Запрашивать по дозвону текущие показания всех датчиков.

При превышении заданного порогового значения температуры произойдет отправка тревожного СМС-сообщения. При возвращении показаний датчика в нормальный температурный диапазон — отправка соответствующее СМС уведомление. Также реализуем возможность получения показания датчиков по запросу.

Для получения точных значений температуры будем использовать цифровой температурный датчик DS18B20. Его диапазон измерений от –55°C до +125°C и точность 0.5°C в диапазоне от –10°C до +85°C. DS18B20 обменивается данными по 1-Wire шине в 9-12 битном (программируется пользователем) коде с ценой младшего разряда от 0.5°C до 0.0625°C и при этом датчик может быть как единственным устройством, так и работать в группе.

Питание датчика возможно двумя способами — внешнее и паразитное питание. При паразитном питании максимально измеряемая температура составляет + 100 °C. Для расширения диапазона температур до + 125 °C необходимо использовать внешнее питание.

Сенсор DS18B20 отличается наличием во внутренней энергонезависимой памяти (EEPROM) программируемых установок по превышению температуры (TH) и по понижению температуры (TL). Внутренний регистр флага будет выставлен, когда измеренная температура больше чем TH или меньше чем TL.

Итак, возьмем два датчика DS18B20 и подключим их по паразитной схеме питания к 8 пину Ардуино.

Воспользуемся функциональной возможностью встроенной в датчик EEPROM и укажем для каждого сенсора свой диапазон температур. При пересечении этого диапазона, как в большую, так и в меньшую сторону — произойдет срабатывание регистра и в этом случае будем производить отправку тревожного СМС.

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

Для работы с датчиками DS18B20 скачайте и установите библиотеку DallasTemperature.

Для работы с шилдом «Cosmo GSM Connect» скачайте и установите библиотеку GSM

Итак, запускаем Arduino IDE, копируем в него следующий скетч.

#include <GSM.h> #include <avr/pgmspace.h> const char RemoteID PROGMEM = «+79281112233»; // Шаблон номера, с которого ждём звонка //и на который отправляем СМС const char PIN PROGMEM = «0000»; // ПИН-код! unsigned long interval = 60000; // Интервал проверки состояния GPRS соединения; 60 секунд unsigned long currentMillis; unsigned long previousMillis; #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 8 // Номер линии, к которой подключены датчики температуры boolean alarm1 = false; boolean alarm2 = false; OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress sensor_1, sensor_2; // Используем 2 температурных датчика unsigned long previousMillisTemp = 0; unsigned long intervalTemp = 1000; // Интервал опроса датчиков; 1 секунда String textMessage; char s; float tempS1; float tempS2; void setup() { sensors.begin(); if (!sensors.getAddress(sensor_1, 0)) {}; if (!sensors.getAddress(sensor_2, 1)) {}; sensors.setHighAlarmTemp(sensor_1, 30); // alarm when temp is higher than 30C sensors.setLowAlarmTemp(sensor_1, -10); // alarm when temp is lower than -10C sensors.setHighAlarmTemp(sensor_2, 30); // alarm when temp is higher than 30C sensors.setLowAlarmTemp(sensor_2, 27); // alarn when temp is lower than 27C while (GSM.Init(PIN)<0); GSM.NewSMSindic(); GSM.WaitCall(); GSM.WaitSMS(); previousMillis=millis(); } void loop() { // Начало отсчёта 60 сек. currentMillis = millis(); // Проверяем входящие вызововы if (IncomingCall == 1) { //пришёл звонок! while (GSM.TerminateCall()<0); IncomingCall = 0; if (strstr_P(CallerID, RemoteID)) { // Номер звонящего совпал с шаблоном sendData(0, 0, 0); // Отправляем СМС с показаниями по запросу } GSM.WaitCall(); currentMillis = previousMillis = millis(); } // Пора проверить состояние GPRS подключения if(currentMillis — previousMillis > interval) { if ((GSM.CheckStatus() != 1)) { // GPRS соединение не установлено! while (GSM.Init(PIN)<0); // Делаем инициализацию } GSM.WaitCall(); currentMillis = previousMillis = millis(); } // Считываем показания датчиков температуры if(currentMillis — previousMillisTemp > intervalTemp) { previousMillisTemp = currentMillis; sensors.requestTemperatures(); if (sensors.hasAlarm(sensor_1)) { // у сенсора 1 сработал Alarm if(!alarm1) { sendData(1, 1, true); // Отправляем тревожное СМС } } else { if(alarm1) { sendData(2, 1, false); // Отправляем СМС о нормализации температуры } } if (sensors.hasAlarm(sensor_2)) { // у сенсора 1 сработал Alarm if(!alarm2) { sendData(1, 2, true); // Отправляем тревожное СМС } } else { if(alarm2) { sendData(2, 2, false); // Отправляем СМС о нормализации температуры } } } } void sendData(int rule, int name, boolean param) { tempS1 = sensors.getTempC(sensor_1); tempS2 = sensors.getTempC(sensor_2); if(rule == 0) { textMessage = «Temperature: «; } if(rule == 1) { textMessage = «Alarm! «; } if(rule == 2) { textMessage = «Now temperature is OK «; } textMessage += «Sensor1 = «; textMessage += dtostrf(tempS1, 2, 2, s); textMessage += » Sensor2 = «; textMessage += dtostrf(tempS2, 2, 2, s); char Out; textMessage.toCharArray(Out,(textMessage.length())+1); while(GSM.SendSMS(RemoteID, Out) < 0); if (name == 1) { alarm1 = param; } if (name == 2) { alarm2 = param; } }

Редактируем номер телефона (const char RemoteID), с которого можно будет производить дозвон и на который будут приходить СМС. При необходимости можно убрать проверку на номер и тогда на все входящие вызовы шилд будет отправлять смс со значениями датчиков.

Задание температурного диапазона для датчика «sensor_1» от +30 до -10 градусов цельсия, выглядит следующим образом:

sensors.setHighAlarmTemp(sensor_1, 30); sensors.setLowAlarmTemp(sensor_1, -10);

Аналогичным способом задаем диапазон срабатывания и для второго датчика. Уже в том случае, как будет зафиксировано значение вне заданного диапазона сработает Alarm.