인터럽트에 해당하는 글 1

[아두이노] 타이머를 이용한 인터럽트(Interrupt) 제어

IOT/아두이노|2019. 3. 1. 09:00

[아두이노] 타이머를 이용한 인터럽트(Interrupt) 제어



어제는 인터럽트 핀을 이용한 하드웨어 인터럽트에 대해 살펴보았습니다. 오늘은 타이머 함수를 이용한 인터럽트를 배워보도록 하죠. 위 참고자료의 해당된 링크로 가시면 MsTimer2 and FlexiTimer2 라이브러리가 있는데 그중에서 MsTimer2 라이브러리를 선택하여 실험해 보도록 하겠습니다.

1. 타이머를 이용한 인터럽트


  • MsTimer2 함수
MsTimer2::set(unsigned long ms, void (*f)()) //타이머 세팅
MsTimer2::start() //타이머 시작
MsTimer2::stop() //타이머 종료

대충 보시면 함수가 그렇게 어렵지 않죠

예)

MsTimer2::set(500, flash) 

0.5초 간격으로 flash 함수를 호출한다고 세팅합니다. start() 함수는 타이머를 시작하라는 명령이고 stop() 함수가 선언되지 않는 이상 아두이노는 0.5초 간격으로 무조건 flash()함수를 호출하게 됩니다.

FlexiTimer2 라이브러리도 비슷하니깐 한번 링크된 곳에 가셔서 보시면 대충 이해가 되실꺼에요.

2. 회로도 구성


  • 준비물 : LED 2개, 저항 220옴 2개, 아두이노우노, 뻥판
  • 내용 : 타이머 인터럽트를 발생시킨 결과를 Blue LED(발광다이오드)에 불이 들어오게 하고 기본 동작은 Red LED(발광다이오드)에는 불이 들오게 한다.


회로도를 보면 간단합니다. 12번 핀에 MsTimer2를 이용해서 0.5초 시간이 되면 5V의 전류를 보내 Blue LED를 제어하고 13번 핀은 loop()함수에서 1초 단위로 불이 깜박이게 할 예정입니다. 여기서 loop()함수의 1초 단위로 깜박이는 기본동작과 상관없이 강제적으로 인터럽트를 발생시켜서 12번핀에 전류 공급을 공급하게 됩니다.
쉽게 말해서 1초 단위로 깜박이는 로직이 있는데 어떤 라인의 명령이 수해되고 있던 상관없이 타이머 시간이 되면 강제적으로 특정 동작을 수행하게 만든다고 생각하시면 됩니다.

3. 코딩


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

복습

  • pinMode(사용핀, OUTPUT) : 사용핀은 출력모드
  • digitalWrite(사용핀, 상태) : 디지털출력핀에 상태가 HIGH(5V) or LOW(0V)를 선택한다.
  • MsTimer2::set(호출시간, 호출함수명) : 타이머 세팅(500은 0.5초라는 것만 기억)
  • MsTimer2::start() : 타이머 시작
  • MsTimer2::stop() : 타이머 종료

설계

  1. Red LED은 loop()함수에서 기본동작으로 1초단위로 깜박이게 해야지
  2. Blue LED은 0.5초 간격으로 깜박이게 해야지

코딩을 전체적으로 하면

이 예제가 너무 잘 코딩 되어있는 거라서 따로 코딩 예제를 안만들고 인용을 하겠습니다. 메인 동작은 Red 핀이 1초 단위로 loop()함수 내에서 반복합니다. 타이머 함수의 경우는 setup() 함수에서 한번만 선언하면 됩니다. 왜냐면 loop()에 선언한다고 생각을 해보세요. 매번 타이먼을 세팅하고 타이머를 시작하고 거기다가 중요한것은 loop()에 넣으면 타이머가 loop() 반복순환문에 일부가 되어서 타이머 자체가 loop()의 기본동작이 되어 버리게 됩니다. 결론은 setup()함수에서 타이머를 작동시키고 loop()은 자신의 기본동작만 수행해서 타이머는 별거의 존재로 동작하도록 배치해야겠죠.

하지만 MsTimer2::start() or MsTimer2::stop() 함수는 loop()안에 넣을 수 있습니다. 타이머를 무조건적으로 동작시킨다면 setup()함수에서 선언하는게 맞지만 loop()함수내에서 타이머가 원하는 조건을 충족하기 전까지는 타이머를 동작안시키고 충족되면 타이머를 동작하게 할 수 있는 로직으로 표현 할 때 loop()함수 내에서 선언하게 됩니다.

#include <MsTimer2.h> //가상시뮬레이터 경우는 삭제하고 해당 라이브러리 파일을 여기에다 복사

int red= 13;
int blue = 12;
  
void flash() {  
  static boolean output = HIGH;
  digitalWrite(blue, output);
  output = !output;
}

void setup() {
  MsTimer2::set(500, flash); // 500ms period
  MsTimer2::start();
}

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

4. 가상시뮬레이터에서 외부라이브러리 함수를 사용하기


가상시뮬레이터에서는 기본 아두이노우노에서 제공되는 라이브러리들을 그냥 쓸 수 있습니다. 하지만 특수한 라이브러리는 제공하지 않습니다. 그러면 가상시뮬레이터에서는 어떻게 실험해야 할지 성멸을 드리도록 하겠습니다.

우선 라이브러리 파일은 두개의 파일로 구성됩니다. 예로 MsTimer2 라이브러리에는 MsTimer2.h, MsTimer2.cpp 파일이 있습니다. 이 두개를 실제로 아두이노 IDE에서 라이브러리 추가해야 사용이 가능합니다.

실제 라이브러리 추가는 LCD16x2 I2C(LiquidCrystal_I2C) 제어(아두이노)의 포스팅에 라이브러리 추가하기를 보시면 됩니다.

하지만 가상시뮬레이터에서는 라이브러리 자체를 추가할 수 없습니다. 라이브러리 자체를 코딩해서 사용해야 합니다. 그럼 사용하기 위해서는 두 파일을 가상시뮬레이터 코딩창에 다 복사해야 합니다.


MsTimer2.h 파일을 전체 복사해서 가상시뮬레이터 코딩창에 붙여넣기 한다음 다음 MsTimer2.cpp 파일에서 

#include <MsTimer2.h>
 라인을 삭제하고 나머지 전체를 복사해서 가상시뮬레이터 코딩창에 이여서 붙여넣기 하시면 됩니다. 그리고 setup(), loop()함수 코딩을 하시면 해결 됩니다.


대충 이런식으로 복사하시면 특수 라이브러리 파일을 연결해서 사용할 수 있습니다.

5. 결과


회로도 설계부터 외부라이브러리 파일을 복사해서 붙이고 코딩을 한 결과를 돌렸을때 결과를 자세히 보시면 대충 어떤식으로 해야할지 감이 잡히실꺼에요. 타이머 라이브러리 함수를 사용해서 LED에 불이 들어오는게 가상시뮬레이터에서 좀 약하게 들어와서 동영상을 보면 잘 안보일 수 있지만 자세히 보시면 두개의 LED들이 따로 독립적으로 움직이는 것처럼 보이실 꺼에요.


마무리


인터럽트는 끼어들기 함수라고 생각 하라고 했죠. 하드웨어 인터럽트에서는 인터럽트 핀에 특정한 조건이 만족했을때 호출 되었습니다. 하지만 오늘 배운 내용에서는 특정한 조건이 만족했을때라기 보다는 타이머로 강제적으로 일정 시간이 되면 호출하는 소프트웨어 인터럽트 였습니다. 둘 차이를 한번 잘 생각해보시고 나중에 어디에 사용할지 상상을 펼쳐 보세요.

한번 둘을 합쳐진 로직을 설계해보면 어떨지 생각해 보세요. 가령 하드웨어 인터럽트의 핀에 상황이 발생했을때 MsTimer2::start(), MsTimer2::stop() 함수가 실행 되게 설계를 한번 해보세요.


댓글()