Сигнализация для загородного дома.

Тема в разделе "Arduino & Shields", создана пользователем Samopalkin, 22 апр 2016.

  1. ostrov

    ostrov Гуру

    Создаете 6 флажков для датчиков (переменных типа bool например), заполняете их true (опрос датчиков вкл) и 6 таймеров (переменных типа unsigned long). Начинаете опрос датчиков. Делаете это так: если флажок данного датчика == true, то опрашиваете его, если == false, то не опрашиваете датчик, но проверяете состояние таймера, не подошла ли очередь перекинуть его в true и переключить то что вам там требуется. Как только датчик сработал, устанавливаете его флажок в false и запускаете таймер timer1 = millis()+10000 (вместо этой цифры ставите индивидуальную задержку). Можно изловчиться и вообще обойтись без флажков, проверяя состояние по содержимому таймера, если больше чем millis(), то датчик не опрашивается, если меньше, то опрашивается.

    Причем, если номера всех пинов датчиков и реле загнать в массивы, то можно будет написать код один раз для всех 6 или сколько их там будет пар и обрабатывать их в цикле по очереди.
     
    Последнее редактирование: 28 апр 2016
  2. ostrov

    ostrov Гуру

    И еще, не прописывайте адреса пинов через переменные. Или константами или макроопределением, например так:
    Код (C++):
    #define PirSensor  12
    #define Relay  10
    Но в таком случае еще грамотнее сделать так:
    Код (C++):
    #define PIRSENSOR  12
    #define RELAY  10
     
  3. ИгорьК

    ИгорьК Гуру

    Код (C++):
    #define PirSensor 12     // Зачем засорять память?
    #define Relay 10
    #define LED 13         // Выносите все определения в заголовок -
    #define DELAY 10000    // мало ли что потом придется поменять
    // Переменная, которая будет помнить время
    unsigned long timeWhenSwitchOFF;

    void setup() {
      pinMode (PirSensor, INPUT);
      pinMode (Relay, OUTPUT);
      pinMode (LED, OUTPUT);
      digitalWrite(LED, LOW);
    }

    void loop() {
        if (digitalRead(PirSensor) == HIGH) {
            timeWhenSwitchOFF = millis() + DELAY;
            // Мы узнали время, и прибавили к нему задержку
            // пока сенсор в единице - это условие выполняется
            // и переменная увеличивается соответственно
            digitalWrite(LED, HIGH);     //для индикации срабатывания датчика
            digitalWrite(Relay, LOW);
        }
        if(millis() > timeWhenSwitchOFF) {
            digitalWrite(LED, LOW);
            digitalWrite(Relay, HIGH);
        }
    }
    А так для трех сенсоров и одного реле. Или реле по количеству сенсоров?
    Код (C++):
    #define PirSensor01 12     // Зачем засорять память?
    #define PirSensor02 9
    #define PirSensor03 7
    #define Relay 10
    #define LED 13         // Выносите все определения в заголовок -
    #define DELAY 10000    // мало ли что потом придется поменять
    // Переменная, которая будет помнить время
    unsigned long timeWhenSwitchOFF;

    void setup() {
      pinMode (PirSensor01, INPUT);
      pinMode (PirSensor02, INPUT);
      pinMode (PirSensor03, INPUT);
      pinMode (Relay, OUTPUT);
      pinMode (LED, OUTPUT);
      digitalWrite(LED, LOW);
    }

    void loop() {
            // А так для трех сенсоров и однго реле.
        if (digitalRead(PirSensor01)  || digitalRead(PirSensor02) || digitalRead(PirSensor03) {
            // Мы узнали время, и прибавили к нему задержку
            // пока сенсор в единице - это условие выполняется
            // и переменная увелиивается соответственно
            timeWhenSwitchOFF = millis() + DELAY;
            digitalWrite(LED, HIGH);     //для индикации срабатывания датчика
            digitalWrite(Relay, LOW);
        }
        if(millis() > timeWhenSwitchOFF) {
            digitalWrite(LED, LOW);
            digitalWrite(Relay, HIGH);
        }
    }
     
    Последнее редактирование: 28 апр 2016
  4. Samopalkin

    Samopalkin Нуб

    Попробую разобраться, спасибо.
    Попробовал использовать этот код, но реле срабатывает сразу, и остается включенным секунд десять. Реле одно.
     
  5. ИгорьК

    ИгорьК Гуру

    Включаю ясновидение...
    Не получилось.
    А какой код из двух? И что потом происходит? Все взорвалось? Инопланетяне прилетели?
    ... так, ясновидение восстановилось. Это я Вам не то накидал.
    То есть Вы хотите, включить реле через 10 секунд после первого срабатывания, и в том случае, если срабатывания продолжаются?
    Ок. Сейчас напишу.
     
    Последнее редактирование: 28 апр 2016
  6. Samopalkin

    Samopalkin Нуб

    Второй. При срабатывании любого датчика, реле включается сразу, и выключается секунд через десять.
     
  7. Samopalkin

    Samopalkin Нуб

    Ну да.
     
  8. ИгорьК

    ИгорьК Гуру

    Код (C++):
    #define PirSensor01 12     // Зачем засорять память?
    #define PirSensor02 9
    #define PirSensor03 7
    #define Relay 10
    #define LED 13         // Выносите все определения в заголовок -
    #define DELAY 10000    // мало ли что потом придется поменять
    // Переменная, которая будет помнить время
    unsigned long timeWhenSwitchOFF;
    unsigned long timeWhenSwitchON;
    bool switchOnFlag = false;
    bool gotMuvFlag = false;

    bool checkSensors() {
        if (digitalRead(PirSensor01)  || digitalRead(PirSensor02) || digitalRead(PirSensor03) ) {
            return true;
        }
        else {
            return false;
        }
    }

    void setup() {
      pinMode (PirSensor01, INPUT);
      pinMode (PirSensor02, INPUT);
      pinMode (PirSensor03, INPUT);
      pinMode (Relay, OUTPUT);
      pinMode (LED, OUTPUT);
      digitalWrite(LED, LOW);
    }

    void loop() {
       
        if (checkSensors() && (gotMuvFlag == false) )  {
            timeWhenSwitchON = millis() + DELAY;
            digitalWrite(LED, HIGH);
            gotMuvFlag = true;
        }

        if(millis() > timeWhenSwitchON)  {
            if(checkSensors()) {
                digitalWrite(Relay, LOW);
                switchOnFlag = true;
                timeWhenSwitchOFF = millis() + DELAY;
            }
            else {
                gotMuvFlag = false;
                digitalWrite(LED, LOW);
            }
        }

        if((millis() > timeWhenSwitchOFF) && !checkSensors() && switchOnFlag) {
            digitalWrite(Relay, HIGH);
            digitalWrite(LED, LOW);
            switchOnFlag = false;
            gotMuvFlag = false;
        }
    }
    Наверно так.
     
    Последнее редактирование: 28 апр 2016
  9. Samopalkin

    Samopalkin Нуб

    Спасибо. Вроде работает, правда не совсем понятно. Реле то срабатывает как надо (если сигнал с датчика продолжается дольше 10 секунд), то сразу вместе с датчиком. Пока не могу уловить алгоритм.
     
  10. Samopalkin

    Samopalkin Нуб

    Установил датчики, пока вроде работают нормально. Подключал датчики с помощью LAN кабеля, по каждой витой паре пускал минус и сигнальный (для уменьшения помех). На датчиках установил дополнительные транзисторы, для инверсии уровня, и притянул входы к плюсу. Без этого, датчики срабатывали как-то неуверенно, когда подключались через длинные провода. Правда с индивидуальной задержкой, для каждого датчика, я так и не разобрался:) Ну и фиг с ней, пусть будет общая:) Теперь пришла в голову мысль, сделать установку и снятие охраны, с помощью смс с кодом:) Пока ищу похожие примеры, надеюсь разберусь:)
     
  11. ИгорьК

    ИгорьК Гуру

  12. Samopalkin

    Samopalkin Нуб

    Появился вопрос:
    Код (C++):

    #define Input1 3
    #define Input2 4
    #define Input3 5
    #define LED 13
    void setup() {
      pinMode (Input1, INPUT_PULLUP);
      pinMode (Input2, INPUT_PULLUP);
      pinMode (Input3, INPUT_PULLUP);
      pinMode (LED, OUTPUT);
      digitalWrite(LED, LOW);
    }

    void loop() {
      if (digitalRead(Input1) || digitalRead(Input2) || digitalRead(Input3) == LOW)
      { digitalWrite(LED, HIGH);
      }else{
        digitalWrite(LED, LOW);
      }
    }
     
    В данном случае светодиод должен загораться только при появлении низкого уровня сигнала, на любом из трех входов, а остальное время не гореть. Или я что-то не так понимаю? Почему-то он горит постоянно.
     
    Последнее редактирование: 2 июн 2016
  13. Limoney

    Limoney Гик

    Код (C++):
    if ((digitalRead(Input1) == LOW) || (digitalRead(Input2) == LOW) || (digitalRead(Input3) == LOW))
      {
        digitalWrite(LED, HIGH);
      }
      else {
        digitalWrite(LED, LOW);
      }
     
  14. Samopalkin

    Samopalkin Нуб

    Спасибо :)
     
  15. Samopalkin

    Samopalkin Нуб

    Идея с задержкой срабатывания оказалась неудачной. После тестирования в солнечный и ветреный день выяснилось, что возникает множество ложных срабатываний датчиков. Задержка помогала игнорировать большинство из них, но примерно раз в час, ложное срабатывание сигнализации все-таки проскакивало. Решил попробовать сделать так, чтобы сигнализация срабатывала только при поступлении сигнала с двух, рядом расположенных датчиков (они стоят примерно через пять метров, так что по любому попадаешь в зону действия двух датчиков):
    Код (C++):
    #define Pir1 2
    #define Pir2 3
    #define Pir3 4
    #define Pir4 5
    #define Pir5 6
    #define Pir6 7
    #define Relay 10
    #define Light 13
    void setup()
    {
      pinMode (Pir1, INPUT_PULLUP);
      pinMode (Pir2, INPUT_PULLUP);
      pinMode (Pir3, INPUT_PULLUP);
      pinMode (Pir4, INPUT_PULLUP);
      pinMode (Pir5, INPUT_PULLUP);
      pinMode (Pir6, INPUT_PULLUP);
      pinMode (Relay, OUTPUT);
      pinMode (Light, OUTPUT);
      digitalWrite(Light, LOW);
    }

    void loop() {
      if ((digitalRead(Pir1) == LOW) && (digitalRead(Pir2) == LOW) || (digitalRead(Pir2) == LOW) && (digitalRead(Pir3) == LOW) || (digitalRead(Pir3) == LOW) && (digitalRead(Pir4) == LOW) || (digitalRead(Pir4) == LOW) && (digitalRead(Pir5) == LOW) || (digitalRead(Pir5) == LOW) && (digitalRead(Pir6) == LOW) || (digitalRead(Pir6) == LOW) && (digitalRead(Pir1) == LOW))
      {
        digitalWrite(Light, HIGH); //для индикации срабатывания датчика
        digitalWrite(Relay, LOW);
      } else {
        digitalWrite(Relay, HIGH);
        digitalWrite(Light, LOW);
      }
    }
     
    За день работы, ни одного ложного срабатывания :) Но когда я пытался пройтись возле дома, срабатывало всегда.
     
  16. Limoney

    Limoney Гик

    Вы попытались запутать компилятор. На этот раз вам это не удалось, компилятор понял задумку.
    Правильнее выделять последовательность выражений скобками.
    Без скобок может нарушиться последовательность выражений, программа сработает, не так как поставлена задача. Она просто выполнит то, что вы ее попросили.
    Код (C++):
    if (((digitalRead(Pir1) == LOW) && (digitalRead(Pir2) == LOW)) ||
        ((digitalRead(Pir2) == LOW) && (digitalRead(Pir3) == LOW))
        ...
       )