Arduino / / 2022. 5. 20. 20:02

[PlatformIO] 아두이노 인터럽트 사용하기

728x90

해당 게시물에서는 VS Code PlatformIO를 사용합니다. 참고바랍니다.

안녕하세요 데브구일입니다!

 

이번엔 인터럽트(Interrupt)에 대해 알아보겠습니다.

조금 복잡할 수도 있으니 천천히 읽어보세요! (최대한 쉽게 설명하려고 애썼습니다 T^T)

 

아두이노에서 인터럽트는 프로그램 실행 중에 인터럽트 조건을 만족하는 순간,

현재 상황을 잠시 중단하고 인터럽트 함수에 따른 기능을 실행한 뒤,

다시 원래 상황으로 돌아와 기능을 실행하는 기능입니다!

 

...

 

무슨 말인지 조금 헷갈릴 수도 있는데요!

아래 그림이랑 같이 예를 한번 들어볼게요!

 

A는 부모님이 전화 오시기로 했고 (인터럽트 조건 설정),

넷플릭스를 시청하고있다가, (프로그램 진행 중)

 

부모님께 전화가 왔습니다! (인터럽트 발생)

 

그럼 A는 잠시 넷플릭스를 보던 걸 일시중지하고, (현재 시점 중단 및 기억)

부모님과 통화를 잠시 하다가 (인터럽트 함수 실행)

 

통화를 끝내고 나서, (인터럽트 함수 종료)

 

다시 넷플릭스를 시청하겠지요! (이전 프로그램 시점으로 복귀)

 

 

그림 보시고 이해 하는데 도움이 되시면 좋을 것 같습니다!

 

이어서 코드를 한번 구현해보도록 하겠습니다.

 

#include <Arduino.h> // PlatformIO를 사용하시는게 아니라면 이 라인은 지워주세요!

#define INTERRUPT_PIN 2 // 인터럽트 핀 설정
#define LED_PIN 6 // LED핀 설정

volatile byte state = LOW;

void blink() {  // 인터럽트 함수 설정
  state = !state;
}

void setup() {
  pinMode(LED_PIN, OUTPUT);
  pinMode(INTERRUPT_PIN, INPUT_PULLUP);  // pinMode INPUT_PULLUP 설정
  
  // 인터럽트 조건 및 함수 설정
  attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), blink, FALLING);
}

void loop() {
  digitalWrite(LED_PIN, state);
  delay(10);
}

 

반응형

 

위 코드를 주요 부분들을 살펴보도록 하겠습니다.

 

---------------------------------------------

첫 번째로 INTERRUPT_PIN을 D2번 핀으로 설정 하였는데요.

디지털 2번 핀으로 설정을 한 이유가 있습니다.

 

인터럽트의 경우 사용 가능한 핀이 정해져있습니다!

아래 표를 보시면 보드에서 사용하는 칩의 기반이 어떤 것이냐에 따라서,

사용 가능 핀이 다른 것을 확인하실 수 있습니다.

 

공식 레퍼런스 문서를 보시면 더 다양한 보드에 대해 나와 있습니다!

(저는 제가 사용해봤던 보드만 적어봤어요!)

---------------------------------------------

두 번째로 state 변수 앞에 volatile을 선언하였는데요.

 

원래 컴파일러가 컴파일을 하면서 자체적으로 최적화가 가능한 부분이 있는 경우,

자동으로 최적화를 해버리게 됩니다!

 

이때 volatile을 선언하게되면 그 변수의 경우 최적화에서 제외되게 됩니다.

쉽게 설명하자면 컴파일러가 따로 건들지 않고 그대로 컴파일 한다는 말이 되겠네요!

아두이노 공식 레퍼런스에서는 인터럽트에서 사용되는 변수는 volatile을 선언하라는 내용이 나와있습니다.

 

---------------------------------------------

세 번째로 attachInterrupt()라는 함수를 사용하는데요.

attachInterrupt()는 인터럽트를 설정하는 함수 입니다.

 

함수의 파라미터를 먼저 알아보면

attachInterrupt(인터럽트 핀, ISR, mode) 입니다.

 

하나씩 알아보도록 할게요!

1. 인터럽트핀은 위에서 보았던 D2핀을 사용합니다.

하지만, 여기서 아두이노 공식 레퍼런스를 살펴보면 추천하는 사용방법이 있습니다.

그냥 핀 번호만 입력 하는 것이 아닌 digitalPinToInterrupt()를 사용하는 것 입니다.

저희도 digitalPinToInterrupt()를 사용하도록 하겠습니다

 

2. ISR은 Interrupt Service Routine의 약자이며,

인터럽트가 발생했을때 실행될 함수명을 입력해 주면됩니다!

저는 여기서 blink()라는 함수를 따로 만들어주었고, LED의 상태를 바꾸는 함수인데요.

 

여기서 ISR은 주의해야 할 점이 있습니다!

(1) 인터럽트가 발생되었을 때 ISR에서는 가능한 한 짧고 빨라야 합니다.

(2) ISR은 파라미터를 가질 수 없으며, 반환하지 않아야 합니다.

(3) delay()를 사용해서는 안됩니다.

(4) 사용되는 변수의 경우 volatile을 선언해야 합니다.

(5) ISR은 한 번에 하나만 실행할 수 있습니다.

 

3. mode는 인터럽트가 발생하기 위한 조건으로 보시면 됩니다.

아두이노에서 인터럽트는 아래와 같이 5가지의 모드를 가지고 있습니다.

예를 들어 버튼을 누를 때 신호가 HIGH -> LOW 상태로 바뀐다면,(FALLING)

이 바뀌는 순간을 인식하여 인터럽트가 발생하게 됩니다.

 

공식 레퍼런스 문서는 아래 링크를 참고해주세요!

 

 

attachInterrupt() - Arduino Reference

Example Code const byte ledPin = 13; const byte interruptPin = 2; volatile byte state = LOW; void setup() { pinMode(ledPin, OUTPUT); pinMode(interruptPin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE); } void loop() { d

www.arduino.cc

 

코드를 업로드 하시고 버튼을 눌러보시면 FALLING으로 선언하였기 때문에

버튼을 누르는 순간 LED가 켜지고, 버튼에서 손은 때면 반응이 없을 것입니다.

그리고 다시 누르는 순간 다시 LED가 꺼지게 될 것입니다!

 

한번 인터럽트에 mode를 변경해서 해보시면 이해하시는데 도움이 되실겁니다 :D

 

오늘은 여기까지이며, 다음 포스팅으로 돌아오겠습니다 :D

 

감사합니다 :D

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유