Не корректно работает прошивка. (сигнализация)

pixel28
Offline
Зарегистрирован: 23.11.2015
При запуске дает код 9x98 что все нормально .если прислонить ключ, выводит квадратик, и все.......
 
 
 
#include <OneWire.h>
#include "pitches.h"
 
const byte iButtonPin = 3; //пин для ibutton
const byte waterPin = 4; // пин датчика воды
const byte pirPin = 5; // пин для СЕНСОРА ДВИЖЕНИЯ
const byte yelowLed = 6; // лампочка индикатор движения
const byte tonePin = 4; // пин для пищалки
const byte gerkonPin = 2; //gerkon
const byte greenLed = 9; //зеленая лампочка
const byte redLed = 12;  //красная лампочка
const byte calibrationTime = 3; // Время калибровки датчика (10-60 сек. по даташиту)
 
const byte alarmTime = 10; // время, чтобы поднести ключ при разблокировке(ЧИСЛО МИГАНИЙ)
const byte startTime = 5; // время на закрытие двери при постановке на сигнализацию(ЧИСЛО МИГАНИЙ)
 
OneWire  ds(iButtonPin); //ibutton
byte code1[8] = {};  //первый ключ
byte code2[8] = {0x01, 0x55, 0xDF, 0x8B, 0x0C, 0x00, 0x00, 0x3F};  // второй ключ
byte code3[8] = {0x01, 0x30, 0xAA, 0x0E, 0x00, 0x00, 0x00, 0x4B};  //ЧЕТВЕРТЫй ключ
byte code4[8] = {0x01, 0xC4, 0x72, 0x22, 0x0B, 0x00, 0x00, 0x26};  // третийй ключ
 
boolean waterAlarmed = 0; //флаг сработавшего оповещения о воде
boolean alarmState = 0; //флаг работающей сигнализации
boolean gerkonState = 0; //первично закрытая дверь (1 - закрыто, 0 - открыто), пока на кнопке.
boolean Hacked = 0;
// стандартные коды: 1- включение, 2- выключение, 3- тревога
boolean lockLow = true; // ИЗНАЧАЛЬНО ПРАВДА
boolean takeLowTime;  
long unsigned int pause = 30000; //30 секунд паузы между срабатываниями датчика движения
long unsigned int lowIn;
 
 
 
 
void setup()
 {
  Serial.begin(9600);
  delay(2000); //задержка включения
  pinMode(greenLed, OUTPUT); //задаем режим работы пинов
  pinMode(redLed, OUTPUT);
         pinMode(yelowLed, OUTPUT);
  pinMode(waterPin, INPUT);
  pinMode(gerkonPin, INPUT);
         digitalWrite(pirPin, LOW);
         pinMode(pirPin, INPUT);
         ////
           
         ////
         //attachInterrupt(0, water, CHANGE); // привязываем 0-е прерывание к функции water
         //дадим датчику время на калибровку
   Serial.print("calibrating sensor ");
     for(int i = 0; i < calibrationTime; i++){// 30 СЕКУНД КАЛИБРУЕТСЯ
       Serial.print(".");
       delay(1000);
       }
     Serial.println(" done");
     Serial.println("SENSOR ACTIVE");
     delay(50);
     Notify(98); // оповещение о включении ардуино (напр. после перезагрузки)
 
 }
 
 
 
 
 
 
 void loop()
 {
  byte returnedValue = 0; // обнуляем значение
  if(alarmState==0) { //Сигнализация выключена, ждем пока поднесут ключ для ВКЛЮЧЕНИЯ
   returnedValue = findKey();
   if (returnedValue == 1)  { // нашли известный ключ
    guardON(); //вкл статус сигнализации
     Serial.println("on");
   }
  }
  if(alarmState==1) { // если включена сигнализация, то
   gerkonState = digitalRead(gerkonPin); //смотрим геркон
   //Serial.println(gerkonState, HEX);
   if (gerkonState == 1 && Hacked != 1) { //открылась дверь и квартира не взломана <img src="http://s70.ucoz.net/sm/1/wink.gif" border="0" align="absmiddle" alt="wink" />
    Notify(1); // сообщаем компьютеру об открытии двери
    alarmON(); //включаем сигналку
   }
   returnedValue = findKey(); //нужно выключить изнутри квартиры
   if (returnedValue == 1)  { // нашли известный ключ и
    alarmState=0;
    guardOFF();
   }
  }
 
 
 
 
 
 
 
 
 returnedValue = 0; //обнуляем для обработки датчиков воды
  returnedValue = checkWater();
  if (returnedValue==1) { // запускаем оповещение о срабатывании датчика воды
   Notify(10); //сообщаем о срабатывании датчика воды
               
  }
   if(digitalRead(pirPin) == HIGH){ //СРАВНИВАЕМ ВЫХОД ДАТЧИКА С ВЫСОКИМ
        digitalWrite(yelowLed, HIGH);   //СВЕТИК ПОКАЗЫВАЕТ СОСТОЯНие  датчико ДВИЖЕНИЯ-сработал или нет
        if(lockLow&& alarmState==1){  // если уровень датчика движения высокий и сигналка включена  
          //гарантирует, что мы ждем перехода к низкому уровню до того, как дальнейший вывод сделан:
          lockLow = false ;   
                     
          /*Serial.println("---");
          Serial.print("motion detected at ");// ОБНАРУЖЕНО ДВИЖЕНИЕ В ,, СЕКУНД
          Serial.print(millis()/1000);
          Serial.println(" sec");  
          delay(50);*/
          Notify(4); // сообщаем компьютеру о движении в квартире
          }          
          takeLowTime = true;// БЕРЕМ НИЗКОЕ ВРЕМЯ РАНВНО ПРАВДА
        }
    
      if(digitalRead(pirPin) == LOW){ //сравниваем выход датчика снизким уровнем       
        digitalWrite(yelowLed, LOW);  // светик ПОКАЗЫВАЕТ СОСТОЯНИЕ  датчика
    
        if(takeLowTime){
         lowIn = millis();          //сэкономить время перехода от высокого до низкого
         takeLowTime = false;       //убедитесь, что это делается только в начале фазы LOW
         }
        //если датчик низкого за более чем данная пауза,
        //Мы считаем, что движение больше не произойдет И НЕ  
        if(!lockLow && millis() - lowIn > pause){   
            //гарантирует, что этот блок кода выполняется только раз после
            //Новая последовательность движений была обнаружена
            lockLow = true;                         
             //Serial.print("motion eted at ");
            delay(50);
            }
              
        }
  delay (500);
 
 }
 
 
 
 
 
 int checkWater() //функция проверки датчика воды
 {
  int WsensorState = digitalRead(waterPin);
  //Serial.println(WsensorState);
  if (WsensorState == 1 && waterAlarmed ==0 ){
   waterAlarmed =1;
                 guardSound(5); // бибикаем  
               //Serial.println("VODA");
   return 1;
                  
  }
  return 0;
 }
 int findKey() // функция поиска ключа
 {
  byte i;
  byte addr[5];
  byte checkOK = 0; //счетчик совпадений массива с эталоном
  //Serial.println("searching key...");
  if ( !ds.search(addr)) {  // тут надо сделать нормально сделатЬ!!!
   ds.reset_search();
   for( i = 0; i < 5; i++) { // КРИВОКОД
    if (addr[i]==code1[i] || addr[i]==code2[i] || addr[i]==code3[i] || addr[i]==code4[i]) {
     checkOK++;
    }
   }
   if (checkOK == 5 )
   return 1;
  }
 return 0;
 }
 
 
 
 
 
 
 
 void guardON() // выполнение действие при на сигнализацию
 {
  int j;
  alarmState=1; //включаем статус сигнализации
  guardSound(1); //бибикаем
  for (j=0; j < startTime; j++) {
   guardBlink(1); //моргаем лампочками и ждем время для закрытия двери
  }
  Notify(0);
 }
 void guardOFF() // выполнение действие при снятии с сигнализации
 {
  alarmState=0; // выключаем статус сигнализации
  Hacked = 0; // отменям статус "взломано"
  digitalWrite(greenLed, LOW);
  guardSound(2); //бибикаем
  guardBlink(2); //моргаем лампочками
  Notify(3);
 }
 int alarmON() // выполнение действий при срабатывании сигнализации
 {
  int checkcount=0;
  while (checkcount < alarmTime) { // даем alarmTime секунд для поднесения ключа
   int alarmCancel = findKey(); //ищем ключик
   if (alarmCancel == 1) { // нашли ключ
    guardOFF(); //отключаем сигналку,
    break; // выходим из цикла
   }
   checkcount++;
   guardBlink(3); //пищим о том, что ищем ключ
   guardSound(3); //светим о том, что ищем ключ
  }
  if (checkcount==alarmTime) { // если не нашли, то включаем оповещение
   Notify(2);
   guardBlink(4); //пищим о том, что УСЁ ПРОПАЛО
   guardSound(4); //светим о том, что УСЁ ПРОПАЛО
   Hacked = 1;
  }
 }
 
 
 
 
 
 
 int guardBlink (int x) //функция светового оповещения
 {
  if (x==1) { // первое ожидание для закрытия двери.
   digitalWrite(redLed, HIGH);
   digitalWrite(greenLed, LOW);
   delay(500);
   digitalWrite(redLed, LOW);
   digitalWrite(greenLed, HIGH);
   delay(500);
  }
  if (x==2) { // выключаем сигнализацию и диоды
   digitalWrite(redLed, LOW);
   digitalWrite(greenLed, LOW);
  }
  if (x==3) { // во время ожидания ключа при открытой двери
   digitalWrite(redLed, HIGH);
   delay (250);
   digitalWrite(redLed, LOW);
   delay (250);
  }
  if (x==4) { // просрочено, ахтунг
   digitalWrite(redLed, HIGH);
  }
 }
 int guardSound (int x)  //функция звукового оповещения
 {
  if (x==1) {
   int melody[] = { // музыка при включении сигнализацию
    NOTE_B6, NOTE_C6, NOTE_D6, NOTE_G6,  
   };
   int noteDurations[] = {
    8, 8, 8, 4, // ДЛИТЕЛЬНОСТЬ НОТ 4 = четверть ноты, 8 = восьмая часть,  
   };
   for (int thisNote = 0; thisNote < 4; thisNote++) {        // ПЕРЕБОР ВСЕХ ВОСЬМИ НОТ
    int noteDuration = 1000/noteDurations[thisNote];
    tone(tonePin, melody[thisNote],noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    noTone(tonePin);
   }
  }
  if (x==2) { // выключаем сигнализацию
   int melody[] = {
    NOTE_C4, NOTE_G3,NOTE_G4, NOTE_A3, NOTE_G3,2, NOTE_B4, NOTE_C5
   };
   int noteDurations[] = {
    4, 8, 8, 4,4,4,4,4
   };
   for (int thisNote = 0; thisNote < 8; thisNote++) {
    int noteDuration = 1000/noteDurations[thisNote];
    tone(tonePin, melody[thisNote],noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    noTone(tonePin);
   }
  }
  if (x==3) { //тон ожидания ключа
   tone(tonePin,NOTE_C4, 100);
  }
  if (x==4) { //тон просроченного ключа
   tone(tonePin,NOTE_E4, 500);
  }
         if (x==5) { //тон просроченного ключа
   tone(tonePin,NOTE_F6, 500);
  }
 }
 
 
 
 
 int Notify(int x) //функция оповещения  в мобильный телефон
 {
  if (x==0) { // оповещение о постановке на сигнализацию
   Serial.println("0x00-ohrana-on");// здесь пишем код под конкретный GSM модем
  }
  if (x==1) { // оповещение о открытии двери
   Serial.println("0x01-otkrytye _dveri"); //здесь пишем код под конкретный GSM модем
  }
  
  if (x==2) { // оповещение о взломе квартиры!
   Serial.println("0x02-vzlom");
  }
  if (x==3) { // оповещение о выключении сигнализации
   Serial.println("0x03-ohrana-off");
  }
         if (x==4) { // оповещение о движухе
   Serial.println("0x03-dvizgenie d kvartire");
  }
  if (x==98) { // оповещение о включении ardunio
   Serial.println("9x98");
  }
  if (x==99) { // оповещение о ОШИБКЕ
   Serial.println("9x99");
  }
     if (x==10) { // оповещение о затоплении  
   Serial.println("9x-VODA");
  } }
  
 
 
 
 
 
При запуске дает код 9x98 что все нормально .если прислонить ключ, выводит квадратик, и все....... (как будто serial на другой частоте работает(
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Для начала опубликуйте код ещё раз как положено - http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii

А теперь давайте смотреть, что Вы пишете:

pixel28 пишет:

При запуске дает код 9x98 что все нормально .если прислонить ключ, выводит квадратик, и все.......

И что? Ну, хорошо, я принял это к сведению. Дальше что? Видимо, Вы ждёте от этого кода какого-то другого поведения и просите помочь этого другого подведения доиться. Так? Тогда может Вы потрудитесь написать чего Вы хотите. Что по-вашему этот код должен делать? Я вот, например не знаю что именно Вы пишете и, не удивляйтесь, даже не знаю нормально ли то, что у Вас печатается квадратик или это ошибка и на самом деле должен печататься треугольник. Ну, вот откуда мне это знать? Или Вы надеетесь, что кто-то полезет в чужой код разбираться и догадываться "что Вы (или тот у кого Вы скачали) им (кодом) хотели сказать"? Вы понимаете о чём я? Хотите ответа - задайте нормальный, понятный вопрос.

pixel28
Offline
Зарегистрирован: 23.11.2015
#include <OneWire.h>
#include "pitches.h"
const byte greenLed = 10; //зеленая лампочка
const byte redLed = 11;  //красная лампочка
const byte gerkonPin = 8; //gerkon
const byte iButtonPin = 12; //пин для ibutton
const byte tonePin = 7; // пин для пищалки
const byte waterPin = 9; // пин датчика воды
 
const byte alarmTime = 15; // время, чтобы поднести ключ при разблокировке
const byte startTime = 10; // время на закрытие двери при постановке на сигнализацию
 
OneWire  ds(iButtonPin); //ibutton
byte code1[8] = {0x01, 0x55, 0xDF, 0x8B, 0x0C, 0x00, 0x00, 0x3F}; //первый ключ
byte code2[5] = {0x01, 0x90, 0xBA, 0xAB, 0x00};  // второй ключ
 
boolean waterAlarmed = 0; //флаг сработавшего оповещения о воде
boolean alarmState = 0; //флаг работающей сигнализации
boolean gerkonState = 0; //первично закрытая дверь (1 - закрыто, 0 - открыто), пока на кнопке.
boolean Hacked = 0;
// стандартные коды: 1- включение, 2- выключение, 3- тревога
void setup()
{
    Serial.begin(9600);
    delay(2000); //задержка включения
    pinMode(greenLed, OUTPUT); //задаем режим работы пинов
    pinMode(redLed, OUTPUT);
    pinMode(waterPin, INPUT);
    pinMode(gerkonPin, INPUT);
    Notify(98); // оповещение о включении ардуино (напр. после перезагрузки)
}
void loop()
{
    byte returnedValue = 0;
    if(alarmState==0) { //Сигнализация выключена, ждем пока поднесут ключ для ВКЛЮЧЕНИЯ
        returnedValue = findKey();
        if (returnedValue == 1)  { // нашли известный ключ
Serial.println("on");
            guardON(); //вкл статус сигнализации
        }
    }
    if(alarmState==1) { // если включена сигнализация, то
        gerkonState = digitalRead(gerkonPin); //смотрим геркон
        //Serial.println(gerkonState, HEX);
        if (gerkonState == 1 && Hacked != 1) { //открылась дверь и квартира не взломана ;)
            Notify(1); // сообщаем компьютеру об открытии двери
            alarmON(); //включаем сигналку
        }
        returnedValue = findKey(); //нужно выключить изнутри квартиры
        if (returnedValue == 1)  { // нашли известный ключ и
            alarmState=0;
            guardOFF();
        }
    }
    returnedValue = 0; //обнуляем для обработки датчиков воды
    //returnedValue = checkWater();
    //if (returnedValue==1) { // запускаем оповещение о срабатывании датчика воды
    //  Notify(10); //сообщаем о срабатывании датчика воды
    //}
    delay (500);
}
int checkWater() //функция проверки датчика воды
{
    int WsensorState = analogRead(waterPin);
    //Serial.println(WsensorState);
    if (WsensorState == 1 && waterAlarmed == 0){
        waterAlarmed =1;
        return 1;
    }
    return 0;
}
int findKey() // функция поиска ключа
{
    byte i;
    byte addr[5];
    byte checkOK = 0; //счетчик совпадений массива с эталоном
    //Serial.println("searching key...");
    if ( !ds.search(addr)) {  // тут надо сделать нормально сделатЬ!!!
        ds.reset_search();
        for( i = 0; i < 5; i++) { // КРИВОКОД
            if (addr[i]==code1[i] || addr[i]==code2[i]) {
                checkOK++;
            }
        }
        if (checkOK == 5 )
        return 1;
    }
return 0;
}
void guardON() // выполнение действие при на сигнализацию
{
    int j;
    alarmState=1; //включаем статус сигнализации
    guardSound(1); //бибикаем
    for (j=0; j < startTime; j++) {
        guardBlink(1); //моргаем лампочками и ждем время для закрытия двери
    }
    Notify(0);
}
void guardOFF() // выполнение действие при снятии с сигнализации
{
    alarmState=0; // выключаем статус сигнализации
    Hacked = 0; // отменям статус "взломано"
    digitalWrite(greenLed, LOW);
    guardSound(2); //бибикаем
    guardBlink(2); //моргаем лампочками
    Notify(3);
}
int alarmON() // выполнение действий при срабатывании сигнализации
{
    int checkcount=0;
    while (checkcount < alarmTime) { // даем alarmTime секунд для поднесения ключа
        int alarmCancel = findKey(); //ищем ключик
        if (alarmCancel == 1) { // нашли ключ
            guardOFF(); //отключаем сигналку,
            break; // выходим из цикла
        }
        checkcount++;
        guardBlink(3); //пищим о том, что ищем ключ
        guardSound(3); //светим о том, что ищем ключ
    }
    if (checkcount==alarmTime) { // если не нашли, то включаем оповещение
        Notify(2);
        guardBlink(4); //пищим о том, что УСЁ ПРОПАЛО
        guardSound(4); //светим о том, что УСЁ ПРОПАЛО
        Hacked = 1;
    }
}
int guardBlink (int x) //функция светового оповещения
{
    if (x==1) { // первое ожидание для закрытия двери.
        digitalWrite(redLed, HIGH);
        digitalWrite(greenLed, LOW);
        delay(500);
        digitalWrite(redLed, LOW);
        digitalWrite(greenLed, HIGH);
        delay(500);
    }
    if (x==2) { // выключаем сигнализацию и диоды
        digitalWrite(redLed, LOW);
        digitalWrite(greenLed, LOW);
    }
    if (x==3) { // во время ожидания ключа при открытой двери
        digitalWrite(redLed, HIGH);
        delay (250);
        digitalWrite(redLed, LOW);
        delay (250);
    }
    if (x==4) { // просрочено, ахтунг
        digitalWrite(redLed, HIGH);
    }
}
int guardSound (int x)  //функция звукового оповещения
{
    if (x==1) {
        int melody[] = { // музыка при включении сигнализацию
            NOTE_G3, NOTE_G3, NOTE_G3
        };
        int noteDurations[] = {
            4,4,4
        };
        for (int thisNote = 0; thisNote < 3; thisNote++) {
            int noteDuration = 1000/noteDurations[thisNote];
            tone(tonePin, melody[thisNote],noteDuration);
            int pauseBetweenNotes = noteDuration * 1.30;
            delay(pauseBetweenNotes);
            noTone(tonePin);
        }
    }
    if (x==2) { // выключаем сигнализацию
        int melody[] = {
            NOTE_C2, NOTE_G1,NOTE_G2, NOTE_A1, NOTE_G1,0, NOTE_B2, NOTE_C3
        };
        int noteDurations[] = {
            4, 8, 8, 4,4,4,4,4
        };
        for (int thisNote = 0; thisNote < 8; thisNote++) {
            int noteDuration = 1000/noteDurations[thisNote];
            tone(tonePin, melody[thisNote],noteDuration);
            int pauseBetweenNotes = noteDuration * 1.30;
            delay(pauseBetweenNotes);
            noTone(tonePin);
        }
    }
    if (x==3) { //тон ожидания ключа
        tone(tonePin,NOTE_C4, 100);
    }
    if (x==4) { //тон просроченного ключа
        tone(tonePin,NOTE_E4, 500);
    }
}
int Notify(int x) //функция оповещения в последователньый порт
{
    if (x==0) { // оповещение о постановке на сигнализацию
        Serial.println("0x00");
    }
    if (x==1) { // оповещение о открытии двери
        Serial.println("0x01");
    }
    if (x==2) { // оповещение о взломе квартиры!
        Serial.println("0x02");
    }
    if (x==3) { // оповещение о выключении сигнализации
        Serial.println("0x03");
    }
    if (x==98) { // оповещение о включении ardunio
        Serial.println("9x98");
    }
    if (x==99) { // оповещение о ОШИБКЕ
        Serial.println("9x99");
    }
}




Вот прикрепил код как подожено, в первом сообщении еще и не весь вставил. Дело в том, что когда я подношу ключик должны выполнятся команды 

Serial.println("on");

guardON();

А у меня они не выполняются. Значит дело в ibutton, что-то в этом коде не правильно сделано...

           

Araris
Offline
Зарегистрирован: 09.11.2012

У Вас строки 79-86 выполняются, если ничего не найдено.

"myWire.search(addrArray) Search for the next device. The addrArray is an 8 byte array. If a device is found, addrArray is filled with the device's address and true is returned. If no more devices are found, false is returned."

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

pixel28 пишет:
Дело в том, что когда я подношу ключик должны выполнятся команды

Кому это они так задолжали? Ничего они Вам не должны.

Судья по Вашему коду (строки 36-38), Serial.println("on"); выполняется только в том случае, если findKey() вернёт 1.

Давайте разбираться что она на самом деле возвращает.

Пожалуйста расскажите чётко и построчно (ссылаяст на номера строк) что у Вас делает функция findKey(). Чётко, шаг за шагом, что делается в каждой строке.

Давайте.

pixel28
Offline
Зарегистрирован: 23.11.2015

Я с тем куском кода разобрался. Теперь сигналка работает. 

Хотел спросить как работает вот эта часть кода?

if(digitalRead(pirPin) == HIGH){ //СРАВНИВАЕМ ВЫХОД ДАТЧИКА С ВЫСОКИМ
        digitalWrite(yelowLed, HIGH);   //СВЕТИК ПОКАЗЫВАЕТ СОСТОЯНие  датчико ДВИЖЕНИЯ-сработал или нет
        if(lockLow&& alarmState==1){  // если уровень датчика движения высокий и сигналка включена  
          //гарантирует, что мы ждем перехода к низкому уровню до того, как дальнейший вывод сделан:
          lockLow = false ;   
                     
          Serial.println("---");
          Serial.print("motion detected at ");// ОБНАРУЖЕНО ДВИЖЕНИЕ В ,, СЕКУНД
          Serial.print(millis()/1000);
          Serial.println(" sec");  
          delay(50);
          Notify(4); // сообщаем компьютеру о движении в квартире
         
         }          
          takeLowTime = true;// БЕРЕМ НИЗКОЕ ВРЕМЯ РАНВНО ПРАВДА
        }
    
      if(digitalRead(pirPin) == LOW){ //сравниваем выход датчика снизким уровнем       
        digitalWrite(yelowLed, LOW);  // светик ПОКАЗЫВАЕТ СОСТОЯНИЕ  датчика
    
        if(takeLowTime){
         lowIn = millis();          //сэкономить время перехода от высокого до низкого
         takeLowTime = false;       //убедитесь, что это делается только в начале фазы LOW
         }
        //если датчик низкого за более чем данная пауза,
        //Мы считаем, что движение больше не произойдет И НЕ  
        if(!lockLow && millis() - lowIn > pause){   
            //гарантирует, что этот блок кода выполняется только раз после
            //Новая последовательность движений была обнаружена
            lockLow = true;                         
             Serial.print("motion eted at ");
             
            delay(50);
            }
              

А то этот код не мой, немного не понятно. Работает с датчиком движения. Как я понял когда на вход идет импульс идет какое то сравнение. Но я не понял какое. 

 

Взял из нового кода:

#include <OneWire.h>
#include "pitches.h"
 
const byte iButtonPin = 3; //пин для ibutton
const byte waterPin = 9; // пин датчика воды
const byte pirPin = 5; // пин для СЕНСОРА ДВИЖЕНИЯ
const byte yelowLed = 6; // лампочка индикатор движения
const byte tonePin = 4; // пин для пищалки
const byte gerkonPin = 2; //gerkon
const byte greenLed = 10; //зеленая лампочка
const byte redLed = 11;  //красная лампочка
const byte calibrationTime = 3; // Время калибровки датчика (10-60 сек. по даташиту)
 
const byte alarmTime = 35; // время, чтобы поднести ключ при разблокировке(ЧИСЛО МИГАНИЙ)
const byte startTime = 10; // время на закрытие двери при постановке на сигнализацию(ЧИСЛО МИГАНИЙ)
 
OneWire  ds(iButtonPin); //ibutton
byte code1[8] = {0x01, 0x55, 0xDF, 0x8B, 0x0C, 0x00, 0x00, 0x3F}; // Первый ключ
byte code2[8] = {0x01, 0x72, 0x97, 0xB1, 0x0C, 0x00, 0x00, 0x88};  // второй ключ
byte code3[8] = {0x01, 0x30, 0xAA, 0x0E, 0x00, 0x00, 0x00, 0x4B};  //ЧЕТВЕРТЫй ключ
byte code4[8] = {0x01, 0xC4, 0x72, 0x22, 0x0B, 0x00, 0x00, 0x26};  // третийй ключ
 
boolean waterAlarmed = 0; //флаг сработавшего оповещения о воде
boolean alarmState = 0; //флаг работающей сигнализации
boolean gerkonState = 0; //первично закрытая дверь (1 - закрыто, 0 - открыто), пока на кнопке.
boolean Hacked = 0;
// стандартные коды: 1- включение, 2- выключение, 3- тревога
boolean lockLow = true; // ИЗНАЧАЛЬНО ПРАВДА
boolean takeLowTime;  
long unsigned int pause = 10000; //30 секунд паузы между срабатываниями датчика движения
long unsigned int lowIn;

void setup()
 {
  Serial.begin(9600);
  delay(2000); //задержка включения
  pinMode(greenLed, OUTPUT); //задаем режим работы пинов
  pinMode(redLed, OUTPUT);
         pinMode(yelowLed, OUTPUT);
  pinMode(waterPin, INPUT);
  pinMode(gerkonPin, INPUT);
         digitalWrite(pirPin, LOW);
         pinMode(pirPin, INPUT);
         ////
           
         ////
         //attachInterrupt(0, water, CHANGE); // привязываем 0-е прерывание к функции water
         //дадим датчику время на калибровку
   Serial.print("calibrating sensor ");
     for(int i = 0; i < calibrationTime; i++){// 30 СЕКУНД КАЛИБРУЕТСЯ
       Serial.print(".");
       delay(1000);
       }
     Serial.println(" done");
     Serial.println("SENSOR ACTIVE");
     delay(50);
    Notify(98); // оповещение о включении ардуино (напр. после перезагрузки)
 
 }

 void loop()
 {
  byte returnedValue = 0; // обнуляем значение
  if(alarmState==0) { //Сигнализация выключена, ждем пока поднесут ключ для ВКЛЮЧЕНИЯ
   returnedValue = findKey();
   if (returnedValue == 1)  { // нашли известный ключ
    guardON(); //вкл статус сигнализации
     
   }
  }
  if(alarmState==1) { // если включена сигнализация, то
   gerkonState = digitalRead(gerkonPin); //смотрим геркон
   //Serial.println(gerkonState, HEX);
   if (gerkonState == 1 && Hacked != 1) { //открылась дверь и квартира не взломана <img src="http://s70.ucoz.net/sm/1/wink.gif" border="0" align="absmiddle" alt="wink" />
    Notify(1); // сообщаем компьютеру об открытии двери
    alarmON(); //включаем сигналку
   }
   returnedValue = findKey(); //нужно выключить изнутри квартиры
   if (returnedValue == 1)  { // нашли известный ключ и
    alarmState=0;
    guardOFF();
   }
  }

  returnedValue = 0; //обнуляем для обработки датчиков воды
  returnedValue = checkWater();
  if (returnedValue==1) { // запускаем оповещение о срабатывании датчика воды
   Notify(10); //сообщаем о срабатывании датчика воды
               
  }
   if(digitalRead(pirPin) == HIGH){ //СРАВНИВАЕМ ВЫХОД ДАТЧИКА С ВЫСОКИМ
        digitalWrite(yelowLed, HIGH);   //СВЕТИК ПОКАЗЫВАЕТ СОСТОЯНие  датчико ДВИЖЕНИЯ-сработал или нет
        if(lockLow&& alarmState==1){  // если уровень датчика движения высокий и сигналка включена  
          //гарантирует, что мы ждем перехода к низкому уровню до того, как дальнейший вывод сделан:
          lockLow = false ;   
                     
          Serial.println("---");
          Serial.print("motion detected at ");// ОБНАРУЖЕНО ДВИЖЕНИЕ В ,, СЕКУНД
          Serial.print(millis()/1000);
          Serial.println(" sec");  
          delay(50);
          Notify(4); // сообщаем компьютеру о движении в квартире
         
         }          
          takeLowTime = true;// БЕРЕМ НИЗКОЕ ВРЕМЯ РАНВНО ПРАВДА
        }
    
      if(digitalRead(pirPin) == LOW){ //сравниваем выход датчика снизким уровнем       
        digitalWrite(yelowLed, LOW);  // светик ПОКАЗЫВАЕТ СОСТОЯНИЕ  датчика
    
        if(takeLowTime){
         lowIn = millis();          //сэкономить время перехода от высокого до низкого
         takeLowTime = false;       //убедитесь, что это делается только в начале фазы LOW
         }
        //если датчик низкого за более чем данная пауза,
        //Мы считаем, что движение больше не произойдет И НЕ  
        if(!lockLow && millis() - lowIn > pause){   
            //гарантирует, что этот блок кода выполняется только раз после
            //Новая последовательность движений была обнаружена
            lockLow = true;                         
             Serial.print("motion eted at ");
             
            delay(50);
            }
              
        }
  delay (500);
 
 }

 int checkWater() //функция проверки датчика воды
 {
  int WsensorState = digitalRead(waterPin);
  //Serial.println(WsensorState);
  if (WsensorState == 1 && waterAlarmed ==0 ){
   waterAlarmed =1;
                 guardSound(5); // бибикаем  
               //Serial.println("VODA");
   return 1;
                  
  }
  return 0;
 }
 int findKey() // функция поиска ключа
{
    byte i;
    byte addr[8];
    byte checkOK = 0; //счетчик совпадений массива с эталоном
    //Serial.println("searching key...");
    if (ds.search(addr)) {  
        ds.reset_search();
         for ( i = 0; i < 8; i++) { // КРИВОКОД
            if (addr[i]==code1[i]) {
                checkOK++;
            }
        }
        if (checkOK == 8 )
        return 1;
  }
 return 0;
 }

 void guardON() // выполнение действие при на сигнализацию
 {
  int j;
  alarmState=1; //включаем статус сигнализации
  guardSound(1); //бибикаем
  for (j=0; j < startTime; j++) {
   guardBlink(1); //моргаем лампочками и ждем время для закрытия двери
   tone(4, 1000, 150);
  }
  Notify(0);
  tone(4, 1000, 1000); 
 }
 void guardOFF() // выполнение действие при снятии с сигнализации
 {
  alarmState=0; // выключаем статус сигнализации
  Hacked = 0; // отменям статус "взломано"
  digitalWrite(greenLed, LOW);
  guardSound(2); //бибикаем
  guardBlink(2); //моргаем лампочками
  Notify(3);
 }
 int alarmON() // выполнение действий при срабатывании сигнализации
 {
  int checkcount=0;
  while (checkcount < alarmTime) { // даем alarmTime секунд для поднесения ключа
   int alarmCancel = findKey(); //ищем ключик
   if (alarmCancel == 1) { // нашли ключ
    guardOFF(); //отключаем сигналку,
    break; // выходим из цикла
   }
   checkcount++;
   guardBlink(3); //пищим о том, что ищем ключ
   guardSound(3); //светим о том, что ищем ключ
  }
  if (checkcount==alarmTime) { // если не нашли, то включаем оповещение
   Notify(2);
   guardBlink(4); //пищим о том, что УСЁ ПРОПАЛО
   guardSound(4); //светим о том, что УСЁ ПРОПАЛО
   Hacked = 1;
  }
 }

 int guardBlink (int x) //функция светового оповещения
 {
  if (x==1) { // первое ожидание для закрытия двери.
   digitalWrite(redLed, HIGH);
   digitalWrite(greenLed, LOW);
   delay(500);
   digitalWrite(redLed, LOW);
   digitalWrite(greenLed, HIGH);
   delay(500);
  }
  if (x==2) { // выключаем сигнализацию и диоды
   digitalWrite(redLed, LOW);
   digitalWrite(greenLed, LOW);
  }
  if (x==3) { // во время ожидания ключа при открытой двери
   digitalWrite(redLed, HIGH);
   delay (250);
   digitalWrite(redLed, LOW);
   delay (250);
  }
  if (x==4) { // просрочено, ахтунг
   digitalWrite(redLed, HIGH);
  }
 }
 int guardSound (int x)  //функция звукового оповещения
 {
  if (x==1) {
   int melody[] = { // музыка при включении сигнализацию
    NOTE_B6, NOTE_C6, NOTE_D6, NOTE_G6,  
   };
   int noteDurations[] = {
    8, 8, 8, 4, // ДЛИТЕЛЬНОСТЬ НОТ 4 = четверть ноты, 8 = восьмая часть,  
   };
   for (int thisNote = 0; thisNote < 4; thisNote++) {        // ПЕРЕБОР ВСЕХ ВОСЬМИ НОТ
    int noteDuration = 1000/noteDurations[thisNote];
    tone(tonePin, melody[thisNote],noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    noTone(tonePin);
   }
  }
  if (x==2) { // выключаем сигнализацию
   int melody[] = {
    NOTE_C4, NOTE_G3,NOTE_G4, NOTE_A3, NOTE_G3,2, NOTE_B4, NOTE_C5
   };
   int noteDurations[] = {
    4, 8, 8, 4,4,4,4,4
   };
   for (int thisNote = 0; thisNote < 8; thisNote++) {
    int noteDuration = 1000/noteDurations[thisNote];
    tone(tonePin, melody[thisNote],noteDuration);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    noTone(tonePin);
   }
  }
  if (x==3) { //тон ожидания ключа
   tone(tonePin,NOTE_C4, 100);
  }
  if (x==4) { //тон просроченного ключа
   tone(tonePin,NOTE_E4, 500);
  }
         if (x==5) { //тон просроченного ключа
   tone(tonePin,NOTE_F6, 500);
  }
 }





int Notify(int x) //функция оповещения  в мобильный телефон
 {
  if (x==0) { // оповещение о постановке на сигнализацию
   Serial.println("ohrana-on");// здесь пишем код под конкретный GSM модем
  }
  if (x==1) { // оповещение о открытии двери
   Serial.println("otkrytye _dveri"); //здесь пишем код под конкретный GSM модем
  }
  
  if (x==2) { // оповещение о взломе квартиры!
   Serial.println("vzlom");
  }
  if (x==3) { // оповещение о выключении сигнализации
   Serial.println("ohrana-off");
  }
         if (x==4) { // оповещение о движухе
   Serial.println("dvizgenie d kvartire");
  }
  if (x==98) { // оповещение о включении ardunio
   Serial.println("Arduino on");
  }
  if (x==99) { // оповещение о ОШИБКЕ
   Serial.println("ERROR");
  }
         if (x==10) { // оповещение о затоплении  
   Serial.println("9x-VODA");
  }
 }