Умные туалет и ванная.

Hamster
Offline
Зарегистрирован: 12.07.2015

Не открывается ссылка

Brewster
Offline
Зарегистрирован: 26.11.2017

А вы прям в али начните в поиске вбивать это название. Китайцы жгут. 

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

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

знаем где   .com/item/PIR-16/32880924402.html

 

Rex
Offline
Зарегистрирован: 16.02.2018
#define SENSOR1_PIN 2            //вход управления 1м электроклапаном
#define SENSOR2_PIN 3            //вход управления 2м электроклапаном
#define FLAP1_PIN 4              //выход управления 1м электроклапаном
#define FLAP2_PIN 5              //выход управления 2м электроклапаном
#define GERKON_PIN 6             //вход геркон
#define SENSOR_PIN 7             //вход датчик движения
#define LAMP_PIN 8               //выход управления освещением
#define R_PIN 9                  //выход управления красным цветом
#define G_PIN 10                 //выход управления зеленым цветом
#define B_PIN 11                 //выход управления голубым цветом
#define RGB_POWER 12             //выход вкл/выкл БП для RGB
#define FAN_BUTTON_PIN 15        //вход управления вентилятором (кнопка)
#define FAN_PIN 16               //выход управления вентилятором
#define DEBOUNCE_DELAY 100       //время антидребезга кнопки вентилятора в мс
#define FAN_ON_TIME 10           //время работы вентилятора после выкл. света, мин
#define ON_FLAP1_ON 30           //время работы 1го клапана при активации сенсора, сек
#define ON_FLAP1_OFF 2           //время работы 1го клапана при деактивации сенсора, сек
#define ON_FLAP2_ON 30           //время работы 2го клапана при активации сенсора, сек
#define ON_FLAP2_OFF 2           //время работы 2го клапана при деактивации сенсора, сек
#define DEBOUNCE1_SENSOR 300     //задержка сработки для 1го электроклапана, мс
#define DEBOUNCE2_SENSOR 300     //задержка сработки для 2го электроклапана, мс
#define DELAY_LAMP_OFF_OPEN 40   //задержка выключения света после открытия двери, сек
#define DELAY_LAMP_OFF_CLOSE 15  //задержка выключения света после закрытия двери, сек
#define DELAY_DOOR_CLOSE 5       //задержка регистрации движения после закрытия двери, сек
#define DEBOUNCE_GERKON 80       //время антидребезга геркона в мс
#define INTERVAL 250             //интервал мигания светодиода индик. сработки датчика движения, мс

//переменные для управления кранами
unsigned long int timeSensor1On, timeSensor1Off, timeSensor2On, timeSensor2Off;
bool flap1On = false;      //переменная для хранения состояния 1го электроклапана
bool flap2On = false;      //переменная для хранения состояния 2го электроклапана
bool sensor1 = LOW;        //переменная для хранения состояния сенсора 1го электроклапана
bool sensor2 = LOW;        //переменная для хранения состояния сенсора 2го электроклапана
bool lastSensor1 = HIGH;   //переменная для хранения последнего состояния сенсора 1го электроклапана
bool lastSensor2 = HIGH;   //переменная для хранения последнего состояния сенсора 2го электроклапана
//////////////////////////////////////////////////////////////////////////////////

//переменные для управления освещением
bool lamp;           //переменная для хранения состояния освещения (вкл/выкл)
bool gerkon_flag;    //вспомогательная переменная для хранения состояния сработки геркона
bool sensor_flag;    //вспомогательная переменная для хранения состояния датчика движения
bool motionClose;    //переменная для индикации движения при закрытой двери
bool motionOpen;     //переменная для индикации движения при открытой двери
unsigned long doorClosedTime, doorOpenedTime, doorClosedDelay; //переменные для хранения времени момента закрытия и открытия двери
//переменные для функции светодиодной индикации сработки датчика движения
unsigned long int previousMillis = 0;
bool ledMotionState;
byte motionCount = 0;
////////////////////////////////////////////////////////////////////////////////////

//переменные для управления вентилятором
bool fanState;
bool fanButtonState;
bool lastFanButtonState;
unsigned long int lastDebounceTime = 0, fanButtonOffTime, workTime = (long)FAN_ON_TIME * 60 * 1000;
/////////////////////////////////////////////////////////////////////////////////////

//переменные для функции задержки (антидребезга) геркона
bool _bounse3S = 1;
bool _bounse3O = 1;
unsigned long _bounse3P = 0UL;
/////////////////////////////////////////////////////////////////////////////////////

//переменные для функций задержек (антидребезга) сенсоров электроклапанов
bool _bounse1S = 1;
bool _bounse1O = 1;
unsigned long _bounse1P = 0UL;
bool _bounse2S = 1;
bool _bounse2O = 1;
unsigned long _bounse2P = 0UL;
/////////////////////////////////////////////////////////////////////////////////////

//переменные для управления RGB
byte bright = 100; // яркость, от 0 до 100 (можно повесить на второй потенциометр при желании)
byte R, G, B;

void setup() {          //конфигурация портов (вход или выход)
  pinMode(SENSOR1_PIN, INPUT_PULLUP);   //подтягиваем вход к плюсу через внутренний резистор 20к
  pinMode(FLAP1_PIN, OUTPUT);
  pinMode(SENSOR2_PIN, INPUT_PULLUP);
  pinMode(FLAP2_PIN, OUTPUT);
  pinMode(GERKON_PIN, INPUT_PULLUP);
  pinMode(LAMP_PIN, OUTPUT);
  pinMode(SENSOR_PIN, INPUT);
  pinMode(FAN_BUTTON_PIN, INPUT_PULLUP);
  pinMode(FAN_PIN, OUTPUT);
  pinMode(R_PIN, OUTPUT);
  pinMode(G_PIN, OUTPUT);
  pinMode(B_PIN, OUTPUT);
  pinMode(RGB_POWER, OUTPUT);
  pinMode(13, OUTPUT);
}

//управление светодиодной лентой RGB (взято с сайта http://alexgyver.ru/arduino-algorithms/)
void rgbLed () {
  int colorPot = analogRead(0); // получаем значение с потенциометра (0 - 1023)
  // разбиваем диапазон 0 - 1023 на участки, и играемся с цветом согласно текущему значению
  if (colorPot >= 10) {  //если значение больше 10, вкл. БП, иначе выкл.
    digitalWrite(RGB_POWER, HIGH);
  } else {
    digitalWrite(RGB_POWER, LOW);
  }
  if (colorPot <= 10) {
    R = 0;
    G = 0;
    B = 0;
  } else if (colorPot > 10 && colorPot <= 20) {
    byte k = map(colorPot, 10, 20, 0, 255);
    R = 255;
    G = 255;
    B = 255;
  } else if (colorPot > 20 /*&& colorPot <= 145*/) {
    byte k = map(colorPot, /*10, 145*/20, 1023, 0, 255);
    R = 255 - k;
    G = 255 - k;
    B = 255 - k;
  } /*else if (colorPot > 145 && colorPot <= 290) {
    byte k = map(colorPot, 145, 290, 0, 255);
    R = 0;
    G = 0;
    B = k;
  } else if (colorPot > 290 && colorPot <= 435) {
    byte k = map(colorPot, 290, 435, 0, 255);
    R = 0;
    G = k;
    B = 255;
  } else if (colorPot > 435 && colorPot <= 580) {
    byte k = map(colorPot, 435, 580, 0, 255);
    R = k;
    G = 255;
    B = 255;
  } else if (colorPot > 581 && colorPot <= 725) {
    byte k = map(colorPot, 581, 725, 0, 255);
    R = 255 - k;
    G = k;
    B = 0;
  } else if (colorPot > 725 && colorPot <= 870) {
    byte k = map(colorPot, 725, 870, 0, 255);
    R = 0;
    G = 255 - k;
    B = k;
  } else if (colorPot > 870) {
    byte k = map(colorPot, 870, 1023, 0, 255);
    R = k;
    G = 0;
    B = 255 - k;
  }*/
  // подаём ШИМ на светодиод, учитывая яркость
  analogWrite(R_PIN, (bright * R / 100));
  analogWrite(G_PIN, (bright * G / 100));
  analogWrite(B_PIN, (bright * B / 100));
}

//функция вкл/выкл вентилятора
//вентилятор вкл/выкл кнопкой при включенном свете. После выключения света, 
//если вентилятор был включен, он выключится через время FAN_ON_TIME
void fan(bool fanOff) {
  bool reading = !digitalRead(FAN_BUTTON_PIN);
  if (reading != lastFanButtonState) {
    lastDebounceTime = millis() + DEBOUNCE_DELAY;
  }
  if (lastDebounceTime <= millis()) {
    if (reading != fanButtonState) {
      fanButtonState = reading;
      if (!fanButtonState) {
        fanState = !fanState;
      }
    }
  }
  lastFanButtonState = reading;

  if (fanOff && fanState) {  //если свет выключился и вентилятор включен
    fanButtonOffTime = millis() + workTime;  //записываем время выключения света (с опережением millis())
  }
  if (fanButtonOffTime <= millis()) {  //если прошло время FAN_ON_TIME
    fanState = LOW;  //выключить вентилятор
  }
  digitalWrite(FAN_PIN, fanState);
}

//функция антидребезга для геркона
//сформирована в программе FLProg
bool bounseGerkon () {
  bool   _bounceTmpD1 =  digitalRead (GERKON_PIN);
  if (!_bounse3S)
  {
    if (millis() >= (_bounse3P + DEBOUNCE_GERKON))
    {
      _bounse3O =  _bounceTmpD1;
      _bounse3S = 1;
    }
  }
  else
  {
    if ( _bounceTmpD1 != _bounse3O )
    {
      _bounse3S = 0;
      _bounse3P = millis();
    }
  }
  return _bounse3O;
}

//------------------------функция управления освещением, начало---------------------------
/* Логики работы: открыли дверь - включился свет, начался отсчет выдержки. По окончании
  выдержки свет выключается, если при открытой двери есть движение, отсчет выдержки
  обновляется. Если закрыть дверь при включенном свете - начинается отсчет второй вы-
  держки, по истечении которой свет выключится. Если есть движение при закрытой двери
  и включенном свете и при сработке датчика движени три раза в течении DELAY_LAMP_OFF_OPEN, свет не выключится 
  до следующего открывания двери не зависимо будет ещё срабатывать датчик движения или нет.
*/
void lite() {
  if (bounseGerkon () && !gerkon_flag) {   //если геркон разомкнулся (дверь открылась) и до этого был замкнут
    gerkon_flag = HIGH;  //изменение переменной (дверь была открыта)
    lamp = HIGH;  //включить свет
    motionClose = LOW;  //сброс индикатора движения
    doorOpenedTime = millis() + (long)DELAY_LAMP_OFF_OPEN * 1000;  //начало отсчета до выключения света при открытой двери
  }
  if (bounseGerkon () && gerkon_flag && digitalRead(SENSOR_PIN)) {  //если дверь открыта и есть движение
    lamp = HIGH;  //включить свет
    doorOpenedTime = millis() + (long)DELAY_LAMP_OFF_OPEN * 1000;  //обновление отсчета до выключения света при открытой двери
  }
  if (bounseGerkon () && gerkon_flag && doorOpenedTime <= millis()) {  //если дверь открыта и прошло время выдержки
    lamp = LOW;  //выключить свет
  }
  if (!bounseGerkon () && gerkon_flag) {  //если геркон замкнулся (дверь закрылась) и до этого он был разомкнут
    gerkon_flag = LOW;  //изменение переменной (дверь была закрыта)
    doorClosedTime = millis() + (long)DELAY_LAMP_OFF_CLOSE * 1000;  //начало отсчета до выключения света при закрытой двери
    doorClosedDelay = millis() + (long)DELAY_DOOR_CLOSE * 1000;  //начало задержки фиксации движения при закрытой двери
  }
  if (!bounseGerkon () && !gerkon_flag) {  //если дверь закрыта
    if (doorClosedDelay <= millis()) {  //и если прошло время задержки до выключения света
      if (digitalRead(SENSOR_PIN) && !sensor_flag) { //подсчет кол-ва сработок датчика движения при закрытой двери
        sensor_flag = HIGH;                          //для предотвращение ложного включения света до следующего
        motionCount ++;                              //открытия двери
        motionClose = HIGH;                          //
        if (!lamp) {  //если свет выключен
          lamp = HIGH;  //включить свет
          doorOpenedTime = millis() + (long)DELAY_LAMP_OFF_OPEN * 1000; //на время DELAY_LAMP_OFF_OPEN
        }
      }
      if (!digitalRead(SENSOR_PIN) && sensor_flag) {  //если датчик движения деактивировался
        sensor_flag = LOW;  //изменить переменную
      }
      if (motionCount >= 3) {
        motionCount = 3;  //ограничение кол-ва сработок датчика движения при закрытой двери до 3
      }
    }
  }
  //если дверь закрыта, прошло время до выключения света и счетчик сработок меньше трех
  if (!bounseGerkon () && !gerkon_flag && doorOpenedTime <= millis() && motionCount <= 2) {
    lamp = LOW;  //выключить свет
  }
  //если дверь закрыта и движения не было и прошло время до выключения света при закрытой двери
  if (!bounseGerkon () && !gerkon_flag && !motionClose && doorClosedTime <= millis()) {
    lamp = LOW;  //выключить свет
  }
  digitalWrite(LAMP_PIN, lamp);  //передать состояние переменной lamp на пин LAMP_PIN

  if (!lamp) {  //если свет выключен
    motionCount = 0;  //обнулить счетчик сработок датчика движения
  }

  //индикация сработки датчика движения
  //эту индикацию я сделал только для удобства мониторинга сработки датчика движения
  if (digitalRead(SENSOR_PIN)) {                //если сработал датчик движения
    digitalWrite(13, HIGH);    //включить светодиод
  } else {
    if (motionClose) {                               //мигание при сработке при закрытой двери
      if (millis() - previousMillis >= INTERVAL) {   //
        previousMillis = millis();                   //
        if (ledMotionState == LOW) {                 //
          ledMotionState = HIGH;                     //
        } else {                                     //
          ledMotionState = LOW;                      //
        }                                            //
        digitalWrite(13, ledMotionState);            //
      }                                              //
    } else {                 //при деактивации датчика движ., если не было сработки при закрытой двери,
      digitalWrite(13, LOW); //выключить светодиод
    }
  }
}
//------------------------функция управления освещением, конец---------------------------

//функция задержки сработки для 1го электроклапана
//сформирована в программе FLProg
bool bounse1flap () {
  bool   _bounceTmpD1 =  (digitalRead (SENSOR1_PIN));
  if (!_bounse1S)
  {
    if (millis() >= (_bounse1P + DEBOUNCE1_SENSOR))
    {
      _bounse1O =  _bounceTmpD1;
      _bounse1S = 1;
    }
  }
  else
  {
    if ( _bounceTmpD1 != _bounse1O )
    {
      _bounse1S = 0;
      _bounse1P = millis();
    }
  }
  return _bounse1O;
}

//функция задержки сработки для 2го электроклапана
//сформирована в программе FLProg
bool bounse2flap () {
  bool   _bounceTmpD1 =  (digitalRead (SENSOR2_PIN));
  if (!_bounse2S)
  {
    if (millis() >= (_bounse2P + DEBOUNCE2_SENSOR))
    {
      _bounse2O =  _bounceTmpD1;
      _bounse2S = 1;
    }
  }
  else
  {
    if ( _bounceTmpD1 != _bounse2O )
    {
      _bounse2S = 0;
      _bounse2P = millis();
    }
  }
  return _bounse2O;
}

//функция управления 1м краном
void flap1() {
  sensor1 = bounse1flap ();                      //считывание состояние сенсора 1 с задержкой
  if (sensor1 == LOW && lastSensor1 == HIGH) {   //если активен и последнее сост. - неактивен, то ...
    digitalWrite(FLAP1_PIN, HIGH);                //включаем 1й электроклапан
    lastSensor1 = LOW;                           //записываем последнее состояние сенсора 1
    timeSensor1On = millis() + (ON_FLAP1_ON * 1000);       //записываем время сработки сенсора 1 +
  }                                              //"опережаем время" на ON_FLAP1_ON для того,чтобы решить проблему
  //с переполнением millis() т.е. "опережение времени" на ON_FLAP1_ON и ON_FLAP1_OFF
  //(взято с сайта http://alexgyver.ru/arduino-algorithms/ от WakeUp4L1fe)

  if (sensor1 == HIGH && lastSensor1 == LOW) {   //если неактивен и последнее состояние сенсора 1 - активен
    timeSensor1Off = millis() + (ON_FLAP1_OFF * 1000);     //записываем время деактивации сенсора 1 +
    lastSensor1 = HIGH;                          //"опережаем время" на ON_FLAP1_OFF
  }
  if ((timeSensor1On <= millis() && sensor1 == LOW) ||   //если после активации сенсора 1 прошло время ON_FLAP1_ON
      (timeSensor1Off <= millis() && lastSensor1 == HIGH)) { //или если после деактивации сенсора 1 прошло время ON_FLAP1_OFF
    digitalWrite(FLAP1_PIN, LOW);   //то выключить кран
  }
}

//функция управления 2м краном
void flap2() {
  sensor2 = bounse2flap ();
  if (sensor2 == LOW && lastSensor2 == HIGH) {
    digitalWrite(FLAP2_PIN, HIGH);
    lastSensor2 = LOW;
    timeSensor2On = millis() + (ON_FLAP2_ON * 1000);
  }
  if (sensor2 == HIGH && lastSensor2 == LOW) {
    timeSensor2Off = millis() + (ON_FLAP2_OFF * 1000);
    lastSensor2 = HIGH;
  }
  if ((timeSensor2On <= millis() && sensor2 == LOW) ||
      (timeSensor2Off <= millis() && lastSensor2 == HIGH)) {
    digitalWrite(FLAP2_PIN, LOW);
  }
}

//основной цикл программы
void loop() {
  lite();
  fan(lamp);
  flap1();
  flap2();
  rgbLed ();
}

Здравствуйте! Хочу поделиться своими наработками. Я написал программу для управления освещением и вытяжкой в ванной, сделал сенсорное управление кранами на кухне и в ванной, а так же RGB светодиодной лентой для подсветки кухонного гарнитура. Я только начинаю изучать Arduino и программирование так что не судите строго. Может кому то пригодится или знающие люди подскажут может можно как-то оптимизировать код программы.

Логика работы сенсоров кранов: если поднести руки (или любой предмет) вода включится, после того как убрали руки вода выключится через 2 с. Если в зону действия сенсора на долго попал какой-то предмет, например поставили кастрюлю в раковину, вода выключится через 30 с. И включится только после того как предмет будет убран и сенсор будет активирован снова.

Логика управления освещением и вытяжкой: при открытии двери свет включается и начинается выдержка 40 с до выключения света. Если фиксируется движение, начало выдержки обновляется. При закрытии двери начинается выдержка 5 с, при которой не фиксируется движение. Я добавил эту выдержку потому, что иногда при выходе из ванной и закрытии двери срабатывает датчик движения и включается свет, когда в ванной никого нет. Когда защитная выдержка заканчивается, начинается фиксация движения. И если датчик движения сработал три раза до выключения света, свет останется включенным до открытия двери не зависимо будет ли дальнейшее движение или нет. После закрытия двери, если нет движения, свет выключится через 15 с.

Вытяжка включается/выключается шнурком с кнопкой. При выключении света, если вытяжка была включена, начинается отсчет выдержки (я сделал 10 мин) до ее выключения. Включение света во время 10ти минутной выдержки сбрасывает отсчет, он начнется заново после выключения света.

По началу я пробовал другой алгоритм работы освещения. Использовал два ИК сенсора и считал кол-во входящих/выходящих человек. Но так как сенсоры расположены на расстоянии 6 см (ширина дверной коробки) были ложные срабатывания. Может быть я еще не удачно выбрал высоту установки датчиков, все люди разного роста, еще датчик повторно срабатывал от заплетенных волос. А маленький ребенок вообще не мог выключить свет. Так что пришлось отказаться от такого управления светом.

Управление RGB лентой и её блоком питания я сделал с помощью переменного резистора. Программный код, с некоторыми переделками, я взял с сайта http://alexgyver.ru/arduino-algorithms/

В своём проекте я использовал Arduino Nano.

 

Hamster
Offline
Зарегистрирован: 12.07.2015

Rex пишет:

... Но так как сенсоры расположены на расстоянии 6 см (ширина дверной коробки) были ложные срабатывания.

Приветствую!

Такая же ситуация была - удалось решить переходом на прерывания (см. выше мои сообщения). Сейчас расстояние между ИК датчиками порядка ~25 мм...

Вопрос к вам - что за краны и что за клапаны?

Буду благодарен за ссылку

Rex
Offline
Зарегистрирован: 16.02.2018

Здравствуйте!
Я сделал сенсорное управление обычными смесителями на кухне и в ванной. Ручкой смесителя регулируется напор воды. Температура воды регулируется с помощью термостатического смесителя, его выход я подключил вместо горячей воды к смесителю на раковине.
Подача воды осуществляется с помощью клапана на подобии как в стиральной машине. Только я нашел на 12 В и с резьбой 1/2.
Включение клапана с помощью ИК сенсора.

Клапана такие:
https://s.click.aliexpress.com/e/cMCGLjj4

Термостатические смесители такие:
https://s.click.aliexpress.com/e/DJEFoYE

Сенсоры:
https://s.click.aliexpress.com/e/fRZL8dU

Hamster
Offline
Зарегистрирован: 12.07.2015

Rex пишет:
Клапана такие: https://s.click.aliexpress.com/e/cMCGLjj4 Термостатические смесители такие: https://s.click.aliexpress.com/e/DJEFoYE

Спасибо! Возьму на заметку.

Еще вопрос - на сколько громко срабатывают клапана и каково качество их изготовления?

Ну и фотки в студию! ))) В частности интересно было бы увидеть как вы примостили сенсоры вблизи крана ;)

Rex
Offline
Зарегистрирован: 16.02.2018

Hamster пишет:

Rex пишет:
Клапана такие: https://s.click.aliexpress.com/e/cMCGLjj4 Термостатические смесители такие: https://s.click.aliexpress.com/e/DJEFoYE

Спасибо! Возьму на заметку.

Еще вопрос - на сколько громко срабатывают клапана и каково качество их изготовления?

Ну и фотки в студию! ))) В частности интересно было бы увидеть как вы примостили сенсоры вблизи крана ;)

Звук сработки клапанов такой же как на стиральной машине. Особо на него не обращаю внимания. Качество хорошее, работают уже около 3х месяцев. Термостатические смесители работают с 2015 года уже на второй квартире.

Фотки выложу позже. Сенсор я разместил в боковом сливном отверстии раковины. Но в новой квартире думаю перенести ИК диод и TSOP в корпус смесителя, чтобы не было срабатываний от противоположной стороны раковины. У меня стальная раковина и при настройке сенсора на сработку от рук в ценре раковины, и когда убираешь руки датчик начинает срабатывать отражаясь от противоположной стенки раковины. Поэтому пришлось уменьшить дальность до пропадания ложных срабатываний. Еще я заменил резистор для настройки дальности на многооборотный для большей точности.

Rex
Offline
Зарегистрирован: 16.02.2018

Обещанные фотографии:

Термостатический смеситель и клапан.

Термостатический смеситель и клапан.

ИК сенсор с внутренней стороны раковины:

ИК сенсор с наружи:

Геркон в дверном косяке:

PIR и вентилятор. На время опытов смонтировал так. В дальнейшем думаю смонтировать PIR в такой же светильник в какие смонтированы лампы освещения.

Hamster
Offline
Зарегистрирован: 12.07.2015

Кузяво! )

У меня два вопроса:

1. ИК сенсор как то защищен от влаги? если нет - то как долго он уже в работе?

2. Про геркон. Как вы надрессировали домашних, чтобы они дверь постоянно закрывали? ))) Судя по фото она к тому еще и откатная?

По сравнению с готовыми решениями для смесителей с ИК (от ~8к руб) схема вполне годная, только мне кажется надо что-то с ИК датчиком придумать...

Rex
Offline
Зарегистрирован: 16.02.2018

1. В сливное отверстие вставлен обрезок маркера и загерметизирован. С одной стороны приклеен прозрачный пластик. Так что на сенсор влага не попадает. В работе около полугода.

2. Дверь обычная. На фото видна дверь шкафа купе в ванной. Свет выключается и при открытой двери, у меня через 40 сек, если PIR не срабатывает.

В будущем я буду монтировать ИК сенсор в смеситель. Сейчас пока все находится в режиме тестов.

Hamster
Offline
Зарегистрирован: 12.07.2015

Понятно. Спасибо!

Rex пишет:

В будущем я буду монтировать ИК сенсор в смеситель

Интересно будет посмотреть что получилось. Удачи вам!

Hamster
Offline
Зарегистрирован: 12.07.2015

avton пишет:

http://ru.aliexpress.com/item/1pcs-IR-Infrared-Obstacle-Avoidance-Sensor...

Излучающий светодиод выпаивается и ставится напротив в дверном проеме,надо 2 таких датчика 

Доброго времени суток!

Подскажите, если кто владеет информацией, не смог сам найти, какова длина волны и мощность излучающего ИК светодиода на подобных датчиках?

В широком дверном проёме не добивает до приёмника ((

Хочу попробовать поставить помощнее ИК светодиод, типа такого:

https://ru.aliexpress.com/item/5-3/32953182050.html?spm=a2g0s.13010208.9...

 

nzl
Offline
Зарегистрирован: 05.12.2015

Hamster пишет:

avton пишет:

http://ru.aliexpress.com/item/1pcs-IR-Infrared-Obstacle-Avoidance-Sensor...

Излучающий светодиод выпаивается и ставится напротив в дверном проеме,надо 2 таких датчика 

Доброго времени суток!

Подскажите, если кто владеет информацией, не смог сам найти, какова длина волны и мощность излучающего ИК светодиода на подобных датчиках?

В широком дверном проёме не добивает до приёмника ((

Хочу попробовать поставить помощнее ИК светодиод, типа такого:

https://ru.aliexpress.com/item/5-3/32953182050.html?spm=a2g0s.13010208.9...

 

У меня проем в 100 см пробивает без проблем, светодиод самособой выпаян и помещен напротив

Hamster
Offline
Зарегистрирован: 12.07.2015

nzl пишет:

У меня проем в 100 см пробивает без проблем, светодиод самособой выпаян и помещен напротив

в моем случае проем 120 см. грешу на датчики, в этот раз попались какие то странные - в неразобранном виде на максимуме регулятора срабатывают на препятствие только в пределах 10 см.

я думаю стоит воздержаться от покупок данного устройства вот у этого продавца:

https://ru.aliexpress.com/item/Free-shipping-IR-Infrared-Obstacle-Avoida...

Hamster
Offline
Зарегистрирован: 12.07.2015

Всех приветствую! Докладаю.

Приобретенные ИК светодиоды повышенной мощности (3W 700mA 940nm 60degree) вот здесь:

https://www.aliexpress.com/store/product/5-PCS-3W-Infrared-IR-High-Power...

действительно улучшают срабатывание ИК барьера. Стабильного срабатывания удалось достичь на 100 см. Далее уже требуется более точная настройка пары друг на друга. Точность срабатывания уменьшается по мере все более частого попадания солнечного света в помещение. Придется скорее всего переходить на лазер типа VL53L0XV2.

Brewster
Offline
Зарегистрирован: 26.11.2017

«Вы все ещё кипятите?» Безо всяких ИК барьеров ванная работает на ПИРах, туалет - ПИР и ИК дальномер (сверху вниз). Год работы без влезания в алгоритм по санузлу. Полет нормальный. Минимум вторжения в интерьер. 

kinguf
Offline
Зарегистрирован: 21.04.2019

Мой вариант работы ИК датчиков в дверном проеме. Взял за основу один из кодов этой темы и переделал под прерывания дуни. На макете проверил все отрабатывает, в реальных условиях дверных не смотрел.

// цель: считать количество людей в комнате
// материалы: датчик приближения ИК 2шт, блок реле, arduino pro mini

 bool IR1_state_old = 0;          // предыдущее значение первого датчика
 bool IR2_state_old = 0;          // предыдущее значение второго датчика
 bool IR1_state_new = 0;          // новое значение первого датчика
 bool IR2_state_new = 0;          // новое значение второго датчика
 bool flag = 0;                   // флаг изменения состояния одного из датчиков
 int Human_Counter_New = 0;       // переменная для учета количества людей
 int LampRELE = 7;                // на этот вывод подключено реле на лампу
 volatile unsigned long time_1;   // таймер 1 для учета зоны нечувтвительности
 volatile unsigned long time_2;   // таймер 2 для учета зоны нечувтвительности
 volatile int zad = 40;           // устранение дребезга, зона нечувствительности после последнего срабатывания

void setup() {
  pinMode(LampRELE, OUTPUT); 
  attachInterrupt(0, IR1_state, CHANGE);    // вызов функции IR1_state при изменении пина D2
  attachInterrupt(1, IR2_state, CHANGE);    // вызов функции IR2_state при изменении пина D3
  Serial.begin(9600);                       // инициализация порта
  Serial.println("Порт готов");             // сообщение о готовности в порт
}

void loop() {
 
  if (flag) {
    if (Human_Counter_New < 0){Human_Counter_New = 0;}
    Serial.println(Human_Counter_New);
 //   Serial.print("IR1new=");Serial.print(IR1_state_new);Serial.print(" "); 
 //   Serial.print("IR2new=");Serial.print(IR2_state_new);Serial.print(" ");
 //   Serial.print("IR1old=");Serial.print(IR1_state_old);Serial.print(" "); 
 //   Serial.print("IR2old=");Serial.println(IR2_state_old);
    IR1_state_old = IR1_state_new;
    IR2_state_old = IR2_state_new;
    flag = 0;
    }
    if ( Human_Counter_New > 0) {digitalWrite(LampRELE,HIGH);}
                           else {digitalWrite(LampRELE,LOW); }
  }

void IR1_state() { 
  if ((millis()-time_1)>zad)  { 
      IR1_state_new = !IR1_state_new;
      if (!IR1_state_old && !IR2_state_old && IR1_state_new && !IR2_state_new){Human_Counter_New++; }
        else{
          if (IR1_state_old && !IR2_state_old && !IR1_state_new && !IR2_state_new){Human_Counter_New--; }
            }
     flag = 1;
  }
  time_1 = millis();
}


void IR2_state() {
    if ((millis()-time_2)>zad)  { 
      IR2_state_new = !IR2_state_new;
      if (!IR1_state_old && !IR2_state_old && IR1_state_new && !IR2_state_new){Human_Counter_New++; }
        else{
          if (IR1_state_old && !IR2_state_old && !IR1_state_new && !IR2_state_new){Human_Counter_New--; }
            }
       flag = 1;
  }
  time_2 = millis();    
}

 

Hamster
Offline
Зарегистрирован: 12.07.2015

Brewster пишет:

«Вы все ещё кипятите?»

мы кипятим, ага ) а ещё жжем )) а вы свет выключаете, если в ванной помедитировать? )))

Brewster
Offline
Зарегистрирован: 26.11.2017

Так сам через пять минут выключится, если неподвижно медитировать. :)

Hamster
Offline
Зарегистрирован: 12.07.2015

Brewster пишет:

Так сам через пять минут выключится, если неподвижно медитировать. :)

 

)) вот именно поэтому то ИК барьеры и ставим (а кто-то и лазерные)  ;)

KindMan
Offline
Зарегистрирован: 19.12.2018

Brewster пишет:

Так сам через пять минут выключится, если неподвижно медитировать. :)

А я наоборот люблю, с утра, не проснувшись, сидишь, а свет выключился. Если надо, шевельнулся и снова горит. Один датчик движения на потолке. А мучиться с этими барьерами и прочим, лишняя фигня, ИМХО

Rex
Offline
Зарегистрирован: 16.02.2018

Я изменил программу. Теперь у меня светом в санузле управляют геркон и PIR. С помощью задержек я настроил программу так, что свет не выключится при закрытой двери даже если нет движения. Еще добавил сторожевой таймер.

#include <MsTimer2.h>
#include <avr/wdt.h>

#define SENSOR1_PIN 2                   //вход управления 1м электроклапаном
#define SENSOR2_PIN 3                   //вход управления 2м электроклапаном
#define FLAP1_PIN 4                     //выход управления 1м электроклапаном
#define FLAP2_PIN 5                     //выход управления 2м электроклапаном
#define GERKON_PIN 6                    //вход геркон
#define SENSOR_PIN 7                    //вход датчик движения
#define LAMP_PIN 8                      //выход управления освещением
#define R_PIN 9                         //выход управления красным цветом
#define G_PIN 10                        //выход управления зеленым цветом
#define B_PIN 11                        //выход управления голубым цветом
#define RGB_POWER 12                    //выход вкл/выкл БП для RGB
#define FAN_BUTTON_PIN 15               //вход управления вентилятором (кнопка)
#define FAN_PIN 16                      //выход управления вентилятором
#define DEBOUNCE_DELAY 100              //время антидребезга кнопки вентилятора в мс
#define FAN_ON_TIME 600000              //время работы вентилятора после выкл. света, мс
#define ON_FLAP1_ON 30000               //время работы 1го клапана при активации сенсора, мс
#define ON_FLAP1_OFF 2000               //время работы 1го клапана при деактивации сенсора, мс
#define ON_FLAP2_ON 30000               //время работы 2го клапана при активации сенсора, мс
#define ON_FLAP2_OFF 2000               //время работы 2го клапана при деактивации сенсора, мс
#define DEBOUNCE1_SENSOR 300            //задержка сработки для 1го электроклапана, мс
#define DEBOUNCE2_SENSOR 300            //задержка сработки для 2го электроклапана, мс
#define DELAY_LAMP_OFF_OPEN 60000       //задержка выключения света при открытой двери, мс
#define DELAY_LAMP_OFF_OPENED 15000     //задержка выключения света после открытия двери, мс
#define DELAY_LAMP_OFF_CLOSE 10000      //задержка выключения света после закрытия двери, мс
#define DELAY_MOTION_OPENED 10000       //задержка регистрации движения после открытия двери, мс
#define DELAY_MOTION_CLOSED 5000        //задержка регистрации движения после закрытия двери, мс
#define DELAY_MOTION_NOBODY 25000       //время, после которого, свет не включится до след. открытия двери, мс
#define DEBOUNCE_GERKON 80              //время антидребезга геркона в мс
#define INTERVAL 250                    //интервал мигания светодиода индик. сработки датчика движения, мс


//переменные для управления кранами
unsigned long int timeSensor1On, timeSensor1Off, timeSensor2On, timeSensor2Off;
bool flap1On = false;      //переменная для хранения состояния 1го электроклапана
bool flap2On = false;      //переменная для хранения состояния 2го электроклапана
bool sensor1 = LOW;        //переменная для хранения состояния сенсора 1го электроклапана
bool sensor2 = LOW;        //переменная для хранения состояния сенсора 2го электроклапана
bool lastSensor1 = LOW;   //переменная для хранения последнего состояния сенсора 1го электроклапана
bool lastSensor2 = LOW;   //переменная для хранения последнего состояния сенсора 2го электроклапана
//////////////////////////////////////////////////////////////////////////////////

//переменные для управления освещением
bool lamp;           //переменная для хранения состояния освещения (вкл/выкл)
bool gerkon_flag;    //вспомогательная переменная для хранения состояния сработки геркона
bool noBody;         //отсутствие людей в ванной
bool motionClose;    //переменная для индикации движения при закрытой двери
bool motionOpen;     //переменная для индикации движения при открытой двери
unsigned long lampOffTimeClose, lampOffTimeOpened, delayMotionOpened, delayMotionClosed, doorClosedNobody, lampOffTimeOpen; //переменные для хранения времени момента закрытия и открытия двери
//переменные для функции светодиодной индикации сработки датчика движения
unsigned long int previousMillis = 0;
bool ledMotionState;
////////////////////////////////////////////////////////////////////////////////////

//переменные для управления вентилятором
bool fanState;
bool fanButtonState;
bool lastFanButtonState;
unsigned long int lastDebounceTime = 0, fanButtonOffTime;
/////////////////////////////////////////////////////////////////////////////////////

//переменные для функции задержки (антидребезга) геркона
bool _bounse3S = 1;
bool _bounse3O = 1;
unsigned long _bounse3P = 0UL;
/////////////////////////////////////////////////////////////////////////////////////

//переменные для функций задержек (антидребезга) сенсоров электроклапанов
bool _bounse1S = 1;
bool _bounse1O = 1;
unsigned long _bounse1P = 0UL;
bool _bounse2S = 1;
bool _bounse2O = 1;
unsigned long _bounse2P = 0UL;
/////////////////////////////////////////////////////////////////////////////////////

//переменные для управления RGB
byte bright = 100; // яркость, от 0 до 100 (можно повесить на второй потенциометр при желании)
byte R, G, B;

void setup() {          //конфигурация портов (вход или выход)
  pinMode(SENSOR1_PIN, INPUT_PULLUP);   //подтягиваем вход к плюсу через внутренний резистор 20к
  pinMode(FLAP1_PIN, OUTPUT);
  pinMode(SENSOR2_PIN, INPUT_PULLUP);
  pinMode(FLAP2_PIN, OUTPUT);
  pinMode(GERKON_PIN, INPUT_PULLUP);
  pinMode(LAMP_PIN, OUTPUT);
  pinMode(SENSOR_PIN, INPUT);
  pinMode(FAN_BUTTON_PIN, INPUT_PULLUP);
  pinMode(FAN_PIN, OUTPUT);
  pinMode(R_PIN, OUTPUT);
  pinMode(G_PIN, OUTPUT);
  //pinMode(B_PIN, OUTPUT);
  pinMode(RGB_POWER, OUTPUT);
  pinMode(13, OUTPUT);
  
  MsTimer2::set(2, timerInterrupt); // период прерывания по таймеру 2 мс
  MsTimer2::start();                // разрешаем прерывание по таймеру

 // Serial.begin(9600); // инициализируем порт, скорость 9600
  wdt_enable(WDTO_15MS); // разрешаем сторожевой таймер, тайм-аутом 15 мс
}

//управление светодиодной лентой RGB (взято с сайта http://alexgyver.ru/arduino-algorithms/)
void rgbLed () {
  int colorPot = analogRead(0); // получаем значение с потенциометра (0 - 1023)
  // разбиваем диапазон 0 - 1023 на участки, и играемся с цветом согласно текущему значению
  /*if (colorPot >= 10) {  //если значение больше 10, вкл. БП, иначе выкл.
    digitalWrite(RGB_POWER, HIGH);
    } else {
    digitalWrite(RGB_POWER, LOW);
    }*/
  if (colorPot <= 10 || colorPot >= 1005) {  //если значение меньше 10 или больше 1005, выкл. БП, иначе вкл.
    digitalWrite(RGB_POWER, LOW);
  } else {
    digitalWrite(RGB_POWER, HIGH);
  }
  if (colorPot <= 10) {
    R = 0;
    G = 0;
    B = 0;
  } else if (colorPot > 11 && colorPot <= 29) {
    byte k = map(colorPot, 10, 20, 0, 255);
    R = 255;
    G = 255;
    B = 255;
  } else if (colorPot > 30 /*&& colorPot <= 145*/) {
    byte k = map(colorPot, /*10, 145*/30, 1024, 0, 255);
    R = 255 - k;
    G = 255 - k;
    B = 255 - k;
  } /*else if (colorPot > 145 && colorPot <= 290) {
    byte k = map(colorPot, 145, 290, 0, 255);
    R = 0;
    G = 0;
    B = k;
  } else if (colorPot > 290 && colorPot <= 435) {
    byte k = map(colorPot, 290, 435, 0, 255);
    R = 0;
    G = k;
    B = 255;
  } else if (colorPot > 435 && colorPot <= 580) {
    byte k = map(colorPot, 435, 580, 0, 255);
    R = k;
    G = 255;
    B = 255;
  } else if (colorPot > 581 && colorPot <= 725) {
    byte k = map(colorPot, 581, 725, 0, 255);
    R = 255 - k;
    G = k;
    B = 0;
  } else if (colorPot > 725 && colorPot <= 870) {
    byte k = map(colorPot, 725, 870, 0, 255);
    R = 0;
    G = 255 - k;
    B = k;
  } else if (colorPot > 870) {
    byte k = map(colorPot, 870, 1023, 0, 255);
    R = k;
    G = 0;
    B = 255 - k;
  }*/
  // подаём ШИМ на светодиод, учитывая яркость
  analogWrite(R_PIN, (bright * R / 100));
  analogWrite(G_PIN, (bright * G / 100));
  //analogWrite(B_PIN, (bright * B / 100));
}

//функция вкл/выкл вентилятора
//вентилятор вкл/выкл кнопкой при включенном свете. После выключения света,
//если вентилятор был включен, он выключится через время FAN_ON_TIME
//если свет включится и выключится еще раз при работающем вентиляторе,
//отсчет выдержки начнется с начала
void fan(bool fanOff) {
  bool reading = !digitalRead(FAN_BUTTON_PIN);
  if (reading != lastFanButtonState) {
    lastDebounceTime = millis() + DEBOUNCE_DELAY;
  }
  if (lastDebounceTime <= millis()) {
    if (reading != fanButtonState) {
      fanButtonState = reading;
      if (!fanButtonState) {
        fanState = !fanState;
      }
    }
  }
  lastFanButtonState = reading;

  if (fanOff && fanState) {  //если свет выключился и вентилятор включен
    fanButtonOffTime = millis() + FAN_ON_TIME;  //записываем время выключения света (с опережением millis())
  }
  if (fanButtonOffTime <= millis()) {  //если прошло время FAN_ON_TIME
    fanState = LOW;  //выключить вентилятор
  }
  digitalWrite(FAN_PIN, fanState);
}

//функция антидребезга для геркона
//сформирована в программе FLProg
bool bounseGerkon () {
  bool   _bounceTmpD1 =  digitalRead (GERKON_PIN);
  if (!_bounse3S)
  {
    if (millis() >= (_bounse3P + DEBOUNCE_GERKON))
    {
      _bounse3O =  _bounceTmpD1;
      _bounse3S = 1;
    }
  }
  else
  {
    if ( _bounceTmpD1 != _bounse3O )
    {
      _bounse3S = 0;
      _bounse3P = millis();
    }
  }
  return _bounse3O;
}

//------------------------функция управления освещением, начало---------------------------
/* Логики работы: открыли дверь - включился свет, начался отсчет выдержки 15 сек. По окончании
  выдержки свет выключается, если при открытой двери есть движение (после задержки 10 сек),
  начнется выдержка 1 мин. до выключения света. 
  Если закрыть дверь при включенном свете - начинается отсчет второй вы-
  держки 10 сек, по истечении которой свет выключится. Если при закрытой двери есть движение
  между интервалами DELAY_LAMP_OFF_CLOSE и DELAY_MOTION_NOBODY, свет не выключится
  до следующего открывания двери не зависимо будет ещё срабатывать датчик движения или нет.
  Если при закрытой двери не было движения в течении DELAY_MOTION_NOBODY, свет не
  включится до следующего открывания двери.
*/
void lite() {
  if (bounseGerkon () && !gerkon_flag) {   //если геркон разомкнулся (дверь открылась) и до этого был замкнут
    gerkon_flag = HIGH;  //изменение переменной (дверь была открыта)
    if (!lamp) {  //если свет выключен
      lamp = HIGH;  //включить свет
    }
    noBody = LOW;  //сброс флага отсутствие людей в ванной
    motionClose = LOW;  //сброс индикатора движения
    delayMotionOpened = millis() + DELAY_MOTION_OPENED;  //начало задержки фиксации движения
    lampOffTimeOpened = millis() + DELAY_LAMP_OFF_OPENED;  //обновление отсчета до выключения света после открывания двери
  }
  if (bounseGerkon () && gerkon_flag) {  //если дверь открыта
    if (delayMotionOpened <= millis()) {  //и если прошло время задержки фиксации движения
      if (digitalRead(SENSOR_PIN)) { //и есть движение
        lampOffTimeOpen = millis() + DELAY_LAMP_OFF_OPEN;  //обновление отсчета до выключения света при открытой двери
        motionOpen = HIGH;  //флаг есть движение
        if (!lamp) {  //если свет выключен
          lamp = HIGH;  //включить свет
        }
      }
    }
  }
  //если дверь открыта и прошло время выдержки и не было движения
  if (bounseGerkon () && gerkon_flag && lampOffTimeOpened <= millis() && !motionOpen) {
    lamp = LOW;  //выключить свет
  }
  //если дверь открыта и прошло время выдержки после движения
  if (bounseGerkon () && gerkon_flag && lampOffTimeOpen <= millis() && motionOpen) {
    lamp = LOW;  //выключить свет
  }
  if (!bounseGerkon () && gerkon_flag) {  //если геркон замкнулся (дверь закрылась) и до этого он был разомкнут
    motionOpen = LOW;
    gerkon_flag = LOW;  //изменение переменной (дверь была закрыта)
    lampOffTimeClose = millis() + DELAY_LAMP_OFF_CLOSE;  //начало отсчета до выключения света при закрытой двери
    delayMotionClosed = millis() + DELAY_MOTION_CLOSED;  //начало задержки фиксации движения
    doorClosedNobody = millis() + DELAY_MOTION_NOBODY;
  }
  if (!bounseGerkon () && !gerkon_flag) {  //если дверь закрыта
    if (delayMotionClosed <= millis()) {  //и если прошло время задержки фиксации движения при закрытой двери
      if (digitalRead(SENSOR_PIN) && !noBody) { //если есть движение при закрытой двери
        motionClose = HIGH;                     //фиксация движения
        if (!lamp) {  //если свет выключен
          lamp = HIGH;  //включить свет
        }
      }
    }
  }
  //если дверь закрыта и движения не было и прошло время до выключения света при закрытой двери
  if (!bounseGerkon () && !gerkon_flag && !motionClose && lampOffTimeClose <= millis()) {
    lamp = LOW;  //выключить свет
  }
  //если дверь закрыта, прошло время до выключения света и не было движения
  if (!bounseGerkon () && !gerkon_flag && !motionClose && doorClosedNobody <= millis()) {
    noBody = HIGH;  //активировать флаг - никого нет
  }
  digitalWrite(LAMP_PIN, lamp);  //передать состояние переменной lamp на пин LAMP_PIN

  //индикация сработки датчика движения
  //эту индикацию я сделал только для удобства мониторинга сработки датчика движения
  if (digitalRead(SENSOR_PIN)) {                //если сработал датчик движения
    digitalWrite(13, HIGH);    //включить светодиод
  } else {
    /*if (motionClose) {                               //мигание при сработке при закрытой двери
      if (millis() - previousMillis >= INTERVAL) {   //
        previousMillis = millis();                   //
        if (ledMotionState == LOW) {                 //
          ledMotionState = HIGH;                     //
        } else {                                     //
          ledMotionState = LOW;                      //
        }                                            //
        digitalWrite(13, ledMotionState);            //
      }                                              //
      } else {*/                 //при деактивации датчика движ., если не было сработки при закрытой двери,
    digitalWrite(13, LOW); //выключить светодиод
  }
  //}
}
//------------------------функция управления освещением, конец---------------------------

//функция задержки сработки для 1го электроклапана
//сформирована в программе FLProg
bool bounse1flap () {
  bool   _bounceTmpD1 =  (digitalRead (SENSOR1_PIN));
  if (!_bounse1S)
  {
    if (millis() >= (_bounse1P + DEBOUNCE1_SENSOR))
    {
      _bounse1O =  _bounceTmpD1;
      _bounse1S = 1;
    }
  }
  else
  {
    if ( _bounceTmpD1 != _bounse1O )
    {
      _bounse1S = 0;
      _bounse1P = millis();
    }
  }
  return _bounse1O;
}

//функция задержки сработки для 2го электроклапана
//сформирована в программе FLProg
bool bounse2flap () {
  bool   _bounceTmpD1 =  (digitalRead (SENSOR2_PIN));
  if (!_bounse2S)
  {
    if (millis() >= (_bounse2P + DEBOUNCE2_SENSOR))
    {
      _bounse2O =  _bounceTmpD1;
      _bounse2S = 1;
    }
  }
  else
  {
    if ( _bounceTmpD1 != _bounse2O )
    {
      _bounse2S = 0;
      _bounse2P = millis();
    }
  }
  return _bounse2O;
}

//функция управления 1м краном
void flap1() {
  sensor1 = bounse1flap ();                      //считывание состояние сенсора 1 с задержкой
  if (sensor1 == LOW && lastSensor1 == LOW) {   //если активен и последнее сост. - неактивен, то ...
    digitalWrite(FLAP1_PIN, HIGH);                //включаем 1й электроклапан
    lastSensor1 = HIGH;                           //записываем последнее состояние сенсора 1
    timeSensor1On = millis() + ON_FLAP1_ON;       //записываем время сработки сенсора 1 +
  }                                              //"опережаем время" на ON_FLAP1_ON для того,чтобы решить проблему
  //с переполнением millis() т.е. "опережение времени" на ON_FLAP1_ON и ON_FLAP1_OFF
  //(взято с сайта http://alexgyver.ru/arduino-algorithms/ от WakeUp4L1fe)

  if (sensor1 == HIGH && lastSensor1 == HIGH) {   //если неактивен и последнее состояние сенсора 1 - активен
    timeSensor1Off = millis() + ON_FLAP1_OFF;     //записываем время деактивации сенсора 1 +
    lastSensor1 = LOW;                          //"опережаем время" на ON_FLAP1_OFF
  }
  if ((timeSensor1On <= millis() && sensor1 == LOW) ||   //если после активации сенсора 1 прошло время ON_FLAP1_ON
      (timeSensor1Off <= millis() && lastSensor1 == LOW)) { //или если после деактивации сенсора 1 прошло время ON_FLAP1_OFF
    digitalWrite(FLAP1_PIN, LOW);   //то выключить кран
  }
}

//функция управления 2м краном
void flap2() {
  sensor2 = bounse2flap ();
  if (sensor2 == LOW && lastSensor2 == LOW) {
    digitalWrite(FLAP2_PIN, HIGH);
    lastSensor2 = HIGH;
    timeSensor2On = millis() + ON_FLAP2_ON;
  }
  if (sensor2 == HIGH && lastSensor2 == HIGH) {
    timeSensor2Off = millis() + ON_FLAP2_OFF;
    lastSensor2 = LOW;
  }
  if ((timeSensor2On <= millis() && sensor2 == LOW) ||
      (timeSensor2Off <= millis() && lastSensor2 == LOW)) {
    digitalWrite(FLAP2_PIN, LOW);
  }
}

//основной цикл программы
void loop() {
  lite();
  fan(lamp);
  flap1();
  flap2();
  rgbLed ();
}

// ---------------------------------------------------обработчик прерывания, 2 мс
void  timerInterrupt() {
  wdt_reset();  // сброс сторожевого таймера
}

 

sstrob
Offline
Зарегистрирован: 21.10.2018

Добрый день. Пытаюсь освоить тему.

      IR1_state_new = !IR1_state_new;

      if (!IR1_state_old && !IR2_state_old && IR1_state_new && !IR2_state_new){Human_Counter_New++; }

        else{

          if (IR1_state_old && !IR2_state_old && !IR1_state_new && !IR2_state_new){Human_Counter_New--; }

            }

     flag = 1;

Вот у нас человек входит, те срабатывает сначала IR1 и потом  IR2. Объясните пожалуйста поэтапно как это будет по скетчу.

 

sstrob
Offline
Зарегистрирован: 21.10.2018

Это был вопрос по скетчу из сообщения #568   kinguf