ESP32

ESP32 with PIR Motion Sensor using Interrupts and Timers

기하 2021. 8. 16. 06:16

이 튜토리얼은 PIR 모션 센서를 사용하여 ESP32로 모션을 감지하는 방법을 보여줍니다. 이 예에서 움직임이 감지되면(인터럽트가 트리거됨) ESP32는 타이머를 시작하고 미리 정의된 시간(초) 동안 LED를 켭니다. 타이머가 카운트다운을 마치면 LED가 자동으로 꺼집니다.

이 예제를 통해 인터럽트와 타이머라는 두 가지 중요한 개념도 살펴보겠습니다.

이 튜토리얼을 진행하기 전에 Arduino IDE에 ESP32 애드온이 설치되어 있어야 합니다. 아직 설치하지 않은 경우 다음 자습서 중 하나에 따라 Arduino IDE에 ESP32를 설치합니다.

비디오 자습서 및 프로젝트 데모 보기

이 튜토리얼은 비디오 형식(아래 보기)과 서면 형식(계속 읽기)으로 제공됩니다.

 

 

필요한 부품

이 튜토리얼을 따르려면 다음 부품이 필요합니다.

위의 링크를 사용하거나 MakerAdvisor.com/tools 로 직접 이동 하여 프로젝트에 필요한 모든 부품을 최적의 가격으로 찾을 수 있습니다!

인터럽트 소개

PIR 모션 센서로 이벤트를 트리거하려면 인터럽트를 사용합니다. 인터럽트는 마이크로컨트롤러 프로그램에서 자동으로 발생하도록 하는 데 유용하며 타이밍 문제를 해결하는 데 도움이 될 수 있습니다.

인터럽트를 사용하면 핀의 현재 값을 지속적으로 확인할 필요가 없습니다. 인터럽트를 사용하면 변경이 감지되면 이벤트가 트리거됩니다(함수가 호출됨).

Arduino IDE에서 인터럽트를 설정하려면 첨부 인터럽트() 인수로 받는 함수: GPIO 핀, 실행할 함수의 이름, 모드:

attachInterrupt(digitalPinToInterrupt(GPIO), function, mode);

GPIO 인터럽트

첫 번째 인수는 GPIO 번호입니다. 일반적으로 다음을 사용해야 합니다.디지털 핀투인터럽트(GPIO)실제 GPIO를 인터럽트 핀으로 설정합니다. 예를 들어 사용하려는 경우GPIO 27 인터럽트로 다음을 사용하십시오.

digitalPinToInterrupt(27)

ESP32 보드를 사용하면 다음 그림에서 빨간색 직사각형으로 강조 표시된 모든 핀을 인터럽트 핀으로 구성할 수 있습니다. 이 예에서 우리는GPIO 27 PIR 모션 센서에 연결된 인터럽트로.

 

트리거될 기능

의 두 번째 주장 첨부 인터럽트() function은 인터럽트가 트리거될 때마다 호출될 함수의 이름입니다.

방법

세 번째 인수는 모드입니다. 5가지 모드가 있습니다.

  • LOW: 핀이 LOW일 때마다 인터럽트를 트리거합니다.
  • 높은: 핀이 HIGH일 때마다 인터럽트를 트리거합니다.
  • 변화: 핀이 값을 변경할 때마다 인터럽트를 트리거합니다(예: HIGH에서 LOW 또는 LOW에서 HIGH로).
  • 떨어지는: 핀이 HIGH에서 LOW로 갈 때;
  • 상승: 핀이 LOW에서 HIGH로 갈 때 트리거합니다.

이 예에서는 PIR 모션 센서가 모션을 감지할 때 연결된 GPIO가 LOW에서 HIGH로 이동하기 때문에 RISING 모드를 사용합니다.

 

타이머 소개

이 예에서는 타이머도 소개합니다. 우리는 움직임이 감지된 후 미리 정해진 시간(초) 동안 LED가 켜져 있기를 원합니다. 를 사용하는 대신지연() 코드를 차단하고 정해진 시간(초) 동안 다른 작업을 수행할 수 없도록 하는 기능을 사용하려면 타이머를 사용해야 합니다.

지연() 함수

에 대해 잘 알고 있어야 합니다. 지연()널리 사용되는 기능입니다. 이 기능은 사용하기 매우 간단합니다. 단일 int 숫자를 인수로 허용합니다. 이 숫자는 프로그램이 다음 코드 줄로 이동할 때까지 기다려야 하는 시간(밀리초)을 나타냅니다.

delay(time in milliseconds)

당신이 할 때 지연(1000) 프로그램은 1초 동안 해당 라인에서 멈춥니다.

지연()차단하는 기능입니다. 차단 기능은 특정 작업이 완료될 때까지 프로그램이 다른 작업을 수행하지 못하도록 합니다. 동시에 여러 작업을 수행해야 하는 경우 사용할 수 없습니다.지연().

대부분의 프로젝트에서 지연 사용을 피하고 대신 타이머를 사용해야 합니다.

millis() 함수

라는 함수를 사용하여 밀리() 프로그램이 처음 시작된 이후 경과된 밀리초 수를 반환할 수 있습니다.

millis()

그 기능이 왜 유용한가요? 약간의 수학을 사용하면 코드를 차단하지 않고도 시간이 얼마나 지났는지 쉽게 확인할 수 있기 때문입니다.

millis()로 LED 깜박임

다음 코드 스니펫은 사용 방법을 보여줍니다. 밀리()깜박임 LED 프로젝트를 만드는 기능입니다. 1000밀리초 동안 LED를 켠 다음 끕니다.

/********* Rui Santos Complete project details at https://randomnerdtutorials.com *********/ // constants won't change. Used here to set a pin number : const int ledPin = 26; // the number of the LED pin // Variables will change : int ledState = LOW; // ledState used to set the LED // Generally, you should use "unsigned long" for variables that hold time // The value will quickly become too large for an int to store unsigned long previousMillis = 0; // will store last time LED was updated // constants won't change : const long interval = 1000; // interval at which to blink (milliseconds) void setup() { // set the digital pin as output: pinMode(ledPin, OUTPUT); } void loop() { // here is where you'd put code that needs to be running all the time. // check to see if it's time to blink the LED; that is, if the // difference between the current time and last time you blinked // the LED is bigger than the interval at which you want to // blink the LED. unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { // save the last time you blinked the LED previousMillis = currentMillis; // if the LED is off turn it on and vice-versa: if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } // set the LED with the ledState of the variable: digitalWrite(ledPin, ledState); } }

 

원시 코드 보기

코드 작동 방식

없이 작동하는 이 깜박임 스케치를 자세히 살펴보겠습니다. 지연() 기능(사용 밀리() 대신 기능).

기본적으로 이 코드는 이전에 기록된 시간을 뺍니다(이전밀리) 현재 시간(현재밀리). 나머지가 간격(이 경우 1000밀리초)보다 크면 프로그램은이전밀리 현재 시간으로 변경하고 LED를 켜거나 끕니다.

if (currentMillis - previousMillis >= interval) { // save the last time you blinked the LED previousMillis = currentMillis; (...)

이 스니펫은 비차단이므로 해당 코드 밖에 있는 모든 코드는 만약 문이 정상적으로 작동해야 합니다.

 

이제 다른 작업을 추가할 수 있다는 것을 이해할 수 있어야 합니다. 고리() 기능과 코드는 여전히 1초마다 LED를 깜박입니다.

이 코드를 ESP32에 업로드하고 다음 회로도를 조합하여 테스트하고 밀리초 수를 수정하여 작동 방식을 확인할 수 있습니다.

참고 : ESP32에 코드를 업로드하는 데 문제가 있는 경우 ESP32 문제 해결 가이드를 살펴보세요 .

PIR 모션 센서가 있는 ESP32

인터럽트와 타이머라는 개념을 이해한 후 프로젝트를 계속 진행해 보겠습니다.

개략도

우리가 만들 회로는 조립하기 쉽고 저항이 있는 LED를 사용할 것입니다. LED가 연결되어 있습니다.GPIO 26. 3.3V에서 작동 하는 Mini AM312 PIR 모션 센서를 사용할 것 입니다. 에 연결됩니다GPIO 27. 다음 회로도를 따르기만 하면 됩니다.

 

중요 : 미니 AM312 PIR 모션 센서  이 프로젝트에 사용이 3.3V에서 동작한다. 그러나 HC-SR501 과 같은 다른 PIR 모션 센서를 사용하는 경우  5V에서 작동합니다. 3.3V에서 작동 하도록  수정  하거나 Vin 핀을 사용하여 전원을 공급할 수 있습니다.

다음 그림은 AM312 PIR 모션 센서 핀아웃을 보여줍니다.

코드 업로드

회로도와 같이 회로를 배선한 후 제공된 코드를 Arduino IDE에 복사합니다.

코드를 그대로 업로드하거나 모션 감지 후 LED가 켜지는 시간(초)을 수정할 수 있습니다. 간단히 변경시간초 원하는 초 수로 변수.

/********* Rui Santos Complete project details at https://randomnerdtutorials.com *********/ #define timeSeconds 10 // Set GPIOs for LED and PIR Motion Sensor const int led = 26; const int motionSensor = 27; // Timer: Auxiliary variables unsigned long now = millis(); unsigned long lastTrigger = 0; boolean startTimer = false; // Checks if motion was detected, sets LED HIGH and starts a timer void IRAM_ATTR detectsMovement() { Serial.println("MOTION DETECTED!!!"); digitalWrite(led, HIGH); startTimer = true; lastTrigger = millis(); } void setup() { // Serial port for debugging purposes Serial.begin(115200); // PIR Motion Sensor mode INPUT_PULLUP pinMode(motionSensor, INPUT_PULLUP); // Set motionSensor pin as interrupt, assign interrupt function and set RISING mode attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING); // Set LED to LOW pinMode(led, OUTPUT); digitalWrite(led, LOW); } void loop() { // Current time now = millis(); // Turn off the LED after the number of seconds defined in the timeSeconds variable if(startTimer && (now - lastTrigger > (timeSeconds*1000))) { Serial.println("Motion stopped..."); digitalWrite(led, LOW); startTimer = false; } }

 

원시 코드 보기

참고: ESP32에 코드를 업로드하는 데 문제가 있는 경우 ESP32 문제 해결 가이드를 살펴보세요 .

코드 작동 방식

코드를 살펴보겠습니다. 2개의 GPIO 핀을 할당하여 시작합니다.~ 주도의 그리고 모션센서 변수.

// Set GPIOs for LED and PIR Motion Sensor const int led = 26; const int motionSensor = 27;

그런 다음 움직임이 감지된 후 LED를 끄도록 타이머를 설정할 수 있는 변수를 만듭니다.

// Timer: Auxiliar variables long now = millis(); long lastTrigger = 0; boolean startTimer = false;

 

NS 지금변수는 현재 시간을 보유합니다. NS마지막 트리거변수는 PIR 센서가 움직임을 감지하는 시간을 유지합니다. NS시작 타이머 움직임이 감지되면 타이머를 시작하는 부울 변수입니다.

설정()

에서 설정(), 직렬 포트를 115200 전송 속도로 초기화하여 시작합니다.

Serial.begin(115200);

PIR 모션 센서를 INPUT PULLUP으로 설정합니다.

pinMode(motionSensor, INPUT_PULLUP);

PIR 센서 핀을 인터럽트로 설정하려면 첨부 인터럽트() 앞에서 설명한 대로 기능합니다.

attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);

움직임을 감지하는 핀은 GPIO 27 그리고 그것은 함수를 호출할 것입니다 움직임 감지() 상승 모드에서.

LED는 상태가 LOW에서 시작하는 OUTPUT입니다.

pinMode(led, OUTPUT); digitalWrite(led, LOW);고리()

NS 고리()기능은 계속해서 계속해서 실행됩니다. 모든 루프에서지금 변수는 현재 시간으로 업데이트됩니다.

now = millis();

다른 작업은 수행되지 않습니다. 고리().

그러나 움직임이 감지되면 움직임 감지() 함수는 이전에 인터럽트를 설정했기 때문에 호출됩니다. 설정().

NS 움직임 감지() 기능은 직렬 모니터에 메시지를 인쇄하고 LED를 켜고 설정합니다. 시작 타이머 부울 변수 진실 그리고 업데이트 마지막 트리거 현재 시간으로 변수.

void IRAM_ATTR detectsMovement() { Serial.println("MOTION DETECTED!!!"); digitalWrite(led, HIGH); startTimer = true; lastTrigger = millis(); }

 

메모: IRAM_ATTR RAM에서 인터럽트 코드를 실행하는 데 사용됩니다. 그렇지 않으면 코드가 플래시에 저장되고 속도가 느려집니다.

이 단계가 끝나면 코드는 고리().

이번에는, 시작 타이머변수는 참입니다. 따라서 초 단위로 정의된 시간이 경과하면(움직임이 감지된 이후) 다음과 같이 표시됩니다.만약 진술은 사실일 것이다.

if(startTimer && (now - lastTrigger > (timeSeconds*1000))) { Serial.println("Motion stopped..."); digitalWrite(led, LOW); startTimer = false; }

"동작이 중지되었습니다..." 메시지가 직렬 모니터에 인쇄되고 LED가 꺼지고 startTimer 변수가 false로 설정됩니다.

데모

ESP32 보드에 코드를 업로드합니다. 올바른 보드와 COM 포트를 선택했는지 확인하십시오.

115200의 전송 속도로 직렬 모니터를 엽니다.

PIR 센서 앞에서 손을 움직입니다. LED가 켜지고 시리얼 모니터에 "MOTION DETECTED!!!"라는 메시지가 출력됩니다. 10초 후에 LED가 꺼집니다.

 

마무리

결론적으로 인터럽트는 현재 GPIO 값을 지속적으로 읽을 필요 없이 GPIO 상태의 변화를 감지하는 데 사용됩니다. 인터럽트를 사용하면 변경이 감지되면 기능이 트리거됩니다. 또한 코드를 차단하지 않고도 미리 정의된 시간(초)이 경과했는지 확인할 수 있는 간단한 타이머를 설정하는 방법을 배웠습니다.

ESP32와 관련된 다른 자습서도 있습니다.

이것은 우리 과정에서 발췌한 것입니다:  Arduino IDE로 ESP32 배우기 . ESP32가 마음에 들고 더 자세히 알고 싶다면 Arduino IDE로 ESP32 배우기 과정에 등록하는 것이 좋습니다  .

읽어 주셔서 감사합니다.