[아두이노] 인터럽트(Interrupt) 제어

IOT/아두이노|2019. 2. 28. 09:00

[아두이노] 인터럽트(Interrupt) 제어



오늘은 인터럽트에 대해서 배워보도록 하겠습니다. 아두이노에서 인터럽트를 이용해서 예의치 못한 상황이 발생할때 중간에 개입하여 해결하는데 사용됩니다. 계속 센서값을 읽는 것에 대한 주제로 부품의 사용 설명을 해야 하는데 중간에 좀 코딩에 관련된 주제로 포스팅을 하게 되었었네요. 우선 이부분을 알고 계속 부품 사용을 살펴보는게 더 나을것 같다는 생각에 먼저 소개 합니다.

1. 인터럽트


인터럽트는 현재 프로그램이 수행 도중에 어떤 도출 상황이 발생하면 수행중인 프로그램을 일시 중단 시키고 도출 상황에 대한 특정 해결 동작을 수행하도록 하는게 인터럽트라고 생각 하시면 됩니다.

예를 들면은 요리사가 요리을 만들어 A라는 사람에게 대접하고 A는 맛있게 요리를 먹습니다.

  • 인터럽트 발생 : 갑자기 B라는 사람이 왔다.
  • 특정 동작 수행 : 요리사는 숟가락 하나를 B에게 건내서 같이 먹도록 하게 한다.
  • A는 계속 요리를 맛있게 먹고 B도 숟가락을 받은 후 A랑 같이 많있게 요리를 먹는다.

어떤 의미인지 아시겠지요. loop()함수에서 기본 아두이노 동작을 수행합니다. 그 동작을 수행할 때에 예기치 못한 상황이 발생하면 그 문제를 해결하기 위한 처리 동작이 필요합니다. 그래서 인터럽트 함수를 사용하게 되는 것이죠.

아두이노우노는 2.3번핀 인터럽트 핀이고 아두이노 종류에 따라서 인터럽트에 사용되는 핀의 갯수와 핀 번호가 각각 다릅니다 아두이노 종류에 따라서 잘 확인하시고 인터럽트 함수를 사용하시면 됩니다. 자세히 알고 싶으면 위에 링크한 참고자료에 가시면 아두이노 종류별 인터럽트 핀에 대해 잘 나와 있으니깐 참고하시면 됩니다.

표현형식

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); //권장
attachInterrupt(interrupt, ISR, mode); 
attachInterrupt(pin, ISR, mode) ; 

세가지 방법이 있는데 첫번째 권장 함수를 사용하세요. 물론 아두이노우노에서 다른 형식도 동작은 하는데 모드마다 제약이 따르기 때문에 권장함수로 표현을 하고 이해하시는게 편하실꺼에요.

함수

attachInterrupt(digitalPinToInterrupt(interruptPin), exchange, FALLING);

attachInterrupt(인터럽트핀, 호출함수, 상태조건)로 해서 setup()함수에 선언하기만 하면 알아서 인터럽트가 발생하면 호출이 됩니다. 동작은 해당 인터럽트핀이 특정 상태조건이 되면 호출함수가 호출됩니다. 이것만 이해하시면 오늘은 내용은 끝입니다.

상태조건은

LOW    :   LOW 상태일 때
CHANGE :  입력 값이 변할때
RISING   :  LOW -> HIGH로 변할때
FALLING :  HIGH -> LOW로 변할때

HIGH      :  HIGH 상태일 때 (rduino Due, Zero, MKR1000 만 허용)

실험에서는 내부풀업저항을 사용하는 스위치 버턴이 초기 상태값이 HIGH이니깐 스위치를 누르면 LOW가 됩니다. 고로 스위치를 누른 순간 HIGH->LOW로 FALLING 상태가 되는 것이죠. 인터럽트핀 2 or 3번 핀에 FALLING상태가 되면 exchange()함수가 호출되는 게 기본 동작입니다. 여기서 exchange라는 단어가 함수명으로 고정이 아니라 마음대로 test1이라고 해도 됩니다.

아래 예제처럼 함수를 표현하시면 됩니다.

attachInterrupt(digitalPinToInterrupt(interruptPin), test1, FALLING);
void test1()
{
  동착;
}

어떤 느낌인지 아시겠지요.

2. 회로도 구성


  • 준비물 : LED 3개, 저항 220옴 3개, 스위치버턴 2개, 아두이노우노, 뻥판
  • 내용 : 인터럽트 발생을 스위치버턴을 활용하고 그 결과를 LED(발광다이오드)에 불이 들어오게 한다.

회로도를 보면 스위치버턴에 저항이 붙어있지 않다. 즉, 내부풀업저항을 이용한다는 것이고 11,12,13번 핀으로 출력값으로 LED에 불이 들어오게 하는 기본 회로도 입니다. 복습차원으로 LED 제어와 스위치버턴 제어를 합쳐서 인터럽트 실험을 하기 위한 회로도 입니다.

3. 코딩


  • 사용함수 : pinMode(), digitalWrite, attachInterrupt(),analogRead()
  • 내용 : 간단히 가변저항 조절기로 조절하면 흐를 전류를 조절할 수 있고 그 조절된 전류 값을 3색 LED에 출력값으로 해서 색을 자유롭게 만들어 낸다.
  • 참고 : [아두이노] LED 제어(아두이노)

복습

  • pinMode(사용핀, OUTPUT) : 사용핀은 출력모드
  • pinMode(사용핀, INPUT_PULLUP) : 사용핀은 내부풀업저항을 이용한 입력모드
  • attachInterrupt(digitalPinToInterrupt(2~3번핀), exchange1, FALLING) : 인터럽트 2~3번핀이 HIGH->LOW로 바뀌면 exchange1 함수를 호출한다.
  • digitalWrite(사용핀, 상태) : 디지털출력핀에 상태가 HIGH(5V) or LOW(0V)를 선택한다.

설계

  1. Red LED은 loop()함수에서 기본동작으로 1초단위로 깜박이게 해야지
  2. Green LED은 2번 인터럽트가 누르면 불이 들어오고 다시 누르면 꺼지게 해야지
  3. Blue LED은 3번 인터럽트가 누르면 불이 들어오고 다시 누르면 꺼지게 해야지
  4. 인터럽트 2,3번 핀을 변수로 선언하고 RGB핀을 각각 변수로 우선 만들어 놔야지
  5. 인터럽트 호출함수를 setup()내에 선언하고 두개를 사용하니깐 두개의 호출될 함수를 만들어 놔야 겠군.
  6. loop()함수 안에다가 Red LED가 기본동작으로 1초 깜박이는 로직을 표현해야지
  7. 인터럽트 호출 함수 exchange1,2는 누를때마다 불이 들어왔다 나갔다 해야하니깐 상태변수를 하나 선언해서 True(1)일때 불이 들어오고 False(0)일때 불이 꺼지게 if문으로 상태변환을 시킬 수 있게 조건문 만들어야 겠다. 그러면 초기 상태변수는 False로 해 놔야지 우선 꺼진상태가 되겠군
  8. 이제 이 글을 코딩으로 바꿔야겠다.

인터럽트 호출시 호출함수내에서 상태변환

  if(state1==false){
    digitalWrite(blue, HIGH);
    state1=true;
  }else{
    digitalWrite(blue, LOW);
    state1=false;
  }

인터럽트 호출된 함수 내에서 state1은 초기값이 false이면 true로 변환 state1이 true이면 false로 변환을 if문으로 바꾸게 됩니다.

더 쉽게 표현을 하자면

state=!state;
digitalWrite(blue,state);

이렇게하면 state의 현재상태를 계속 반전 시키게 됩니다.

코딩을 전체적으로 하면

int red = 13; 
int blue = 12;
int green = 11;
int interruptPin1 = 2;
int interruptPin2 = 3;
boolean state1 = false;
boolean state2 = false;

void setup() {
  pinMode(red, OUTPUT);
  pinMode(blue, OUTPUT);
  pinMode(interruptPin1, INPUT_PULLUP);
  pinMode(interruptPin2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin1), exchange1, FALLING);
  attachInterrupt(digitalPinToInterrupt(interruptPin2), exchange2, FALLING);
}

void loop() {
  
  digitalWrite(red, HIGH);
  delay(1000);
  digitalWrite(red, LOW);
  delay(1000);
  
}

void exchange1() {
  if(state1==false){
    digitalWrite(blue, HIGH);
    state1=true;
  }else{
    digitalWrite(blue, LOW);
    state1=false;
  }
}
void exchange2() {
  if(state2==false){
    digitalWrite(green, HIGH);
    state2=true;
  }else{
    digitalWrite(green, LOW);
    state2=false;
  }
}

4. 결과


회로도와 코딩을 가상시뮬레이터에서 디자인하고 코딩을 복사해서 붙이고 실행 시켜보세요. 스위치 버턴을 누르면 인터럽트가 발생하하여 해당 LED에 불이 들어오는걸 확인하실 수 있을거에요. 여기수 주 동작인 Red LED는 인터럽트 발생과 상관없이 규칙적으로 1초 단위로 깜박입니다. 인터럽트가 어떤 느낌인지 잘 생각해보세요.

마무리


인터럽트는 끼어들기 함수라고 생각하시면 돼요. 기본 메인 동작을 수행하는 도중에 어떤 돌출된 상황이 발생하면 그 상황을 메인 동작에 영향을 안주는 선에서 끼여들어서 그 상황을 해결하는 특정 동작을 수행하고 그 뒤에 메인 동작은 연속해서 하고자 하는 일을 하게 됩니다.

이런 원리를 이용하여 아두이노에서 어떤곳에서 활용하면 좋을지 상상의 나래를 펼쳐보세요.


댓글()