#1 2018-04-05 22:05:34

demonstrius
Учасник
Зареєстрований: 2018-04-05
Повідомлень: 4

Обработка длительной сработки PIR-датчика

Нужно чтобы при 10-секундной сработке PIR-датчика в переменную Pir10Sec заносилась 1, а при отключении датчика -0.
Написал такой код:

void pirmonitoring() {

  val = digitalRead(inputPin);
  if (val == HIGH) {
     digitalWrite(ledPin, HIGH);

     if (pirState == LOW) {      // пир-датчик включен
         pirState = HIGH;
         PirOn = millis();
         DigitpirState = 1;
     
         Serial.print("Motion ON!: ");
         Serial.print(h); Serial.print(":"); Serial.println(m);
         Serial.print("DigitpirState: ");
         Serial.println(DigitpirState);
         Serial.println();

        }
    }

     else {
         digitalWrite(ledPin, LOW);

         if (pirState == HIGH) {      // пир-датчик отключен
             pirState = LOW;
             PirOff = millis();
             Pir10Sec = 0;
             DigitpirState = 0;
     
             Serial.print("Motion OFF: ");
             Serial.print(h); Serial.print(":"); Serial.println(m);
             Serial.print("DigitpirState: ");
             Serial.println(DigitpirState);
             Serial.print("Pir10Sec: ");
             Serial.println(Pir10Sec);
             Serial.println();

            }
        }

      if (PirOff - PirOn > 10000) {    // длительная сработка пир-датчика
         Pir10Sec = 1;
         Serial.print("Motion LONG ON!: ");
         Serial.print(h); Serial.print(":"); Serial.println(m);   
         Serial.print("Pir10Sec: ");
         Serial.println(Pir10Sec);
         Serial.println();
        }

}

Но он не работает так как надо. А именно - при коротком срабатывании и отключении датчика переменная DigitpirState записывается правильно (0 или 1), а вот при длительной сработке датчика в  переменную Pir10Sec записывается 1, но при отключении так и остается 1 пока не произойдет короткая сработка.
Прошу помощи спецов. Заранее спасибо.

Неактивний

#2 2018-04-05 22:58:29

Госпади
Учасник
Зареєстрований: 2018-04-02
Повідомлень: 6

Re: Обработка длительной сработки PIR-датчика

Ну смотрите, в этой строке

      if (PirOff - PirOn > 10000) {    // длительная сработка пир-датчика

происходит что-то странное, а именно по условию "длительная сработка пир-датчика" происходит когда PirOff (время выключения датчика / последнее время НЕ сработки датчика) БОЛЬШЕ PirOn (времени включения / последнего времени сработки датчика).

В данном условии просходит сравнение "отключен ли датчик 10 секунд и более". Так что для начала поменяйте на

      if (PirOn - PirOff > 10000) {    // длительная сработка пир-датчика

Неактивний

#3 2018-04-06 10:38:53

demonstrius
Учасник
Зареєстрований: 2018-04-05
Повідомлень: 4

Re: Обработка длительной сработки PIR-датчика

Поменял if (PirOff - PirOn > 10000) на if (PirOn - PirOff > 10000). Теперь в переменную Pir10Sec записываются правильные значения, но сработка PIR-датчика происходит как попало. На короткое движение может среагировать как на длительное.
Вот лог serial:

PirOn: 158519
PirOff: 150694
Motion LONG ON!: 10:28
Pir10Sec: 1

Motion OFF: 10:28
DigitpirState: 0
PirOff: 161361
Pir10Sec: 0

Motion ON!: 10:28
DigitpirState: 1
PirOn: 163071

Motion OFF: 10:28
DigitpirState: 0
PirOff: 165968
Pir10Sec: 0

Неактивний

#4 2018-04-06 10:54:49

NoName
Customer
З Київ
Зареєстрований: 2014-07-08
Повідомлень: 1,446

Re: Обработка длительной сработки PIR-датчика

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

  


typedef struct 
{
int pin_number; 
int             time_debounce; 
unsigned long   time_press  ;
unsigned long   time_released;
unsigned long   time_last_press;
unsigned long   time_last_release;

int             press_level_detect;  

bool            status_press;
bool            status_release;

bool            interrupt_press;
bool            interrupt_release;
bool            need_release;
bool            execute;
}  tdpkey;

tdpkey key1;

setup
  key1.pin_number          = 11;
  key1.time_debounce       = 50;
  pinMode(key1.pin_number, INPUT);
  key1.need_release        = false;
  key1.press_level_detect  = HIGH;





void clear_fkey_interrupt ( tdpkey *pkey )
{
 pkey->interrupt_release  = false;
 pkey->interrupt_press    = false;
 pkey->need_release       = true;
}

//------------------------------------
   
void fKey (tdpkey *pkey, int time_elapsed )
{
  if ( digitalRead( pkey->pin_number) == pkey->press_level_detect )
  { 
   pkey->time_press         += time_elapsed; 
  // Serial.print("+"); Serial.println ( pkey->time_press );
  }
  else 
  {  
   pkey->time_released += time_elapsed;
 //  Serial.print("-"); Serial.println ( pkey->time_released );
  }
  
  // key was release
  if  ( pkey->time_released > pkey->time_debounce )
  {
  if ( pkey->status_release == false ) 
    {
   
    pkey->status_release  = true;
    pkey->status_press    = false;
    pkey->interrupt_press   = false;

    // if  ( pkey->need_release  == false )
    {
      pkey->interrupt_release = true;
    }
    
    pkey->need_release  = false;
    pkey->time_last_press = pkey->time_press;
	pkey->time_press =  0;

#ifdef DEBUG   
    sprintf  ( debug_str,"dbg:key_release");  Serial.println  ( debug_str );  
#endif
    }
  }

if ( pkey->time_press > pkey->time_debounce )
{    
  if ( pkey->status_press == false ) 
  {
    pkey->status_press      = true;
    pkey->need_release      = false;
    pkey->status_release    = false;
    pkey->interrupt_press   = true;
    pkey->interrupt_release = false;
    pkey->time_last_release = pkey->time_released;
    pkey->time_released    = 0;
#ifdef DEBUG  
    sprintf  ( debug_str,"dbg:key_press");  Serial.println  ( debug_str );  
#endif
  }
}
 return;
}



loop

 static unsigned long  hw_old_system_timer = 0; 
        unsigned long  hw_current_system_timer = 0; 

 unsigned long  delta_task_timer; 

 hw_current_system_timer  = millis();
 delta_task_timer         = hw_current_system_timer - hw_old_system_timer;
 hw_old_system_timer      = hw_current_system_timer;

 fKey (&key1 , delta_task_timer );

 use 
if ( key1.interrupt_release )  {}

дальше сами

Неактивний

#5 2018-04-06 11:18:56

demonstrius
Учасник
Зареєстрований: 2018-04-05
Повідомлень: 4

Re: Обработка длительной сработки PIR-датчика

Спасибо. Не уверен в результате, но буду разбираться.

Неактивний

#6 2018-04-06 18:13:11

Госпади
Учасник
Зареєстрований: 2018-04-02
Повідомлень: 6

Re: Обработка длительной сработки PIR-датчика

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

Т.е. обновляем время чаще:

void pirmonitoring() {

  val = digitalRead(inputPin);
  if (val == HIGH) {
     digitalWrite(ledPin, HIGH);
     PirOn = millis();

     if (pirState == LOW) {      // пир-датчик включен
         pirState = HIGH;
         DigitpirState = 1;
     
         Serial.print("Motion ON!: ");
         Serial.print(h); Serial.print(":"); Serial.println(m);
         Serial.print("DigitpirState: ");
         Serial.println(DigitpirState);
         Serial.println();

        }
    }

     else {
         digitalWrite(ledPin, LOW);
         PirOff = millis();

         if (pirState == HIGH) {      // пир-датчик отключен
             pirState = LOW;
             Pir10Sec = 0;
             DigitpirState = 0;
     
             Serial.print("Motion OFF: ");
             Serial.print(h); Serial.print(":"); Serial.println(m);
             Serial.print("DigitpirState: ");
             Serial.println(DigitpirState);
             Serial.print("Pir10Sec: ");
             Serial.println(Pir10Sec);
             Serial.println();

            }
        }

      if (PirOff - PirOn > 10000) {    // длительная сработка пир-датчика
         Pir10Sec = 1;
         Serial.print("Motion LONG ON!: ");
         Serial.print(h); Serial.print(":"); Serial.println(m);   
         Serial.print("Pir10Sec: ");
         Serial.println(Pir10Sec);
         Serial.println();
        }

}

Неактивний

#7 2018-04-09 18:39:45

demonstrius
Учасник
Зареєстрований: 2018-04-05
Повідомлень: 4

Re: Обработка длительной сработки PIR-датчика

Тема закрыта. Спасибо Госпади за помощь. Код был переписан благодаря NoName, за что ему особая благодарность.

Остання редакція demonstrius (2018-04-09 18:41:03)

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму