Adatum
Фев
22
2013

Делаем систему «Умный дом» на Arduino часть 1.

smart home
Добрый день сегодня хочу начать серию статей про умный дом на Ардуино. Конечно его нельзя назвать в полном смысле умным домом скорее системой мониторинга.
Сегодня выложу исходные коды и схемы модулей, смотрим под катом.

Основной идеей послужило идея обеднения и общий контроль устройств на радио сигнале 315 и 433 Мгц. К счастью на сегодняшний день таких устройств превеликое множество. Это и различные пульты, датчики движения и дыма. Контроллеры жалюзи, протечек воды. Я постараюсь показать как сделать систему автоматизации за очень небольшие деньги. Ведь тот де датчик китайский движения стоит около 300 руб.

 

1.Главный модуль

  • Обрабатывает сигналы с радио пультов .
  • Обрабатывает сигналы с  измерительного модуля.
  • Передает полученные команды на компьютер.

mainmodule

#include <RCSwitch.h>                          // RF подключаем библиатеку
#include <RemoteReceiver.h>
#include <RemoteTransmitter.h>
#include <VirtualWire.h>
RCSwitch mySwitch = RCSwitch();                // RF  приёмник
long previousMillis2 = 0;                      // храним время последнего переключения светодиода
long previousMillis3 = 0;                      // храним время последнего переключения светодиода
char unitID_in[11];                            // Переменные для разбора буфера
char numb_in[14];                              // Переменные для разбора буфера
char dat_in[14];                               // Переменные для разбора буфера
char ol_in[14];                                // Переменные для разбора буфера
unsigned long rf_dt, old_rf; 
const int ledPin =  6;                          // номер выхода, подключенного к светодиоду
int ledState = LOW;                             // этой переменной устанавливаем состояние светодиода
long previousMillis = 0;                        // храним время последнего переключения светодиода
long interval = 500;                           // интервал между включение/выключением светодиода (1 секунда)
char buffer[32];
unsigned long rf2_dt, old_rf2; 

void setup() 
{
   RemoteReceiver::init(1, 3, showCode);
   Serial.begin(9600);                          // Скорость компорта
   mySwitch.enableReceive(0);                   // Приемник RF 0 => это pin #2 
   pinMode(ledPin, OUTPUT);                     // задаем режим выхода для порта, подключенного к светодиоду
   
   vw_set_tx_pin(7);	                        // VirtualWire
   vw_set_rx_pin(2);	                        // VirtualWire
   vw_set_ptt_inverted(true);                   // VirtualWire
   vw_setup(4000);	                        // VirtualWire
   vw_rx_start(); 	                        // VirtualWire
   
   mySwitch.enableTransmit(7);                  // Передатчик RF is connected to Arduino Pin #10  
   mySwitch.setRepeatTransmit(5);               // Передатчик RF setRepeatTransmit
 

    
 
Serial.println("                                                        ");
Serial.println("                WELCOME to ADATUM                       ");
Serial.println("              MAIN MODULE  v.0.9                        ");
Serial.println("                                                        ");

 

}

void loop() {
  
 uint8_t buf[VW_MAX_MESSAGE_LEN];  uint8_t buflen = VW_MAX_MESSAGE_LEN;   if(vw_get_message(buf, &buflen)){      int i; for(i = 0;  i < buflen; ++i){  buffer[i] = char(buf[i]);}buffer[i++]='\0';              Serial.println(buffer); } 
 

    
int i=0; 
if(Serial.available()){delay(100);
while( Serial.available() && i< 99) { buffer[i++] = Serial.read();} buffer[i++]='\0';}                                       
if(i>0)
{
    sscanf(buffer, "%[^','],%[^','],%[^','],%[^',']", &unitID_in, &numb_in, &dat_in, &ol_in);     
    
    if ((String)unitID_in == "rn") { vw_setup(0); unsigned long n2; unsigned long m2; n2 = atol(numb_in); m2 = atol(dat_in); RemoteTransmitter::sendCode(7, n2, m2, 5);vw_setup(4000);}  //отправляем команду типа rn,177075,126
    if ((String)unitID_in == "rf") { vw_setup(0);  unsigned long n;  unsigned long  m; unsigned long  g; n = atol(numb_in);  m = atol(dat_in); g = atol(ol_in); mySwitch.setPulseLength(g); mySwitch.send(n, m); vw_setup(4000);}
    if ((String)unitID_in == "ir") { char sl[32]; sprintf(sl, "ir,%s,%s,%s",  numb_in, dat_in, ol_in); vw_send((uint8_t *)sl, strlen(sl)); }      //ir,PAN,16825533,16388
    if ((String)unitID_in == "id") { char sl[32]; sprintf(sl, "id,send"); vw_send((uint8_t *)sl, strlen(sl)); }
    if ((String)unitID_in == "mu") { char sl[32]; sprintf(sl, "mu,%d", numb_in); vw_send((uint8_t *)sl, strlen(sl)); }
    if ((String)unitID_in == "re") { char qw[32]; sprintf(qw, "re,%s,%s", numb_in, dat_in); Serial.print(qw); vw_send((uint8_t *)qw, strlen(qw)); }
    
}


                                                 
if (mySwitch.available()>0 ) 
{  rf_dt = mySwitch.getReceivedValue();  unsigned long currentMillis2 = millis();                                                                                                                                      // Приемник RF
   if ((old_rf != rf_dt) || (currentMillis2 - previousMillis2 > 1000)) 
   {
   previousMillis2 = currentMillis2; old_rf=rf_dt; Serial.print("rf,");    Serial.print( mySwitch.getReceivedValue() );  
   Serial.print(",");  Serial.print( mySwitch.getReceivedBitlength() ); Serial.print(",");  Serial.print( mySwitch.getReceivedDelay() );Serial.print(",");Serial.print("0");Serial.print(",");Serial.println("rf");
 
   mySwitch.resetAvailable();
  } 
  mySwitch.resetAvailable(); 
}
  
    
      
unsigned long currentMillis = millis();  if(currentMillis - previousMillis > interval) { previousMillis = currentMillis;  if (ledState == LOW) ledState = HIGH; else  ledState = LOW; digitalWrite(ledPin, ledState);  }
            
}


void showCode(unsigned long receivedCode, unsigned int period) { rf2_dt = receivedCode; unsigned long currentMillis3 = millis(); if ((old_rf2 != rf2_dt) || (currentMillis3 - previousMillis3 > 500)) {previousMillis3 = currentMillis3; old_rf2=rf2_dt; Serial.print("rn,"); Serial.print(receivedCode); Serial.print(",");Serial.print(period);Serial.print(",");Serial.print("0");Serial.print(",");Serial.print("0");Serial.print(",");Serial.println("rn");}    }    // Приемник  PT2262  





mainmodule2

2. Измерительный модуль.

  • Обрабатывает сигналы с радио пультов .
  • Обрабатывает сигналы с инфракрасных пультов .
  • Проигрывает сигнал тревоги и другие сигналы через динамик.
  • Измеряет уровень освещения.
  • Измеряет влажность и температуру.
  • Отправляет все данные главному модулю.

module
module2

#include <VirtualWire.h>
#include "DHT.h"                              // DHT
#include <IRremote.h>                         // Ir управление
#include <RCSwitch.h>                         // RF подключаем библиатеку
RCSwitch mySwitch = RCSwitch();               // RF  приёмник
DHT dht(6, DHT11);                            // DHT
long interval = 60000;                        // интервал между включение/выключением светодиода (1 секунда)
long previousMillis = 0;                      // храним время последнего переключения светодиода
long previousMillis2 = 0;                     // храним время последнего переключения светодиода
IRrecv irrecv(8);                             // Ir управление
decode_results results;
unsigned long ir_dt, old_ir; 
unsigned long rf_dt, old_rf; 
const int ledPin =  13;                          // номер выхода, подключенного к светодиоду
int ledState = LOW;                             // этой переменной устанавливаем состояние светодиода

long previousMillis3 = 0;                     // храним время последнего переключения светодиода
char unitID_in[11];                           // Переменные для разбора буфера
char numb_in[14];                             // Переменные для разбора буфера
char dat_in[14];                              // Переменные для разбора буфера
char ol_in[14];                               // Переменные для разбора буфера
IRsend irsend;                                // Ir управление
int sensorPin = A0;                           // устанавливаем входную ногу для АЦП
int sensorPin2 = A6;                           // устанавливаем входную ногу для АЦП
unsigned int sensorValue = 0;                 // цифровое значение фоторезистора
int speakerPin = 4;                           // Musik
char buffer[32];

void setup() 
{
        
    Serial.begin(9600);                       // Musik
    pinMode(ledPin, OUTPUT);                     // задаем режим выхода для порта, подключенного к светодиоду
    pinMode(speakerPin, OUTPUT);              // Musik
    mySwitch.enableReceive(0);                // Приемник RF 0 => это pin #2 
    dht.begin();                              // DHT
    irrecv.enableIRIn();                      // Start the receiver
    mySwitch.enableTransmit(7);               // Передатчик RF is connected to Arduino Pin #10  
    mySwitch.setRepeatTransmit(5);            // Передатчик RF setRepeatTransmit
    
    vw_set_tx_pin(7);	                        // VirtualWire
    vw_set_rx_pin(2);	                        // VirtualWire
    vw_set_ptt_inverted(true);                   // VirtualWire
    vw_setup(4000);	                        // VirtualWire
    vw_rx_start(); 	                        // VirtualWire


Serial.println("                                                          ");
Serial.println("                WELCOME to ADATUM                         ");
Serial.println("              RECIVER MODULE  v.0.9                       ");
Serial.println("                                                          ");

}

void loop() 
{
   
   uint8_t buf[VW_MAX_MESSAGE_LEN];  uint8_t buflen = VW_MAX_MESSAGE_LEN;                                                                                                    // VirtualWire 

   if(vw_get_message(buf, &buflen)){int i; for(i = 0;  i < buflen; ++i){  buffer[i] = char(buf[i]);}buffer[i++]='\0';
              
                   sscanf(buffer, "%[^','],%[^','],%[^','],%[^',']", &unitID_in, &numb_in, &dat_in, &ol_in);          
 
    if ((String)unitID_in == "id") {

          int s = analogRead(sensorPin2); int k = analogRead(sensorPin);  int h = dht.readHumidity();  int t = dht.readTemperature();  
      char meteo[32];   sprintf(meteo, "id,0001,%d,%d,%d,%d,id", t,h,k,s); 
      Serial.print("send: "); Serial.println(meteo); vw_send((uint8_t *)meteo, strlen(meteo));
                                    } 
    if ((String)unitID_in == "mu") {int length = 5; int tempo = 10; char notes[] = "cgcgc";  int beats[] = {1,1,1,1,1};  for (int i = 0; i < length; i++) {if (notes[i] == ' ') {delay(beats[i] * tempo);} else {playNote(notes[i], beats[i] * tempo);}delay(tempo/2);}Serial.println("MUSIC");} 
    if ((String)unitID_in == "ir")
      {
           Serial.print("recive: ");  Serial.print(buffer);

	

    
       if ((String)numb_in == "nec") {    vw_setup(0); int long bits2 = atol(dat_in); int long value2 = atol(ol_in); irsend.sendNEC(bits2, value2);      Serial.print("send: ");  Serial.print("nec,"); Serial.println(bits2); vw_setup(4000);	} 
       if ((String)numb_in == "sony"){    vw_setup(0); int long bits4 = atol(dat_in); int long value4 = atol(ol_in); irsend.sendSony(bits4, value4);     Serial.print("send: ");  Serial.print("sony,");Serial.println(bits4); vw_setup(4000);	}      
       if ((String)numb_in == "rc5") {    vw_setup(0); int long bits5 = atol(dat_in); int long value5 = atol(ol_in); irsend.sendRC5(bits5, value5);      Serial.print("send: ");  Serial.print("rc5,"); Serial.println(bits5); vw_setup(4000);	}     
       if ((String)numb_in == "rc6") {    vw_setup(0); int long bits6 = atol(dat_in); int long value6 = atol(ol_in); irsend.sendRC6(bits6, value6);      Serial.print("send: ");  Serial.print("rc6,"); Serial.println(bits6); vw_setup(4000);	}  
       if ((String)numb_in == "jvc") {    vw_setup(0); int long bits7 = atol(dat_in); int long value7 = atol(ol_in); irsend.sendJVC(bits7, value7, 0);   Serial.print("send: ");  Serial.print("jvc,"); Serial.println(bits7); vw_setup(4000);	}     
       if ((String)numb_in == "pan") {    vw_setup(0); int long bits3 = atol(dat_in); int long value3 = atol(ol_in); irsend.sendPanasonic(value3,bits3); Serial.print("send: ");  Serial.print("pan,"); Serial.println(bits3); vw_setup(4000);	}   
       }
 


    irrecv.enableIRIn();
 }
  
  
  
  
  if (irrecv.decode(&results)) {
  if (results.value > 0 && results.value < 0xFFFFFFFF)     {  
  int count = results.rawlen;
         if (results.decode_type == NEC)     { char text2[32]; sprintf(text2, "ir,nec,%ld,%d,0,ir",  results.value, results.bits);               Serial.print("reciv:");Serial.println(text2); vw_send((uint8_t *)text2, strlen(text2)); }
   else if (results.decode_type == SONY)     { char text4[32]; sprintf(text4, "ir,sony,%ld,%d,0,ir", results.value, results.bits);               Serial.print("reciv");Serial.println(text4); vw_send((uint8_t *)text4, strlen(text4)); } 
   else if (results.decode_type == RC5)      { char text5[32]; sprintf(text5, "ir,rc5,%ld,%d,0,ir",  results.value, results.bits);               Serial.print("reciv");Serial.println(text5); vw_send((uint8_t *)text5, strlen(text5)); } 
   else if (results.decode_type == RC6)      { char text6[32]; sprintf(text6, "ir,rc6,%ld,%d,0,ir",  results.value, results.bits);               Serial.print("reciv");Serial.println(text6); vw_send((uint8_t *)text6, strlen(text6)); }
   else if (results.decode_type == JVC)      { char text7[32]; sprintf(text7, "ir,jvc,%ld,%d,0,ir",  results.value, results.bits);               Serial.print("reciv");Serial.println(text7); vw_send((uint8_t *)text7, strlen(text7)); }
   else if (results.decode_type == PANASONIC){ char text3[32]; sprintf(text3, "ir,pan,%ld,%d,0,ir",  results.value, results.panasonicAddress);   Serial.print("reciv");Serial.println(text3); vw_send((uint8_t *)text3, strlen(text3)); } 

 }
    irrecv.enableIRIn();
}


if (mySwitch.available()>0 ) 
{  rf_dt = mySwitch.getReceivedValue();  unsigned long currentMillis2 = millis();                                                                                                                                     // Приемник RF
   if ((old_rf != rf_dt) || (currentMillis2 - previousMillis2 > 1000)) { previousMillis2 = currentMillis2; old_rf=rf_dt; 
   Serial.print("reciv: "); Serial.print("rf,");    
   Serial.print( mySwitch.getReceivedValue() );     Serial.print(",");  Serial.print( mySwitch.getReceivedBitlength() );  Serial.print(",");  Serial.print( mySwitch.getReceivedDelay() );  
   int long n = mySwitch.getReceivedValue();  int m = mySwitch.getReceivedBitlength(); int g = mySwitch.getReceivedDelay(); 
   vw_setup(0);	                        // VirtualWire
   mySwitch.setPulseLength(g-58); mySwitch.send(n, m);
  vw_setup(4000);	                        // VirtualWire
   char sl[32]; sprintf(sl, "%ld,%d,%d",  n, m, g);Serial.print(" -> send: ");Serial.println(sl);
   mySwitch.resetAvailable();} mySwitch.resetAvailable(); 
}

    

unsigned long currentMillis = millis();  if(currentMillis - previousMillis > interval) {
  
   previousMillis = currentMillis;
  
     int s = analogRead(sensorPin2); int k = analogRead(sensorPin);  int h = dht.readHumidity();  int t = dht.readTemperature();  
      char meteo[32];   sprintf(meteo, "id,0001,%d,%d,%d,%d,id", t,h,k,s); 
      Serial.print("send: "); Serial.println(meteo); vw_send((uint8_t *)meteo, strlen(meteo));
 
 
   if (ledState == LOW) ledState = HIGH; else  ledState = LOW; digitalWrite(ledPin, ledState);  }

}

void playTone(int tone, int duration){for (long i = 0; i < duration * 1000L; i += tone * 2) {digitalWrite(speakerPin, HIGH); delayMicroseconds(tone); digitalWrite(speakerPin, LOW); delayMicroseconds(tone); }}
void playNote(char note, int duration){char names[]={'c','d','e','f','g','a','b','C'}; int tones[]={1915,1700,1519,1432,1275,1136,1014,956}; for (int i=0; i<8; i++) {if (names[i] == note){playTone(tones[i], duration);}}}

По коду думаю у вас не возникнет вопросов, основные моменты прокомментированы. Все таки если возникают вопросы пишем не стесняемся, буду рад ответить.
В проекте использованы библиотеки.

  • IRremote * Version 0.1 July, 2009 * Copyright 2009 Ken Shirriff.
  • Virtual Wire implementation for Arduino Author: Mike McCauley (mikem@open.com.au) Copyright (C) 2008 Mike McCauley.
  • DHT library written by Adafruit Industries.
  • RCSwitch Suat Цzgьr. Contributors: — Andre Koehler / info(at)tomate-online(dot)de — Gordeev Andrey Vladimirovich.
  • RemoteSwitch library v2.3.0 DEV made by Randy Simons.

Похожие статьи

Оставить комментарий

  • Я что-то не понял. Передатчик тоже подключается к Arduino? Тогда в чём смысл радиоканала? Мне нужно передатчик метров на 50 отнести от приемника.

  • Слушай дружище, работа конечно хорошая но вот код не компилится в 1.5 кучу ошибок даёт…

    • Где именно и какие ошибки? лог в студию !

  • В случае, если использую плату ардуино мега 2560, какие пины нужно использовать вместо использованных на картинке? D3 D2 D6 D7 в какие пины на ардуино втыкать в мега 2560

  • ну если много комнат, какая на компе программа используется для отображения информации?
    я хотел дисплей 4-х строчный применить, ну или что то подобное, чтоб от компа избавится

  • Привет. Я на форме Амперки ответил, но и тут продублирую.
    Желательно вводить спящий режим, в момент передачи информации отключать модуль своего приемника, не забыть дисплей подключить .
    Как будет огранизована передача данных с нескольких датчиков температуры?
    http://forumdvrobot.ru/forum/3-63-1

    • Видишь ли я не собираюсь переводить в спящий режим т.к у меня едет постоянный сбор данных с датчиков, у меня датчик работают каждый по себе в отдельных комнатах и от сети, на каждый датчик одна ардуинка + различные датчика в том числе управление по ir каналу, скоро опубликую вторую статью думаю там будет понятней.