본문 바로가기
아두이노

Arduino PIR 모션 센서 튜토리얼

by 모빌리티키즈 2023. 11. 14.
728x90

손을 대면 자동으로 물이 나오는 수도꼭지나 누군가가 들어오는 순간 방을 밝히는 스마트 전구의 마법에 대해 생각해 본 적이 있나요? 이러한 많은 경우 PIR 센서는 배후의 마법입니다.

이 튜토리얼에서는 PIR 모션 센서의 작동 방식과 PIR 센서를 Arduino에 연결하는 방법을 배웁니다. 이 튜토리얼이 끝나면 PIR 센서를 사용하는 멋진 프로젝트를 만들겠습니다.

PIR 모션 센서 소개

PIR 센서(수동 적외선 센서)는 시야 내에서 적외선 복사의 변화를 감지하는 동작 센서 유형입니다. 이름에서 알 수 있듯이 "수동" 적외선 센서이므로 어떤 유형의 적외선도 방출하지 않습니다. 시야에 있는 물체에서 방출되는 적외선(IR)만 측정합니다.

모든 생명체와 물체에는 일정 수준의 내부 열이 포함되어 있으며 이 열을 적외선 복사의 형태로 지속적으로 방출합니다. 물체가 움직이면 방사선 수준이 변합니다. PIR 센서는 방사선 수준의 변화를 감지하여 동작을 식별합니다.

PIR 모션 센서는 홈 보안 시스템, 홈 오토메이션 및 스마트 장치에서 모션을 감지하는 데 널리 사용됩니다. 가격이 저렴하고 동작을 완벽하게 감지하는 정확성으로 인해 이러한 유형의 애플리케이션에서 매우 인기가 있습니다. 하지만 PIR은 움직임의 방향이 아닌 움직임만 감지할 수 있다는 점을 명심하세요.

PIR 센서 작동 방식

PIR 센서는 일반적으로 다양한 수준의 적외선을 감지할 수 있는 초전성 재료로 만들어집니다. 자세히 살펴보면 센서 내부에 두 개의 직사각형 슬롯이 있음을 알 수 있습니다. 두 슬롯 모두 시야에서 IR 수준을 감지할 수 있는 동일한 셀을 가지고 있습니다.

움직임이 없으면 두 슬롯 모두 동일한 양의 적외선을 방출합니다. 그러나 인체나 동물이 센서 범위 안팎으로 움직일 때 두 센서의 판독값에 차이가 있습니다. 이 전압 변화를 읽어 움직임을 감지할 수 있습니다.

HC-SR501 PIR 센서 모듈

초전기 센서는 처리하기 어려울 수 있는 아날로그 신호를 생성합니다. HC-SR501 PIR 센서 모듈은 프로세스를 단순화합니다. BISS0001 칩을 사용하여 이 아날로그 신호를 디지털 신호로 변환합니다.

움직임이 감지되면 출력이 높아지고 움직임이 멈추면 출력이 낮아집니다. HC-SR501 모듈의 출력 신호 파형은 아래와 같습니다.

 

위에서 볼 수 있듯이 출력 신호와 관련된 두 가지 타임아웃이 있습니다. 하나는 출력 펄스 폭(T x )이고 다른 하나는 트리거 금지 타이밍(T i )입니다. T x 는 트리거링 후 펄스가 높게 유지되는 시간입니다. 모든 펄스 트리거링 이후에는 일정 시간 동안 억제됩니다. 이를 금지 타이밍(T i )이라고 합니다.

HC-SR501 모듈에는 두 개의 트림 전위차계가 있는데, 하나는 펄스 폭(T x ) 을 조절하는 데 사용되고 다른 하나는 센서의 감도를 제어하는 ​​데 사용됩니다. 노브를 시계 방향이나 시계 반대 방향으로 돌려 펄스 폭 지속 시간과 감도를 조정할 수 있습니다.

HC-SR501 모듈에는 단일 트리거 모드와 재트리거 모드의 두 가지 유형의 트리거 모드 중에서 선택할 수 있는 일부 점퍼 헤더도 포함되어 있습니다.

단일 트리거 모드(L) - 이 트리거 모드에서는 움직임이 감지되면 출력 신호가 높아지며 사전 설정된 시간 동안 높은 상태를 유지합니다. 이 시간 동안 센서는 더 이상의 움직임에 반응하지 않습니다. 지정된 기간이 지나면 펄스가 낮은 상태로 전환됩니다.

재트리거 모드(H) – 재트리거 모드에서는 센서가 감지된 각 동작에 반응합니다. 움직임이 감지되면 출력 신호가 높아지며 사전 설정된 시간(T x ) 동안 이 상태를 유지합니다. 센서가 이 시간(T x ) 내에 다른 움직임을 감지하면 타이머가 재설정되고 신호는 추가 시간(T x ms) 동안 높은 상태로 유지됩니다. 이 기간 내에 더 이상 움직임이 감지되지 않으면 펄스는 낮은 상태로 전환됩니다.

HC-SR501 모듈 핀아웃

HC-SR501 PIR 센서에는 VCC, OUT, GND 세 개의 핀만 있습니다. VCC 및 GND는 OUT 핀이 센서의 출력 신호를 제공하는 전원 공급 장치 핀입니다.

Arduino PIR 센서 회로

PIR 센서를 Arduino와 연결하는 것은 매우 간단하고 간단합니다. VCC 및 GND 핀을 각각 Arduino 5V 및 접지 핀에 연결하십시오. OUT 핀을 Arduino 핀 3(인터럽트 핀)에 연결합니다. 또한 동작이 감지되면 불이 켜지도록 회로에 LED를 추가했습니다.

PIR 데이터는 간단한 디지털 읽기 또는 인터럽트로 읽을 수 있다는 점을 기억하십시오. 간단한 디지털 읽기는 대부분의 프로젝트에서 작동하지만 고급 프로젝트의 경우 PIR 센서를 인터럽트로 연결해야 합니다.

 

PIR 모션 센서 Arduino 코드

PIR 센서의 코드는 Arduino 핀의 디지털 판독만큼 간단할 수 있습니다. 그러나 대규모 프로젝트의 경우 더 복잡해질 수 있습니다. 모든 프로젝트에 PIR 센서를 추가하는 데 도움이 되는 몇 가지 다양한 시나리오에 대한 코드를 작성하고 설명하겠습니다.

Arduino IDE의 직렬 플로터에 출력 펄스의 파형을 간단히 표시하는 것부터 시작해 보겠습니다.

코드 – 파형 표시

/*
  PIR Sensor data on the Serial Plotter
  Written by : Kishor
  Tutorial : https://www.circuitgeeks.com
*/

const int pirPin = 3;     // pin for the PIR sensor
const int pirState = LOW; // variable for reading the PIR pin status

void setup() {
  // initialize serial communication at 9600 bits per second
  Serial.begin(9600);
  pinMode(pirPin, INPUT); // declare sensor as input
}

void loop() {
  pirState = digitalRead(pirPin); // read input value  
  Serial.println(pirState); // print out the state of the button:
  delay(50); // delay in between reads
}

코드를 실행하고 Arduino IDE에서 직렬 플로터를 엽니다. 센서 앞에서 손을 흔들어 센서가 움직임에 어떻게 반응하는지 확인하세요. 지연을 조정하여 펄스 속도를 제어합니다.

간단히 LED를 켜고 끄세요

아래 코드는 움직임이 감지되면 LED를 켜는 코드입니다. 펄스가 높아질 때까지 LED는 계속 켜져 있습니다. 펄스가 낮은 상태로 전환되자마자 꺼집니다.

/*
  Arduino digitalRead a PIR sensor with LED
  Written by : Kishor
  Tutorial : https://www.circuitgeeks.com
*/

const int ledPin = 7; // pin for the LED
const int pirPin = 3; // pin for the PIR sensor
byte pirState = LOW;  // variable for reading the PIR pin status

void setup() {
  pinMode(ledPin, OUTPUT); // declare LED as output
  pinMode(pirPin, INPUT);  // declare sensor as input
}

void loop() {
  pirState = digitalRead(pirPin); // read input value
  if (pirState == HIGH) {
    digitalWrite(ledPin, HIGH); // turn LED ON
  }
  else {
    digitalWrite(ledPin, LOW); // turn LED OFF
  }
}

위 프로그램에서 LED의 켜짐 시간은 펄스 지속 시간에 전적으로 의존한다는 것을 확인했습니다. 이는 일부 응용 프로그램에서는 제한이 될 수 있습니다.

버튼을 누를 때만 LED를 끄고 싶거나 센서의 펄스 지속 시간에 관계없이 특정 지속 시간 동안 LED를 켜두기를 원한다고 가정해 보겠습니다. 이러한 경우 Arduino 인터럽트 기능이 필요합니다.

PIR 센서 Arduino 인터럽트 코드

아래 코드는 PIR 모션 센서와 함께 Arduino 인터럽트 기능을 사용하는 방법을 보여줍니다. 움직임이 감지되면 코드가 LED를 켭니다. 프로그램에 설정된 시간 동안 켜져 있습니다. 그 후에는 꺼지고 다음 동작을 기다립니다.

/*
  Arduino Interrupt with PIR sensor and LED
  Written by : Kishor
  Tutorial : https://www.circuitgeeks.com
*/

const int ledPin = 7; // pin for the LED
const int PIRInterrupt = 3; // pin for the PIR sensor

volatile byte motion = false; // flag

const long onTime = 10000; // LED on time after a motion is detected
unsigned long lastTrigger = 0; // last time the sensor was triggered

void setup() {
  pinMode(ledPin, OUTPUT); // declare LED as output
  pinMode(PIRInterrupt, INPUT); // declare sensor as input
  // Call the motionDetected function when a rising edge is detected
  attachInterrupt(digitalPinToInterrupt(PIRInterrupt), motionDetected, RISING);
}

void loop() {
  if ((millis() - lastTrigger) < onTime && motion == true) {
    // during the onTime period & motion = true
    digitalWrite(ledPin, HIGH); // turn on the LED
  }
  else {
    digitalWrite(ledPin, LOW); // turn off the LED
  }
}

void motionDetected() {
  lastTrigger = millis();
  motion = true;
}

코드 설명

먼저 프로그램에서 나중에 사용할 몇 가지 변수를 선언합니다. LED와 PIR 출력 핀에 연결된 핀 번호를 유지하기 위해 두 개의 상수 정수 변수를 사용했습니다.

const  int  ledPin  =  7 ; 
const  int  PIRInterrupt  =  3 ;

프로그램에서 플래그로 사용할 Motion이라는 변수를 만들었습니다.

volatile byte motion = false;

또한 시간을 처리하려면 두 개의 다른 변수가 필요합니다. onTime 움직임이 감지된 후 LED가 켜져 있는 시간을 설정하는 데 사용됩니다 . lastTrigger 마지막으로 움직임이 감지된 시간을 저장하는 데 사용됩니다 

const long onTime = 10000;
unsigned long lastTrigger = 0;

설정에서 섹션 I은 LED 핀을 출력 핀으로 설정하고 PIR 핀을 입력 핀으로 설정했습니다.

 

pinMode(ledPin, OUTPUT);
pinMode(PIRInterrupt, INPUT);

PIR 센서의 출력 핀을 지속적으로 모니터링하기 위해 Arduino 인터럽트 기능을 사용합니다 . RISING여기서는 인터럽트 핀에서 상승 에지가 감지될 때 기능을 트리거하는 모드를 사용합니다 .

attachmentInterrupt ( digitalPinToInterrupt ( PIRInterrupt ) ,  MotionDetected ,  RISING ) ;

인터럽트 기능에는 인터럽트 핀에서 특정 유형의 변경(예: 상승 또는 하강 등)을 감지할 때마다 호출하는 ISR(인터럽트 서비스 루틴)이 필요합니다.

motionDetected그래서 프로그램 끝에 이름이 붙은 ISR 함수를 만들었습니다 . 센서가 마지막으로 트리거된 시간을 모니터링하고 모션 플래그를 로 설정합니다 true.

void motionDetected() {
  lastTrigger = millis();
  motion = true;
}

루프 섹션에서는 Arduino millis() 함수를 사용하여 시간을 추적합니다. LED는 lastTrigger 시간부터 onTime 기간이 끝날 때까지 켜집니다. 그 후에는 꺼지고 다음 동작을 기다립니다.

if ((millis() - lastTrigger) < onTime && motion == true) {
  digitalWrite(ledPin, HIGH);
}
else {
  digitalWrite(ledPin, LOW);
}

간단한 제스처 제어 장치

PIR 센서를 스마트 홈 프로젝트에 추가하여 모든 대체 동작에서 작업을 시작하고 종료하는 간단한 제스처 제어 장치를 만들 수 있습니다.

시연을 위해 다시 LED를 사용하겠습니다. 모든 대체 동작에서 켜지고 꺼집니다.

/*
  Arduino Interrupt with PIR sensor and LED
  Written by : Kishor
  Tutorial : https://www.circuitgeeks.com
*/

const int ledPin = 7; // pin for the LED
const int PIRInterrupt = 3; // pin for the PIR sensor
volatile byte state = LOW; // variable to hold the LED State

void setup() {
  pinMode(ledPin, OUTPUT); // declare LED as output
  pinMode(PIRInterrupt, INPUT); // declare sensor as input
  // Call the motionDetected function when a rising edge is detected
  attachInterrupt(digitalPinToInterrupt(PIRInterrupt), motionDetected, RISING);
}

void loop() {
  // we dont need anything in the loop
}

void motionDetected() {
  state = !state; // change the LED state
  digitalWrite(ledPin, state); // assign the LED state to the LED.
}

PIR 모션 센서가 있는 버저

여기서는 물체를 감지할 때 소리를 생성하고 LED를 켜는 부저를 회로에 추가하는 방법을 살펴보겠습니다. 뒷마당에 PIR 센서를 설치하면 누군가가 귀하의 재산을 추적할 때 알림을 받을 수 있습니다.

버저에 익숙하지 않다면 내 Arduino 버저 튜토리얼을 읽어보세요 . 또한 Arduino Relay Tutorial을 따라 LED 대신 전구(120V)를 사용할 수도 있습니다 .

회로에 버저 추가

회로는 앞에서 설명한 대로 변경되지 않은 상태로 유지되므로 회로에 부저만 추가하면 됩니다. 버저의 양극(+) 핀을 Arduino 핀 7에 연결하고 다른 핀을 접지에 연결합니다. 버저와 직렬로 470옴 미만의 저항을 추가하면 버저의 볼륨을 줄일 수 있습니다. 저항이 높을수록 볼륨이 낮아집니다.

PIR 센서 부저 사이렌 코드

아래 코드는 움직임이 감지될 때마다 LED를 켜고 5초 동안 소리를 발생시킵니다.

/*
  Arduino PIR Interrupt with Buzzer and LED
  Written by : Kishor
  Tutorial : https://www.circuitgeeks.com
*/

const int PIRInterrupt = 3; // pin for the PIR sensor
const int buzzer = 5; // pin for the Buzzer
const int ledPin = 7; // pin for the LED
const int freqInterval = 10;

volatile byte motion = false; // flag

const long onTime = 5000; // LED and Buzzer on time after a motion is detected
unsigned long lastTrigger = 0; // last time the sensor was triggered
unsigned long lastFreqChange = 0; // last time the frequency was changed
int freq = 635;

void setup() {
  pinMode(ledPin, OUTPUT); // Set the LED pin as Output
  pinMode(buzzer, OUTPUT); // Set the Buzzer pin as Output
  digitalWrite(ledPin, LOW);
  pinMode(PIRInterrupt, INPUT);
  // call the motionDetected function when a rising edge is detected
  attachInterrupt(digitalPinToInterrupt(PIRInterrupt), motionDetected, RISING);
}

void loop() {
  if ((millis() - lastTrigger) < onTime && motion == true) {
    // during the interval period & if motion is true
    digitalWrite(ledPin, HIGH); // turn on the LED
    buzzerSiren(); // call the buzzerSiren function
  }
  else {
    digitalWrite(ledPin, LOW); // turn off the LED
    noTone(buzzer); // turn off the Buzzer
    freq = 635;
  }
}

void motionDetected() {
  lastTrigger = millis();
  motion = true;
}

void buzzerSiren() { // Function for the Buzzer sound
  tone(buzzer, freq);

  if (millis() - lastFreqChange > freqInterval) {
    lastFreqChange = millis();
    freq++;
  }
  if (freq > 912)
    freq = 635;
}

 

728x90