인터럽트는 지정된 핀의 input 상태가 원하는 조건와 일치하면 미리 등록한 인터럽트 callback 함수(ISR, Interrupt Service Routines)를 자동으로 호출해주는 기능입니다. 이때 실행중이던 loop() 함수 안의 루틴은 인터럽트 callback 함수가 끝날 때 까지 대기상태가 됩니다.
즉, 특정 핀의 입력 상태가 바뀔때 아두이노는 이를 자동으로 감지해서 모든 동작을 잠시 멈춘 다음, ISR(Interrupt Service Routines) 이라 불리는 미리 지정된 함수를 실행하고, 다시 원래 작업으로 복귀합니다. 이를 하드웨어 인터럽트라 부릅니다. 이 외에도 타이머(timer) 인터럽트가 있는데 이건 사용 방법이 전혀 다르므로 여기서는 다루지 않습니다.
인터럽트는 Signal 상태에 따라 자동으로 특정 동작을 수행할 수 있도록 해주며, 타이밍 문제를 해결 할 수 있는 강력한 기능입니다. 주로 Rotary encoder, User input 등 을 처리하거나 모션센서 시그널을 모니터링 할 때 사용되곤 합니다.
아두이노는 인터럽트를 지원하기 위해 몇 개의 핀을 인터럽트 핀으로 지정해 두었습니다. 하드웨어 인터럽트는 이 핀을 통해서만 동작합니다.
아두이노 인터럽트 핀
UNO 기준으로 2개의 인터럽트 핀이 할당되어 있습니다. Number 0 (D2), Number 1 (D3). 각 보드별 지원되는 인터럽트 핀은 아래와 같습니다. 인터럽트 callback (ISR) 을 등록할 때 핀 번호가 아니라 인터럽트 넘버를 사용한다는 점에 주의!
Board int.0 int.1 int.2 int.3 int.4 int.5
Uno, Ethernet 2 3
Mega2560 2 3 21 20 19 18
Leonardo 3 2 0 1 7
Arduino Due 보드는 모든 핀에 인터럽트가 지원됩니다.
주의 사항
- 인터럽트 callback 함수(ISR, Interrupt Service Routines)는 파라미터를 전달하거나 리턴할 수 없습니다. void xxx_callback() 형태가 됩니다.
- ISR 안에서는 delay() 함수를 사용할 수 없습니다.
- 그리고 milli-단위의 시각을 가져오는 함수인 millis() 를 사용하더라도 값이 증가하지 않습니다. delayMicroseconds() 의 경우에는 인터럽트에 독립적이므로 정상 동작합니다.
- ISR 안에서 Serial data를 읽을 경우 값이 소실됩니다.
- ISR 안에서 수정되는 전역 변수는 volatile 로 선언되어야 합니다.
- ISR 은 최대한 짧고 빠르게 수행되도록 작성해야 합니다.
- 여러개의 ISR이 등록되어 있더라도 동시에 수행되지는 않습니다.
- 블루투스 모듈과의 통신을 위해 주로 사용되는 SoftwareSerial 라이브러리의 경우 내부적으로 인터럽트를 사용하는 것으로 알려져 있습니다. 따라서 UNO 보드의 경우 D2, D3 에 연결해야만 정상동작 합니다. 이를 회피하기 위해서 D0, D1 핀에 연결해서 Hardware Serial 로 동작시킬 수 있습니다.
인터럽트 등록 함수
void attachInterrupt(interrupt, ISR, mode)
interrupt: 인터럽트 번호, 핀 번호 아님! 아두이노 DUE 보드만 핀 번호로 사용. (int)
ISR: 인터럽트가 발생할 때 수행할 callback 함수
mode: 인터럽트가 수행될 조건
LOW: pin 이 LOW 상태일 때
CHANGE: pin 입력 값이 변경 될 때
RISING: LOW -> HIGH 로 변경 될 때
FALLING: HIGH -> LOW 로 변경 될 때
(HIGH: HIGH 상태일 때 – 아두이노 DUE 에서만 지원)