Adatum
Авг
19
2014

Основной датчик контроля для системы умного дома Adatum+

Основной датчик Умного дома

Основной датчик Умного дома


Это основной модуль системы, позволяет управлять техникой по инфракрасному каналу, принимать и передавать радиосигналы на частоте 315 Мгц, измерять температуру, влажность,освещенность а также шум в помещении и определять движение.

type

izm
В соответствии с тем протоколам который был разработан для системы мы имеем 11 команд, рассмотрим их по подробнее.

— LED,R6775TR5,100,10,0,0,LED (только отправка)

Команда LED мигает сигнальным диодом на устройстве 1 группа — Длительность свечения, 2 группа — Количество мигание.

— QA,R6775TR5,0,0,0,0,QA (только отправка)

Команда запрашивает с устройства температуру, влажность, освещённость, уровень шума.
Соответственно:
Температура

— TEM,R6775TR5,25,0,0,0,TEM (только прием).

Влажность

— HUM,R6775TR5,50,0,0,0,HUM (только прием).

Освещённость

— LUM,R6775TR5,100,0,0,0,LUM (только прием).

Уровень шума

— BEEP,R6775TR5,102,0,0,0,BEEP (только прием).

— TST,R6775TR5,0,0,0,0,TST (прием-передача)

Команда отклика устройства TST,R6775TR5,0,0,0,iBN,TST это команда двунаправленная, она передаётся при включении устройства, а так же она придет в ответ на неё же для определения «живости» устройства.

— IR,R6775TR5,NEC,16825533,16825,0,IR (прием-передача)

Инфракрасный приемо — передатчик эта команда передается когда устройство фиксирует нажатие кнопки пульта. И соответственно эта команда отправленная устройству отправит инфракрасный сигнал бытовой технике.

— MU,R6775TR5,100,10,0,0,MU (только отправка)

Команда воспроизводит звуковой сигнал. 1 группа — Частота звука, 2 группа — длительность звучания.

— RF,R6775TR5,2683969,24,190,0,RF (прием-передача)

Радиочастотный приемо — передатчик эта команда передается когда устройство фиксирует радиосигнал 315 Мгц. И соответственно эта команда отправленная устройству отправит радиосигнал внешним устройствам. 1 группа — Уникальный идентификатор, 2 группа — битность сигнала , 3 группа — длительность сигнала.

— PIR,R6775TR5,1,0,0,0,PIR(только прием)

Датчик движения передается когда в поле зрения устройства фиксируется движение.

Текст скетча.

#include "DHT.h"                              // DHT
#include <IRremote.h>                         // Ir управление
#include <RCSwitch.h>                         // RF подключаем библиотеку
RCSwitch mySwitch = RCSwitch();               // RF  приёмник
DHT dht(6, DHT11);                            // DHT
const int analogPin = 2;
long interval = 10000;                        // интервал между включение/выключением светодиода (1 секунда)
long previousMillis = 0;                      // храним время последнего переключения светодиода
long previousMillis2 = 0;                     // храним время последнего переключения светодиода
long beepprevious = 0;  
unsigned long beepcurrent =0;
long beeptone;

int ledPin  = 13;
int pirPin = 11; 
int ledState = LOW;   
long ledpreviousMillis = 0;        // храним время последнего переключения светодиода
long ledinterval = 0;           // интервал между включение/выключением светодиода (1 секунда)
int ledcol=0;

IRrecv irrecv(8);                             // pin инфракрасный приёмник
decode_results results;
unsigned long ir_dt, old_ir; 
unsigned long rf_dt, old_rf; 
int speakerOut = 4;
long previousMillis3 = 0;                     // храним время последнего переключения светодиода

long dalaypir = 0;                     // Задержка датчика движения


char mode[4];                                 // Переменные для разбора буфера
char addr[10];                                // Переменные для разбора буфера
char vale1[14];                               // Переменные для разбора буфера
char vale2[14];                               // Переменные для разбора буфера
char vale3[14];                               // Переменные для разбора буфера
char vale4[4];                                // Переменные для разбора буфера
char modecontrol[4];                          // Переменные для разбора буфера
IRsend irsend;                                // Ir управление
int sensorPin = A0;                           // устанавливаем входную ногу для АЦП
unsigned int sensorValue = 0;                 // цифровое значение фоторезистора
char serianname[] = "T6DNAE0S" ;              // серийный номер устройства в сети
char datepr[] = "20140729" ;              
char ver[] = "ver0024" ;         
char buffer[100];
int d = 0;
int lum;//глобальная переменная силы света
long beep=0;  

int lumsend;//глобальная переменная силы света
#define SerialTxControl 10   //RS485 Direction control
#define RS485Transmit    HIGH
#define RS485Receive     LOW  



 
void playTone(int note)  {     digitalWrite(speakerOut,HIGH);     delayMicroseconds(note / 2);     digitalWrite(speakerOut, LOW);     delayMicroseconds(note / 2);} 
  
void setup() 
{      
   pinMode(SerialTxControl, OUTPUT);    
  Serial.begin(9600); 
  pinMode(speakerOut, OUTPUT);
 pinMode(ledPin, OUTPUT);  
 pinMode (pirPin, INPUT);
 
  digitalWrite(SerialTxControl, RS485Transmit); 
   Serial.print("TST,");   Serial.print(serianname);Serial.print(",");Serial.print(datepr);Serial.print(",");Serial.print(ver); Serial.println(",0,STAT,TST");
  delay(100); 
  digitalWrite(SerialTxControl, RS485Receive);                    
 
 
    pinMode(4, OUTPUT);                       // Musik
    mySwitch.enableReceive(0);                // Приемник RF 0 => это pin #2 
    dht.begin();                              // DHT
    irrecv.enableIRIn();                      // Start the receiver
    mySwitch.enableTransmit(7);               // Передатчик RF is connected
    mySwitch.setRepeatTransmit(5);            // Передатчик RF setRepeatTransmit


}


void loop() 
{


int pirVal = digitalRead (pirPin);
dalaypir=dalaypir-1;
if (pirVal == HIGH && dalaypir <0){
 digitalWrite(SerialTxControl, RS485Transmit); 
   Serial.print("PIR,");   Serial.print(serianname);Serial.print(","); Serial.println("1,0,0,0,PIR");
  delay(100); 
  digitalWrite(SerialTxControl, RS485Receive);  
  dalaypir=5000;
//delay (2000);
}
  
 
  int val = analogRead(analogPin);
  if(val>130){
  digitalWrite(SerialTxControl, RS485Transmit); 
  Serial.print("BEEP,");   Serial.print(serianname); Serial.print(",");     Serial.print(val);    Serial.println(",0,0,0,BEEP");
  delay(100); 
  digitalWrite(SerialTxControl, RS485Receive);  }
    
//Функция мигания диодом
 unsigned long ledcurrentMillis = millis();
 if(ledcurrentMillis - ledpreviousMillis > ledinterval && ledcol > 0) {
    ledpreviousMillis = ledcurrentMillis; 
    if (ledState == LOW)      ledState = HIGH;
    else{      ledState = LOW;       ledcol=ledcol-1;}
  digitalWrite(ledPin, ledState);
  }
//Функция мигания диодом
  
  
  
 unsigned long beepcurrent = millis(); 
 if(beepcurrent < beepprevious) 
      {          playTone (beeptone);        }

  
   
  //    digitalWrite(SerialTxControl, RS485Transmit);  
    digitalWrite(SerialTxControl, RS485Receive);  
    
    
   
  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, "%[^','],%[^','],%[^','],%[^','],%[^','],%[^','],%s", &mode, &addr, &vale1, &vale2, &vale3, &vale4, &modecontrol);          
  

  
     if ((String)addr == serianname) {
     if ((String)mode == (String)modecontrol) {
       
       
     if ((String)mode == "TST")   
      {
  digitalWrite(SerialTxControl, RS485Transmit); 
   Serial.print("TST,");   Serial.print(serianname);Serial.print(",");Serial.print(datepr);Serial.print(",");Serial.print(ver); Serial.println(",0,STAT,TST");
  delay(100); 
  digitalWrite(SerialTxControl, RS485Receive);   
      
     }
     
     
          if ((String)mode == "LED")   //LED,T6DNAE0S,500,5,0,0,LED

      {
ledinterval = atoi(vale1);          
ledcol=atoi(vale2);
  digitalWrite(SerialTxControl, RS485Transmit); 
  Serial.print("SEND,");   Serial.print(serianname); Serial.println(",0,0,0,LED,SEND");
  delay(100); 
  digitalWrite(SerialTxControl, RS485Receive);   
     }
     
     
     
     
          if ((String)mode == "QA")   
      {

        
              int l = analogRead(sensorPin);
      int h = dht.readHumidity(); 
      int t = dht.readTemperature(); 
      
      
  digitalWrite(SerialTxControl, RS485Transmit); 
  Serial.print("LUM,");   Serial.print(serianname);Serial.print(","); Serial.print(l); Serial.println(",0,0,0,LUM");
  delay(100); 
  Serial.print("HUM,");   Serial.print(serianname);Serial.print(","); Serial.print(h); Serial.println(",0,0,0,HUM");
  delay(100); 
  Serial.print("TEM,");   Serial.print(serianname);Serial.print(","); Serial.print(t); Serial.println(",0,0,0,TEM");
  delay(100); 
   Serial.print("BEEP,");   Serial.print(serianname);Serial.print(","); Serial.print(val); Serial.println(",0,0,0,BEEP");
  delay(100); 
   Serial.print("SEND,");  Serial.print(serianname);   Serial.println("0,0,0,0,QA,SEND");       
   delay(100); 
  digitalWrite(SerialTxControl, RS485Receive); 
      
     }

   
    if ((String)mode == "RF")   
      {
      mySwitch.setPulseLength(atol(vale3)-64); 
      mySwitch.send(atol(vale1), atol(vale2));    
      mySwitch.resetAvailable();  
    
       digitalWrite(SerialTxControl, RS485Transmit); 
       
      Serial.print("SEND,");  Serial.print(serianname);   Serial.print(",");    Serial.print(vale1);   Serial.print(","); Serial.print(vale2);   Serial.print(",");Serial.print(vale3);   Serial.println(",RF,SEND");        //RF,T6DNAE0SKO,11229962,24,293,0,RF, 
     
       delay(100); 
      digitalWrite(SerialTxControl, RS485Receive); 
      
     }

    if ((String)mode == "IR")
      {

 // irsend.sendPanasonic(4004,100BCBD); // This should turn your TV on and off
//  irsend.sendPanasonic(16388,16825533); // This should turn your TV on and off
       if ((String)vale1 == "NEC") {     int long bits2 = atol(vale2); int long value2 = atol(vale3); irsend.sendNEC(bits2, value2);     } 
       if ((String)vale1 == "SONY"){     int long bits4 = atol(vale2); int long value4 = atol(vale3); irsend.sendSony(bits4, value4);    }      
       if ((String)vale1 == "RC5") {     int long bits5 = atol(vale2); int long value5 = atol(vale3); irsend.sendRC5(bits5, value5);     }     
       if ((String)vale1 == "RC6") {     int long bits6 = atol(vale2); int long value6 = atol(vale3); irsend.sendRC6(bits6, value6);     }  
       if ((String)vale1 == "JVC") {     int long bits7 = atol(vale2); int long value7 = atol(vale3); irsend.sendJVC(bits7, value7, 0);  }     
       if ((String)vale1 == "PAN") {     int long bits3 = atol(vale2); int long value3 = atol(vale3); irsend.sendPanasonic(value3,bits3);}   
  //     irrecv.enableIRIn();
        digitalWrite(SerialTxControl, RS485Transmit); 
       Serial.print("SEND,"); Serial.print(serianname);   Serial.print(","); Serial.print(vale1);   Serial.print(","); Serial.print(vale2);   Serial.print(",");Serial.print(vale3);   Serial.println(",IR,SEND");  
              delay(100); 
      digitalWrite(SerialTxControl, RS485Receive); 
     }
      irrecv.enableIRIn();
      
    if ((String)mode == "MU")    
    {  
         digitalWrite(SerialTxControl, RS485Transmit); 
      Serial.print("SEND,"); Serial.print(serianname);   Serial.print(",");  Serial.print(vale1);   Serial.print(","); Serial.print(vale2);   Serial.print(",");Serial.print(vale3);   Serial.println(",MU,SEND");         // MU,T6DNAE0S,1500,1000,0,0,MU  
             delay(100); 
      digitalWrite(SerialTxControl, RS485Receive); 
      beeptone=atoi(vale1);
      beepprevious = millis()+atoi(vale2); 
    } 
   
 }
 } 
 }
  
  
  if (irrecv.decode(&results)) {
  if (results.value > 0 && results.value < 0xFFFFFFFF)     {  
    
  int count = results.rawlen;
  
        if (results.decode_type == NEC)      
                { 
                char text2[100]; sprintf(text2, "IR,%s,NEC,%ld,%d,0,IR",  serianname, results.value, results.bits);                
                digitalWrite(SerialTxControl, RS485Transmit); 
                Serial.println(text2); 
                delay(100); 
                digitalWrite(SerialTxControl, RS485Receive);  
                }
                
   else if (results.decode_type == SONY)     
             { char text4[100]; sprintf(text4, "IR,%s,SONY,%ld,%d,0,IR", serianname, results.value, results.bits);             
             digitalWrite(SerialTxControl, RS485Transmit); 
                Serial.println(text4); 
                delay(100); 
                digitalWrite(SerialTxControl, RS485Receive);     } 
                
   else if (results.decode_type == RC5)      { char text5[100]; sprintf(text5, "IR,%s,RC5,%ld,%d,0,IR",  serianname, results.value, results.bits);            
   digitalWrite(SerialTxControl, RS485Transmit); 
      Serial.println(text5); 
      delay(100); 
      digitalWrite(SerialTxControl, RS485Receive);     } 
      
      
   else if (results.decode_type == RC6)      { char text6[100]; sprintf(text6, "IR,%s,RC6,%ld,%d,0,IR",  serianname, results.value, results.bits);      
   digitalWrite(SerialTxControl, RS485Transmit); 
      Serial.println(text6); 
      delay(100); 
      digitalWrite(SerialTxControl, RS485Receive);  
 }
   else if (results.decode_type == JVC)      { char text7[100]; sprintf(text7, "IR,%s,JVC,%ld,%d,0,IR",  serianname, results.value, results.bits);  
   digitalWrite(SerialTxControl, RS485Transmit); 
      Serial.println(text7); 
      delay(100); 
      digitalWrite(SerialTxControl, RS485Receive);  
 
 
   }
   else if (results.decode_type == PANASONIC){ char text3[100]; sprintf(text3, "IR,%s,PAN,%ld,%d,0,IR",  serianname, results.value, results.panasonicAddress);  
   digitalWrite(SerialTxControl, RS485Transmit); 
      Serial.println(text3); 
      delay(100); 
      digitalWrite(SerialTxControl, RS485Receive);  
  
   }  

 }
    irrecv.enableIRIn();
}


if (mySwitch.available()>0 ) 
{  rf_dt = mySwitch.getReceivedValue();  unsigned long currentMillis2 = millis();                                                                                                                                     // Приемник RF
   if ((old_rf != rf_dt) || (currentMillis2 - previousMillis2 > 300)) 
     { previousMillis2 = currentMillis2; old_rf=rf_dt; 
     
     
  //   digitalWrite(SerialTxControl, RS485Transmit); delay(100);
  //     Serial.print("RF,"); Serial.print(serianname); Serial.print(","); Serial.print( mySwitch.getReceivedValue() ); Serial.print(","); Serial.print( mySwitch.getReceivedBitlength() ); Serial.print(",");  Serial.print( mySwitch.getReceivedDelay() ); Serial.println(",0,RF");   
  //    digitalWrite(SerialTxControl, RS485Receive);  
     
       digitalWrite(SerialTxControl, RS485Transmit); 
  Serial.print("RF,");   Serial.print(serianname);Serial.print(","); Serial.print(mySwitch.getReceivedValue());Serial.print(",");Serial.print(mySwitch.getReceivedBitlength());Serial.print(",");Serial.print( mySwitch.getReceivedDelay() ); Serial.println(",0,RF");
  delay(100); 
  digitalWrite(SerialTxControl, RS485Receive); 
     
            mySwitch.resetAvailable();
     } 
   mySwitch.resetAvailable(); 
}


    
    if(lum > 0){
    int l = analogRead(sensorPin);
    if (abs((lum-l)/10)>10){   lum = analogRead(sensorPin); lumsend=lum; }
    }
    else
    {
      lum = analogRead(sensorPin);
    }
    
    if(lumsend > 0){
  digitalWrite(SerialTxControl, RS485Transmit); 
  Serial.print("LUM,");   Serial.print(serianname);Serial.print(","); Serial.print(lumsend); Serial.println(",0,0,0,LUM");
  delay(100); 
  digitalWrite(SerialTxControl, RS485Receive);   
    lumsend=0;
    }
}

Фото устройства.

Основной датчик

Основной датчик

Скачать скетч

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

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

  • Димитрий, а где коробочку покупали? Отдельно заказывали или начинку из полноценного датчика доставали?

  • С интересом слежу за вашим проектом. Кое-что реализую у себя. Очень интересно как у вас в системе реализовано питание всех устройств?

    • Добрый день, у меня все устройства подключены по витой паре в которой и шина данных и питание идёт, и все у одному блоку питания. К сожалению пока нет времени выкладывать обновления системы. Но после нового года обязательно выложу кое какие изменения и исправления ошибок.

      • Вечер добрый! А что за блок питания, если не секрет? И сколько устройств и на каком расстоянии?

  • Это конечно здорово но не проще тогда каждому прибору задать задержку индивидуально, по порядку, например 1 — 2 мс 2 — 4мс и так далее не кто не с кем не пересечётся а если и пересечётся то шанс этого будет минимален ?

    • Для того что бы использовать задержку, нужно все приборы периодически синхронизировать. Если частота кварцев в приборах плавает, очень быстро все приборы рассинхронизируются и начнут их задержки накладываться и в итоге передача будет одновременной. Можно конечно сделать так что бы мастер периодически передавал команду синхронизации, но тогда при «умирании» мастера вся сеть быстро упадет.

  • Как я понимаю вопрос коллизий в линии RS485 не решен никак? В итоге если два устройства одновременно решат что то передать в линию никто ничего вразумительного не получит. Представьте ситуацию когда у вас не одна комната и в каждой установлен вот такой «основной датчик». При нажатии кнопки на радио-пульте есть оооочень большая вероятность что радио команду примут сразу несколько «основных датчиков». Они как порядочные принятую команду начнут слать центральному серверу и естественно все одновременно :) Думаю пора начинать усовершенствовать протокол как то на предмет проверки свободности линии.

    • Да вы совершенно правы. Коллизии вполне реальны. Руки скоро и до этого дойдут.

      • Сам давно ломаю голову как бы осуществить контроль «линия свободна», но ничего толкового без еще одного провода не получается. Либо можно сделать устройства пассивными, что бы по собственной инициативе ничего не слали, и постоянно опрашивать их с центрального устройства.

      • Придумал такой вариант:
        1. Каждый прибор имеет цифровой идентификационный номер. Этот номер идет по возрастающей для каждого нового прибора. В каждой посылке в линию обязательно передается номер прибора осуществляющего передачу.
        2. Каждый прибор постоянно «слушает» линию и запоминает номер последнего прибора передавшего что то в линию.
        3. При необходимости что то передать в линию прибор получает разницу собственного номера и номера последнего вещавшего прибора и устанавливает задержку равную разнице идентификационных номеров. Если в течении задержки никакой другой прибор не начал вещать, прибор занимает линию и начинает передачу.
        4. По окончании передачи прибор передает команду «END» и осфобождает линию.

        Если например только что в линии вещал прибор с номером 2, все приборы получат его номер и установят задержку равную разнице номеров. Таким образом прибор с номером 3 установит задержку например в 100 мс, а прибор с номером 5 — 300 мс. Это означает что прибор с номером 5 никогда не начнет вещать раньше прибора 3. Если прибору 3 ничего не нужно передавать в линию он просто молчит и по истечении 300 мс прибор 5 передаст свою информацию в линию. Если в сети есть прибор с номером 4 то он начнет свою передачу через 200 мс после прибора 2 и услышав эту передачу прибор с номером 5 отменит свою задержку после прибора 2 в 300 мс и установит задержку в 100 мс. Таким образом через 100 мс после передачи прибора 4 начнет передачу прибор 5. В итоге все приборы выстроятся в очередь по возрастающей их номеров, и никто никогда не нарушит эту очередь.
        Понятно что длительность задержки я указал только для примера. Еще понятно что чем больше приборов тем реже будет передача одного и того же прибора. И еще считаю недостатком то что если в сети например 2 прибора с номерами 2 и 22, пауза между их передачей будет большой и линия будет использоваться неэфективно.
        Это пока только идея имеющая массу недостатков. Ее конечно же нужно доработать.

  • С помощью библиотеки RCSwitch.h, в принципе можете подключить Arduino на прямую к web части и без RS-485, просто закоментируйте в скетче следующие строки:

    //digitalWrite(SerialTxControl, RS485Transmit);
    //digitalWrite(SerialTxControl, RS485Receive);

    И подключить к ардуине только радио модули по схеме выше и посмотреть в ком порте что будет выдавать при нажатии на радио пульты. Если нужно что то конкретнее пиши.

  • Дмитрий, добрый день! Расскажите, как вы декодировали сигналы радио пультов? Есть две радио розетки, решил потренироваться на вашей системе.