아두이노

아두이노 GPIO 인터럽트(Interrupt)

CreatoMaestro 2023. 12. 28. 19:32
반응형

인터럽트란 무엇이고, 언제 쓰는가

아두이노로 무언가 하다 보면 중간에 다른 일을 해야 할 때가 있습니다.

예를 하나 들어봅시다.

 

아두이노가 LED를 깜박이고 있습니다.

이때 버튼이 눌리면 LED를 껴야 합니다.

 

그래서 우리는 digitalRead를 이용해 스위치의 입력을 받을 수 있게 해놨습니다.

다음과 같이 말이죠.

 


bool LED_ON = true;
void setup() {
  // put your setup code here, to run once:
  pinMode(13,OUTPUT);
  pinMode(12, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(digitalRead(12)) {
    LED_ON = !LED_ON;
  }
  if(LED_ON) {
    digitalWrite(13, 1);
    delay(1000);
    digitalWrite(13, 0);
    delay(1000);
  } else {
    digitalWrite(13, 0);
  }
 
}

 

이 코드에서 LED_ON은 LED를 깜박일지를 저장하는 변수입니다.

true면 LED를 깜박이고, false면 LED를 끕니다.

스위치를 누르면 LED_ON의 상태가 바뀌도록 했습니다.

 

이렇게 코드를 짜고 스위치를 눌렀는데 LED가 꺼지지 않습니다.

이게 어떻게 된 일일까요?

 

아두이노는 한번에 하나의 일만 할 수 있습니다.

그렇기 때문에 위에서 LED를 깜박이는 동안에는 스위치의 입력을 받지 못합니다.

때문에 우리가 정확한 타이밍에 스위치를 누르지 않는 이상

아두이노는 우리가 원하는 대로 동작하지 않을 것입니다.

 

이럴 때 사용하는 것이 인터럽트(Interrupt)입니다.

인터럽트는 아두이노에게 어떤 일이 일어나면 알람을 보내

아두이노가 하던 일을 멈추고 일에 대한 처리를 할 수 있도록 해줍니다.

 

GPIO인터럽트 사용하기

아두이노에서 Interrupt를 사용하기 위해선 다음과 같이 쓰면 됩니다.

 
pinMode(2,INPUT);
attachInterrupt(digitalPinToInterrupt(2), interrupt_uart, RISING);
 

 

우선 인터럽트를 사용할 핀을 INPUT으로 설정해줍니다.

그리고 INPUT으로 설정한 핀을 인터럽트 핀으로 설정해 줍니다.

 

이때 사용하는 함수가 digitalPinToInterrupt()입니다.

소괄호 안에 인터럽트로 사용할 핀을 넣어주면 됩니다.

 

이 때 주의해야 할 점이 하나 있습니다.

아두이노 우노에서 인터럽트로 사용할 수 있는 핀은 2,3번으로 정해져 있습니다.

다른 핀은 인터럽트로 사용하지 못합니다.

 

인터럽트 핀을 설정했다면 attachIinterrupt로 호출함수와 이벤트를 정의해줍니다.

호출함수는 인터럽트가 발생했을 때 실행하는 함수입니다.

이벤트는 인터럽트 핀에 어떤 변화가 생길 때 인터럽트를 걸지 결정하는 핀입니다.

attachInterrupt(digitalPinToInterrupt(인터럽트 핀), 호출함수, 이벤트)와 같이 쓰면 됩니다.

 

인터럽트 사용해보기

이제 인터럽트를 사용해 보겠습니다.


bool LED_ON = true;
void setup() {
  // put your setup code here, to run once:
  pinMode(13,OUTPUT);
  pinMode(2, INPUT);
  attachInterrupt(digitalPinToInterrupt(2), interrupt, RISING);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(LED_ON) {
    digitalWrite(13, 1);
    delay(1000);
    digitalWrite(13, 0);
    delay(1000);
  } else {
    digitalWrite(13, 0);
  }
 
}

void interrupt() {
  LED_ON = !LED_ON;
  if(!LED_ON){
    digitalWrite(13, 0);
  }
  while(digitalRead(2));
}

 

위 코드는 앞서 설명한 코드를 인터럽트를 이용해 구현한 것입니다.

여기서는 2번 핀을 인터럽트로 설정해 주었고, 호출함수는 interrupt,

이벤트를 RISING 이벤트로 설정해 주었습니다.

 

이렇게 설정하면 아두이노로 들어가는 입력이 0에서 1로 변할 때

interrupt 함수가 실행됩니다.

 

interrupt 함수 안에서는 LED_ON 변수의 상태를 바꾸고,

만약 LED_ON이 false이면 LED를 끄도록 설정했습니다.

 

마지막의 while(digitalRead(2))는

스위치에서 발생되는 damping의 영향을 줄이기 위한 코드입니다.

 

회로는 다음과 같이 구성하시면 됩니다.

GPIO 인터럽트 회로도
회로 구성

LED는 13번 핀에 연결하시고, 버튼은 풀다운 저항으로 연결하시면 됩니다.

 

지금까지 GPIO 인터럽트에 대해 알아봤습니다.

반응형