количество человек или время срабатывания двух датчиков

igorcds
Offline
Зарегистрирован: 03.12.2013

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

Извеняюсь за старую тему... гуглил, чтото ничего путящего не нашел..

Имеется два датчика - PIR Sensor HC-SR501 и ультрасоник HC-SR04. Пытался делать включение света по срабатыванию этих датчиков. По отдельности все работает, конечно есть свои минусы для обеих датчиков(сонар могу установить только в дверной проем и срабатывание только на пересечение, установить  напротив дверей и измерять приближение или удаление от сонара не имею возможности), пир сенсор работает, но когда к примеру находишся к нему спиной и двигаются только руки(клавиатура к примеру) пир уже не срабатывает и свет отключается...

хочу поставить и ультрасоник и PIR сенсор, подсчет количества людей - i=i+1 и i=i-1, соответственно - если i>0  свет горит.

На вход человек сначала пересекает сонар, а потом попадает в зону действия PIR, на выход соответственно наоборот. Как програмно просчитать время срабатывание этих датчиков? нашел код котрый может подойти под мои нужды. Человек делал под измерение скорости пули :)

/*Хронометр
 Формат вывода: например 56,7
 соответственно не может измерять больше 100м/с
	*/
	 
	volatile unsigned long Time1=0;        //Время срабатывания первого датчика
	volatile unsigned long Time2=0;        //Время срабатывания второго
	long value = 0;                        //время пролета пули между датчиками
	boolean flag=false;
	void setup(){
	  Serial.begin(9600);
	  attachInterrupt(0, Start, RISING);   //Прерывание по нарастающему фронту на D0
	  attachInterrupt(1, End, RISING);     //Прерывание по нарастающему фронту на D1
	}
	 
	void loop(){
	  if (flag==true){
	    value = (Time2-Time1);             //вычисляем задержку
	    value = 7000000/value;             //вычисляем скорость для расстояния между датчиками 5см
	     
	    Serial.print(Time2-Time1);
	    Serial.print("      ");
	    Serial.print(value/10);
	    Serial.print(",");
	    Serial.println(value%10);
	    delay(1000);
	    flag=false;
	  }
	}
	 
        void Start(){
	  Time1=micros();
	}
	void End(){
	  Time2=micros();
	  flag=true;
	}

ветка этого форума вот http://arduino.ru/forum/proekty/khronograf-izmeritel-skorosti-puli-ot-pr....

Страшные слова - прерывания...... и человек там указывал, что два датчика подключены к выводам 2и3, а в коде не понятно- где подключение...

Подскажите пожалуйсто как измерить время срабатывания сонара и pir когда они работают в паре?

спасибо

 

igorcds
Offline
Зарегистрирован: 03.12.2013

имел ввиду - как просчитать, какой датчик первый сработал?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

да в коде неточность в комментариях. там надо не D0 а 0 прерывание. но не суть D2 и D3 подключение

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

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

вешаете оба дачтика на прерывания и обрабатываете

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

ну и основная программа анализирует флаги. обрабатывает и обнуляет флаги, чтобы система работала дальше

 

igorcds
Offline
Зарегистрирован: 03.12.2013

Здравствуйте.

А вы не могли бы прояснить про флаги...про boolean....в чем разница между boolean и другой переменной?

почему я не могу присвоить состояние пресловутой LED к примеру переменной status, а не boolean( для boolean true или false, а для status к примеру 1 и 0)?

я сваял себе небольшую систему управления светом в трех помещениях, делал на millis, т.к необходимо одновременное выполнение трех задач( свет- коридор, ванная, кухня). в каждом помещении ставил по одному сонару HC-SR04. По задумке - коридор свет горит 1 минута, потом отключается, в ванной и кухне по пересечению сонара- вкл/откл. все это делал просто для интереса, и для расширения кругозора...интерестно....вообщем вся система работает, но ожидаемо, там где просто на пересечение сонаров - это как бы просто пример отработки сонара...вот  и хочу на кухню сделать сонар + PIR.

можно сделать к примеру - пересечение сонара и если потом отрабатывает PIR- это + 1 человек, если наоборот - -1, но PIR может отрабатывать постоянно и килдык.......и т.д.

где то читал, что не рекомендуется использовать boolean и millis вместе.

не могли бы вы подсказать как добавить boolean в нижестоящий код? не надо готовых решений, мне бы направление куда копать(желательно в моем направлении) ну и какой нибудь пример с пояснением.

вот код для помещения куда хочу добавить PIR сенсор.


val = analogRead(RelayChn2);  // считываем состояние РЕЛЕ 2
//------------------------------------------------------------------------------------------------------------------------------

//ВКЛЮЧЕНИЕ С ЗАДЕРЖКОЙ 2сек- включение света по пересечению сонара
//ЕСЛИ СВЕТ ОТКЛЮЧЕН
//2 секунды реле не реагирует на срабатывание сонара и остается включенным и дальше

	  if ((dist_cm2 < 40)&&(val == HIGH))     // если дистанция меньше 40см и ОТКЛЮЧЕН свет - ВКЛЮЧАЕМ, val -считанное ранее состояние реле
          { 
          digitalWrite(RelayChn2,LOW);            //  ВКЛЮЧИТЬ реле
          
	    previousMillis2 = millis();           // каждый раз отсчёт отсрочки начинаеться сначала...
	  }
	  // отсчет 2 секунды
	  if(previousMillis2 && (millis()-previousMillis2 >= interval2))
	  {
	     // РЕЛЕ ОСТАЛОСЬ ВКЛЮЧЕННЫМ    
	    previousMillis2 = 0;
	  }

//-------------------------------------------------------------------------------------------------------------------------------

//ОТКЛЮЧЕНИЕ С ЗАДЕРЖКОЙ 2сек- включение света по пересечению сонара
//ЕСЛИ СВЕТ ВКЛЮЧЕН

//2 секунды реле не реагирует на срабатывание сонара и остается отключенным и дальше        
         
          if ((dist_cm2 < 40)&&(val == LOW))     // если дистанция меньше 40см и ВКЛЮЧЕН свет - ОТКЛЮЧАЕМ, val -считанное ранее состояние реле
          { 
          digitalWrite(RelayChn2,HIGH);            //  отключить реле
          
	    previousMillis2 = millis();           // каждый раз отсчёт отсрочки начинаеться сначала...
	  }
	  // отсчет 2 секунды
	  if(previousMillis2 && (millis()-previousMillis2 >= interval2))  // через 2 секунды
	  {
                 // РЕЛЕ ОСТАЛОСЬ ОТКЛЮЧЕННЫМ    
	    previousMillis2 = 0;
	  }

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

igorcds пишет:

А вы не могли бы прояснить про флаги...про boolean....в чем разница между boolean и другой переменной?

почему я не могу присвоить состояние пресловутой LED к примеру переменной status, а не boolean( для boolean true или false, а для status к примеру 1 и 0)?

У boolean может быть всего два значения - true или false (или 1 и 0, это одно и то же, используй как тебе удобнее).

У int может быть 65535 значений, но если тебе функционально нужно только два состояния, зачем использовать int и держать в памяти место для остальных 65533?  :)

// val лучше заменить на что-то понятное, типа stateOfRelay2 - только потому что через полгода будет проще вспомнить что же эта переменная означает :)
boolean stateOfRelay2 = analogRead(RelayChn2);  // считываем состояние РЕЛЕ 2
//------------------------------------------------------------------------------------------------------------------------------

//ВКЛЮЧЕНИЕ-ВЫКЛЮЧЕНИЕ С ЗАДЕРЖКОЙ 2сек- света по пересечению сонара
//2 секунды реле не реагирует на срабатывание сонара и остается включенным и дальше

if ((dist_cm2 < 40) && stateOfRelay2)     // если дистанция меньше 40см и ОТКЛЮЧЕН свет - ВКЛЮЧАЕМ, stateOfRelay2-считанное ранее состояние реле
{ 
    digitalWrite(RelayChn2,LOW);            //  ВКЛЮЧИТЬ реле //

    previousMillis2 = millis();           // каждый раз отсчёт отсрочки начинаеться сначала...
}
// отсчет 2 секунды
if(previousMillis2 && (millis()-previousMillis2 >= interval2))
{
  // РЕЛЕ ОСТАЛОСЬ ВКЛЮЧЕННЫМ    
    previousMillis2 = 0;
}

//-------------------------------------------------------------------------------------------------------------------------------

//ОТКЛЮЧЕНИЕ С ЗАДЕРЖКОЙ 2сек- включение света по пересечению сонара
//ЕСЛИ СВЕТ ВКЛЮЧЕН

//2 секунды реле не реагирует на срабатывание сонара и остается отключенным и дальше        

if ((dist_cm2 < 40) && !stateOfRelay2)     // если дистанция меньше 40см и ВКЛЮЧЕН свет - ОТКЛЮЧАЕМ, val -считанное ранее состояние реле
// выражение !stateOfRelay2 равноценно stateOfRelay2 == false, то так код читать легче
{ 
    digitalWrite(RelayChn2,HIGH);            //  отключить реле

    previousMillis2 = millis();           // каждый раз отсчёт отсрочки начинаеться сначала...
}
// отсчет 2 секунды
if(previousMillis2 && (millis()-previousMillis2 >= interval2))  // через 2 секунды
{
    // РЕЛЕ ОСТАЛОСЬ ОТКЛЮЧЕННЫМ    
    previousMillis2 = 0;
}

Но, на мой взгляд, у тебя два куска кода делают одно и то же, но с обратным значением, поэтому можно их объединить:

//ВКЛЮЧЕНИЕ С ЗАДЕРЖКОЙ 2сек- включение света по пересечению сонара
//2 секунды реле не реагирует на срабатывание сонара и остается включенным и дальше

if (dist_cm2 < 40)     // если дистанция меньше 40см, значит тело рядом и пора что-то делать
{ 
  digitalWrite(RelayChn2,!analogRead(RelayChn2)); // изменить состояние реле на противоположное
  previousMillis2 = millis();           // каждый раз отсчёт отсрочки начинаеться сначала...
}
// отсчет 2 секунды
if(previousMillis2 && (millis()-previousMillis2 >= interval2))
{
  // РЕЛЕ ОСТАЛОСЬ В ТОМ ЖЕ СОСТОЯНИИ
  previousMillis2 = 0;
}

Но тут могут быть подводные камни, ибо всего кода узреть не удалось. К примеру, в твоем коде чтобы выключить свет, надо тоже подходить к (мимо) датчику(а) - это так задумано?.

igorcds
Offline
Зарегистрирован: 03.12.2013

Вот весь код, переделал по вашей рекомендации:

    #include "Ultrasonic.h"
      unsigned long distance, time_sonar; //Переменные для сонара sonar()

       // Trig - 2, Echo - 3
       Ultrasonic ultrasonic1(2,3); // КОРИДОР, включение на 3 минуты
       
       // Trig - 4, Echo - 5
       Ultrasonic ultrasonic2(4, 5); // КУХНЯ, вкл/откл по пересечению сонара
       
       // Trig - 6, Echo - 7
       Ultrasonic ultrasonic3(6, 7); // ВАННАЯ, вкл-откл по пересечению сонара

        const int RelayChn1 = 8; //для КОРИДОРА
        const int RelayChn2 = 9; //для КУХНИ
        const int RelayChn3 = 10; //для ВАННОЙ

        int sensorPin = A0;    // пин фоторезистора 10кОм подтяжка
        int sensorValue = 0;  // показание фоторезистора
            
        unsigned long previousMillis1 = 0;      //храним время последнего Включения РЕЛЕ 1
	unsigned long previousMillis2 = 0;      //храним время последнего Включения РЕЛЕ 2
        unsigned long previousMillis3 = 0;      //храним время последнего Включения РЕЛЕ 3
	
        unsigned long interval1 = 20000;        //интервал для КОРИДОРА(20 СЕКУНД)
	unsigned long interval2 = 2000;         //пересечение на КУХНЮ(2 секунды)
        unsigned long interval3 = 2000;         //пересечение на ВАННУЮ(2 секунды)
	
void setup()
{	 
	  Serial.begin(9600); 
          pinMode(RelayChn1,OUTPUT);        //ВЫХОД на РЕЛЕ 1
          digitalWrite(RelayChn1,HIGH);     //Устанавливаем на входах релейного модуля ВЫСОКИЙ уровень 
          pinMode(RelayChn2,OUTPUT);        //ВЫХОД на РЕЛЕ 2
          digitalWrite(RelayChn2,HIGH);     //Устанавливаем на входах релейного модуля ВЫСОКИЙ уровень
          pinMode(RelayChn3,OUTPUT);       //ВЫХОД на РЕЛЕ 3
          digitalWrite(RelayChn3,HIGH);     //Устанавливаем на входах релейного модуля ВЫСОКИЙ уровень
         
}
 
void loop()
{
           float dist_cm1 = ultrasonic1.Ranging(CM);       // get distance
           delay(10);
           float dist_cm2 = ultrasonic2.Ranging(CM);       // get distance
           delay(10);
           float dist_cm3 = ultrasonic3.Ranging(CM);       // get distance
           delay(10);
           sensorValue = analogRead(sensorPin);           // снимаем показание фоторезистора 
           delay(10);
          
            
//СВЕТ В КОРИДОРЕ__свет включен 20секунд

	  if (dist_cm1 < 110)
          { 
          digitalWrite(RelayChn1,LOW); //включить РЕЛЕ 1

	  previousMillis1 = millis();  // каждый раз при нажатии кнопки отсчёт отсрочки начинаеться сначала...
	  }
	  // Прошло время выключаем реле 1
	  if(previousMillis1 && (millis()-previousMillis1 >= interval1))
	  {
	    digitalWrite(RelayChn1,HIGH); //отключить РЕЛЕ 1
           
	    previousMillis1 = 0;
	  }

// К У Х Н Я
//------------------------------------------------------------------------------------------------------------------------------

//ВКЛЮЧЕНИЕ С ЗАДЕРЖКОЙ 2сек- включение света по пересечению сонара
       //2 секунды реле не реагирует на срабатывание сонара и остается включенным и дальше
	 
	if ((dist_cm2 < 50)&&(sensorValue < 450))     // если дистанция меньше 40см, значит тело рядом и пора что-то делать
	{
	  digitalWrite(RelayChn2,!analogRead(RelayChn2)); // изменить состояние реле на противоположное
	  previousMillis2 = millis();           // каждый раз отсчёт отсрочки начинаеться сначала...
	}
	// отсчет 2 секунды
	if(previousMillis2 && (millis()-previousMillis2 >= interval2))
	{
	  // РЕЛЕ ОСТАЛОСЬ В ТОМ ЖЕ СОСТОЯНИИ
	  previousMillis2 = 0;
	}


// В А Н Н А Я  ПЕРЕДЕЛАТЬ НА ОТКРЫТИЕ ДВЕРЕЙ
//------------------------------------------------------------------------------------------------------------------------------

           
       //ВКЛЮЧЕНИЕ С ЗАДЕРЖКОЙ 2сек- включение света по пересечению сонара
       //2 секунды реле не реагирует на срабатывание сонара и остается включенным и дальше
	 
	if (dist_cm3 < 40)     // если дистанция меньше 40см, значит тело рядом и пора что-то делать
	{
	  digitalWrite(RelayChn3,!analogRead(RelayChn3)); // изменить состояние реле на противоположное
	  previousMillis3 = millis();           // каждый раз отсчёт отсрочки начинаеться сначала...
	}
	// отсчет 2 секунды
	if(previousMillis3 && (millis()-previousMillis3 >= interval3))
	{
	  // РЕЛЕ ОСТАЛОСЬ В ТОМ ЖЕ СОСТОЯНИИ
	  previousMillis3 = 0;
	}
}

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

Смущает объявление вот этой переменной 

unsigned long distance, time_sonar; //Переменные для сонара sonar().

Помоему это лишнее, или неправильно. Где то вычитал, что объявление  необходимо, чтобы не было переполнений в переменных сонара.

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

 

Набросал код для подсчета количества людей сонаром(сонар стоит напротив дверного проема), Код работает, но как то неправильно....:


#include "Ultrasonic.h"

// sensor connected to:
// Trig - 12, Echo - 13
Ultrasonic ultrasonic(12, 13);

int distans [25];                    // массив для сохранения значений сонара 25 измерений
int i= 0;

const int LED2 =  2;                   // горит если удаляюсь от сонара
const int LED3 =  3;                   // горит если приближаюсь к сонару

unsigned long previousMillis = 0;      //храним время последнего Включения
unsigned long interval = 6000;         //время работы LED1 или LED2     

void setup()
{
  Serial.begin(9600);                           // start the serial port
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
}

void loop()
{
  float dist_cm = ultrasonic.Ranging(CM);       // get distance
 delay(10);
  if ((dist_cm < 100)&&(i==0))
  { 
       previousMillis = millis();
       for (i=0; i<24; i++)
       {
           float dist_cm = ultrasonic.Ranging(CM);       // get distance
           distans[i]=dist_cm;
           delay(10);   
       }
     
     // если приближаюсь горит LED2, 
     // если удаляюсь горит LED1
       if (distans[2] < distans[19])
          {
         digitalWrite(LED2, HIGH);     // УДАЛЯЮСЬ
         digitalWrite(LED3, LOW);
          } 
        if (distans[2] > distans[19])
          {
         digitalWrite(LED2, LOW);
         digitalWrite(LED3, HIGH);     // приближаюсь
          }
          
  }
   // Прошло время выключаем
  if(previousMillis && (millis()-previousMillis >= interval))
	  {
            i=0;
            previousMillis = 0;
            Serial.print("i=");
            Serial.println(i);
             
            digitalWrite(LED2, LOW);
            digitalWrite(LED3, LOW); 
          }
        
}


Код как бы слишком быстро работает(ну или я слишком медленно хожу) :), слишком быстро снимаются показания сонара. Может что нибудь посоветуете?

Или как можно связать воедино - время нахождения человека в луче сонара и длину массива? Не хочу гуглить и искать готовое решение, хочу сам доделать... спасибо

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

наверное, 10 мс слишком мало, сколько см человек успеет пройти за 240 мс?

И в описании ультрасоников есть фраза "Следующий импульс может быть излучён, только после исчезновения эха от предыдущего. Рекомендованный период между импульсами должен быть не менее 50 мс.", а у тебя 10 мс.

igorcds
Offline
Зарегистрирован: 03.12.2013

то есть, скажем, что человеку на вход/выход из помещения требуется около 1 секунды - необходимо 20 заполнений массива с периодом 50мс...ну или там +- поэксперементировать...А если произойдет такое - измерит не 20 раз, а меньше(к примеру 15 раз). недостающие пять измерений приравняюся к нулю?  да, и получается, что необходимо обнулять массив в определенном месте(если измерит 15 раз вместо 20, пять неизмеренных значений будут иметь предыдущее значение...).

Еще вопрос - как можно в массиве выявить минимальное и максимальное значение и соответсвенно узнать местоположение минумама и максимами? можно использовать операторы min и max? min(massiv[20])? или только цикл и оператор if?

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

igorcds пишет:

имел ввиду - как просчитать, какой датчик первый сработал?

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

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

нет больше определитель в какую сторону прошел человек)))

2 лазерных модуля с приемниками больше бы облегчили изначально задачу и программирование

Клапауций
Offline
Зарегистрирован: 10.02.2013

не - турникет нужно ставить.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

ага. с карточками rfid. забыл карточку не попал в туалет. и тут только зайцем. а вдруг контролер))))

igorcds
Offline
Зарегистрирован: 03.12.2013

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

Доделал код на подсчет количества людей, сделан на двух сонарах.

Сонары расположены один за другим на расстоянии друг от друга около метра.

Высота от пола 1,2 метра. Может посмотрите код, подскажите пожалуйсто какие есть недочеты или косяки.

вот код на подсчет количества людей

#include "Ultrasonic.h"

// Trig - 8, Echo - 7
Ultrasonic IN2(8, 7);     // сонар в двери

// Trig - 6, Echo - 5
Ultrasonic START2(6, 5);  // сонар для подсчета

const int RelayChn3 = 9; // реле


int i=0;                 // количество людей

unsigned long IN2_2= 0;    //когда сработал IN1
unsigned long START2_2= 0; //когда сработал START2
unsigned long previousMillis21= 0;
unsigned long IN_interval21= 2000; //  интервал измерения IN сонаром
unsigned long previousMillis22= 0;
unsigned long START_interval22= 2000; // интервал измерения START сонаром
unsigned long previousMillis23= 0;
unsigned long START_interval23= 1000; //  время подсчета количества людей

void setup()
{
  Serial.begin(9600);                           // start the serial port
  pinMode (RelayChn3, OUTPUT);
  digitalWrite(RelayChn3, HIGH);
}

void loop()
{
  float distIN2 = IN2.Ranging(CM);   
  delay(50);
  float distSTART2 = START2.Ranging(CM); 
  delay(50);
   
 
 // ОТРАБОТКА СОНАРА IN2__В ДВЕРЯХ
 
  if(distIN2 < 60){
   IN2_2= millis(); 
   previousMillis21 = millis();
              }
             
  // ВРЕМЯ ЗАМЕРА 0.5 сек.           
 if(previousMillis21 && (millis()-previousMillis21 >= IN_interval21))
	{ if(START2_2==0) {IN2_2=0;}
  
  previousMillis21 = 0;
   
	} 

// ОТРАБОТКА СОНАРА START__контроль в помещении
if(distSTART2 < 80){
   START2_2= millis(); 
   previousMillis22 = millis();
              }
             
  // ВРЕМЯ ЗАМЕРА 0.5 сек.           
 if(previousMillis22 && (millis()-previousMillis22 >= START_interval22))
	{
  if(IN2_2==0) {START2_2=0;}
  previousMillis22 = 0; 
  
	}   

// ПОДСЧЕТ ЛЮДЕЙ плюс

       if (IN2_2 > 100&&START2_2 >100&&( IN2_2 < START2_2))
        {
          i=i+1;
         IN2_2=0;
         START2_2=0;          
        }                
   if(previousMillis23 && (millis()-previousMillis23 >= START_interval23))
      {  
   previousMillis23 = millis();
    IN2_2=0;
    START2_2=0;  
       }  

// минус
// ПОДСЧЕТ ЛЮДЕЙ 

       if (IN2_2 > 100&&START2_2 > 100&&i >= 1&&( IN2_2 > START2_2))
             {
          i=i-1;
         IN2_2=0;
         START2_2=0;          
        
               }
   if(previousMillis23 && (millis()-previousMillis23 >= START_interval23))
      {
          
   previousMillis23 = millis();
       }
    
  // Если i=0 и выход
   if (IN2_2 > 100&&START2_2 > 100&&i ==0 &&( IN2_2 > START2_2))
        {
         IN2_2=0;
         START2_2=0;
         i=0;
        }  
  
 
 // ВКЛЮЧЕНИЕ СВЕТА
if(i>=1)
 { 
   digitalWrite(RelayChn3, LOW);
 } else {
   digitalWrite(RelayChn3, HIGH);
         }
  if(previousMillis23 && (millis()-previousMillis23 >= START_interval23))
      {
          
   previousMillis23 = millis();
       }
 
  
}

вот весь код, на три помещения. в одном помещении срабатывание по PIR sensor, во втором по пересечению сонара и в третьем на подсчет людей.

#include "Ultrasonic.h"
      unsigned long distance, time_sonar; //Переменные для сонара sonar()

       //1 КОРИДОР 
        int PIR = 2;         // ПИР сенсор 12
        int val_PIR= 0;       //состояние ПИРА КУХНЯ, вкл/откл по пересечению сонара

       
       
       // 3 ВАННАЯ
       //Trig - 6, Echo - 7
       Ultrasonic ultrasonic3(3,4); // ВАННАЯ, вкл-откл по пересечению сонара
       
       //КУХНЯ 2 сонара
       // Trig - 8, Echo - 7
       Ultrasonic IN2(8, 7);     // сонар в двери

       // Trig - 6, Echo - 5
       Ultrasonic START2(6, 5);  // сонар для подсчета

        const int RelayChn1 = 11; //для КОРИДОРА  8пин
        const int RelayChn2 = 9; //для КУХНИ
        const int RelayChn3 = 10; //для ВАННОЙ      
      
        int val1 = 0;         // состояние реле1(КОРИДОР)
        int val3 = 0;         // состояние реле3(ВАННАЯ)
        
        
	unsigned long previousMillis1 = 0;      //храним время последнего Включения РЕЛЕ 1
	unsigned long previousMillis2 = 0;      //храним время последнего Включения РЕЛЕ 2
        unsigned long previousMillis3 = 0;      //храним время последнего Включения РЕЛЕ 3
	
        unsigned long interval1 = 15000;        //интервал для КОРИДОРА 15секунд + настройка PIR
	unsigned long interval2 = 1500;         //пересечение на КУХНЮ(1,5 секунды)
        unsigned long interval3 = 1500;         //пересечение на ВАННУЮ(1,5 секунды)
  
  // ДЛЯ КУХНИ     
        int i=0;                 // количество людей
        unsigned long IN2_2= 0;    //когда сработал IN1
        unsigned long START2_2= 0; //когда сработал START2
        unsigned long previousMillis21= 0;
        unsigned long IN_interval21= 1000; //  интервал измерения IN сонаром
        unsigned long previousMillis22= 0;
        unsigned long START_interval22= 1000; // интервал измерения START сонаром
        unsigned long previousMillis23= 0;
        unsigned long START_interval23= 500; //  время подсчета количества людей
	
void setup()
{	 
	  //задаем режим выхода для порта, подключенного к светодиоду
	  Serial.begin(9600); 
          pinMode(PIR, INPUT);              // режим работы PIR
          pinMode(RelayChn1,OUTPUT);        //ВЫХОД на РЕЛЕ 1
          digitalWrite(RelayChn1,HIGH);     //Устанавливаем на входах релейного модуля ВЫСОКИЙ уровень 
          pinMode(RelayChn2,OUTPUT);        //ВЫХОД на РЕЛЕ 2
          digitalWrite(RelayChn2,HIGH);     //Устанавливаем на входах релейного модуля ВЫСОКИЙ уровень
          pinMode(RelayChn3,OUTPUT);       //ВЫХОД на РЕЛЕ 3
          digitalWrite(RelayChn3,HIGH);     //Устанавливаем на входах релейного модуля ВЫСОКИЙ уровень
         
}
 
void loop()
{          float distIN2 = IN2.Ranging(CM);   
           delay(50);
           float distSTART2 = START2.Ranging(CM); 
           delay(50);
           float dist_cm3 = ultrasonic3.Ranging(CM);       // get distance
           delay(50);
           
           val_PIR = digitalRead(PIR);                    // запоминаем показания PIR
          
            
//СВЕТ В КОРИДОРЕ

	 // сработал датчик движения и реле отключено - ВКЛ свет 
	  if (val_PIR == HIGH) 
          { 
          digitalWrite(RelayChn1,LOW);            //  ВКЛЮЧИТЬ реле 1     8пин

	  previousMillis1 = millis();           // каждый раз отсчёт отсрочки начинаеться сначала
	  }
	  // отсчет 5-10 секунд и отключаем свет
	  if(previousMillis1 && (millis()-previousMillis1 >= interval1))
	  {
	   previousMillis1 = 0;
           digitalWrite(RelayChn1,HIGH);            //  ОТКЛЮЧИТЬ реле 1
           val1 = digitalRead(RelayChn1);  // считываем состояние РЕЛЕ 1
	  }

// В А Н Н А Я
//------------------------------------------------------------------------------------------------------------------------------
           
	  //ВКЛЮЧЕНИЕ С ЗАДЕРЖКОЙ 2сек- включение света по пересечению сонара
	 
	if ((dist_cm3 < 35)&&(val3 == HIGH))                              
	{
	  digitalWrite(RelayChn3,LOW);            //  ВКЛЮЧИТЬ реле 3     10пин
	  previousMillis3 = millis();            // каждый раз отсчёт отсрочки начинаеться сначала...
	}
	// отсчет 2 секунды
	if(previousMillis3 && (millis()-previousMillis3 >= interval3))
	{
         val3=digitalRead(RelayChn3);
	  previousMillis3 = 0;
	}

//отключаем свет ванная

        if ((dist_cm3 < 35)&&(val3 == LOW))                               
	{
	 digitalWrite(RelayChn3, HIGH);            //  ВКЛЮЧИТЬ реле 1     10пин
	 previousMillis3 = millis();               // каждый раз отсчёт отсрочки начинаеться сначала...
	}
	// отсчет 2 секунды
	if(previousMillis3 && (millis()-previousMillis3 >= interval3))
	{
         val3=digitalRead(RelayChn3);
   // РЕЛЕ ОСТАЛОСЬ В ТОМ ЖЕ СОСТОЯНИИ
	  previousMillis3 = 0;
	}
//----------------------------------------------------------------------
// КУХНЯ

 // ОТРАБОТКА СОНАРА IN2__В ДВЕРЯХ
 
  if(distIN2 < 60){
   IN2_2= millis(); 
   previousMillis21 = millis();
              }
             
  // ВРЕМЯ ЗАМЕРА равно interval21          
 if(previousMillis21 && (millis()-previousMillis21 >= IN_interval21))
	{ if(START2_2==0) {IN2_2=0;}
  
  previousMillis21 = 0;
   
	} 

// ОТРАБОТКА СОНАРА START__контроль в помещении
// время замера interval22
if(distSTART2 < 80){
   START2_2= millis(); 
   previousMillis22 = millis();
              }
             
  // ВРЕМЯ ЗАМЕРА 0.5 сек.           
 if(previousMillis22 && (millis()-previousMillis22 >= START_interval22))
	{
  if(IN2_2==0) {START2_2=0;}
  previousMillis22 = 0; 
  
	}   

// ПОДСЧЕТ ЛЮДЕЙ плюс

       if (IN2_2 > 100&&START2_2 >100&&( IN2_2 < START2_2))
        {
          i=i+1;
         IN2_2=0;
         START2_2=0;          
        }                
   if(previousMillis23 && (millis()-previousMillis23 >= START_interval23))
      {  
   previousMillis23 = millis();
    IN2_2=0;
    START2_2=0;  
       }  

// минус
// ПОДСЧЕТ ЛЮДЕЙ 

       if (IN2_2 > 100&&START2_2 > 100&&i >= 1&&( IN2_2 > START2_2))
        {
          i=i-1;
         IN2_2=0;
         START2_2=0;          
        
               }
   if(previousMillis23 && (millis()-previousMillis23 >= START_interval23))
      {
          
   previousMillis23 = millis();
       }
    
  // Если i=0 и выход
   if (IN2_2 > 100&&START2_2 > 100&&i ==0 &&( IN2_2 > START2_2))
        {
         IN2_2=0;
         START2_2=0;
         i=0;
        }  
  
 
 // ВКЛЮЧЕНИЕ СВЕТА
if(i>=1)
 { 
   digitalWrite(RelayChn2, LOW);
 } else {
   digitalWrite(RelayChn2, HIGH);
         }
  if(previousMillis23 && (millis()-previousMillis23 >= START_interval23))
      {
          
   previousMillis23 = millis();
       }
       
       
}

Спасибо