아뒤노가 임베디드 환경을 처음 접하는 사람들에게 매우 쉬운 환경임에 틀림없지만 조금만 복잡한 작업을 하려고만 하면 제약사항이 꽤 많아진다.
특히 가장 아쉬운게 attachInterrupt()를 통해서 외부 인터럽트 2개(Arduino Mega에서는 6개로 늘어났다)만 사용할 수 있다는 점이다.

단순하게 센서값을 읽어서 그 값에 따라 LED나 모터를 구동하는건 별 문제가 없지만 동시에 여러개의 입력을 기다리면서 그와 별도로 작업을 처리하거나 해야 한다면 타이머 인터럽트는 거의 필수적이 되어 버린다.

물론 atmega의 타이머 관련 레지스터(TCCR2, ASSR 등등)를 직접 제어하면 인터럽트를 사용할 수 있지만 이 경우 아뒤노의 장점(?)이 사라져 버린다.
그 래서 아뒤노 라이브러리 섹션의 contributed libraries (아뒤노 사용자들이 만든 라이브러리들)에 보면 MsTimer2가 있다. Atmega의 timer 2를 사용해서 ms 단위의 해상도로 타이머 인터럽트를 걸어줄 수 있다.
현재 Atmega 1280, 328, 48/88/168, 128/8을 사용한 arduino 및 arduino clone에서 사용할 수 있다.

이 라이브러리를 사용하려면 MsTimer2를 다운받아 압축을 해제한 다음 만들어 진 폴더를 아뒤노가 설치된 폴더 내의 hardware/libraries 에 복사해 주면 그것으로 설치가 끝난다. 그리고 스케치북에 #include <MsTimer2.h> 를 넣어주면 된다.

set, start, stop 이렇게 단 3개의 메쏘드만 있어 사용법은 매우 쉽다.
먼저 MsTimer2::set(unsigned long ms, void (*f)()) 을 사용해서 타이머를 설정해 준다. 이 함수에는 두개의 파라메터가 필요하다. 첫번째는 타이머 시간(ms 단위, 즉 여기에 1000을 넣어주면 1초마다 한번씩 타이머 인터럽트가 발생한다.), 두번째는 인터럽트 서비스 루틴(인터럽트가 발생했을 때 호출할 함수) 이름이다.
set()을 이용해서 타이머를 설정했으면 MsTimer2::start() 를 호출해주면 타이머가 동작하기 시작해 정해진 시간마다 인터럽트 서비스 루틴이 실행된다.
타이머 동작을 멈추려면 MsTimer2::stop()을 호출해주면 된다.

타이머 인터럽트가 왜 유용한가는 아래의 예제를 보면 잘 알수있다.
0.5초마다 LED를 깜빡이게 하는 프로그램이다.

boolean output = HIGH;
void setup() {
  pinMode(13, OUTPUT);
}

void loop() {
digitalWrite(13, output);
output = !output;
delay(500);
}
---------------------------------------
// Toggle LED on pin 13 each second
#include <MsTimer2.h>

void flash() {
static boolean output = HIGH;

digitalWrite(13, output);
output = !output;
}

void setup() {
pinMode(13, OUTPUT);

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

void loop() {
}

둘 다 같은 동작을 한다. 그런데 위의 경우와 같이 타이머 인터럽트를 사용하지 않은 경우 0.5초동안 다른 일을 하지 못하고 단지 기다려야 한다. 그에 비해 아래쪽 프로그램의 경우는 LED를 토글하는걸 인터럽트 서비스 루틴(여기서는 flash())에서 처리해주기 때문에 따로 0.5초를 기다릴 필요가 없이 그 동안 다른 일을 할 수 있게 된다. (loop() 함수에서 아무일도 하지 않는걸 확인할 수 있다. 여기에 다른 작업을 넣어주면 된다.)

예를 들어 동작중에 시리얼 포트를 통해 시간을 입력받아 LED가 깜빡이는 간격을 조정하도록 만들려면 상당히 힘들어 지지만 아래쪽 프로그램의 경우 시리얼 포트를 통해 데이터를 입력받는 부분은 loop() 안에서 처리하게 하고 그 입력받은 값에 따라 타이머 설정만 바꿔주면 실제 깜빡이는건 타이머 인터럽트가 담당해 주기 때문에 매우 간단해진다.
Posted by nautes

댓글을 달아 주세요

  1. 2010.08.28 03:18

    안녕하세요. 네이버 검색후 올려놓으신 자료는 정말 잘 보고 있습니다.^^ 제가 인터럽트 글을읽고 궁금하게 있어서 여쭤보려합니다. 타이머인터럽트로 서보모터를 작동시키는데 시리얼 데이터가 들어오면 스탑 안들어오면 스타트를 하려하는데 이상하게 시리얼통신으로 제어하면 막 신호가 튀더라구요. 조언좀 얻고자 이렇게 초면에 글을 남겨 봅니다.
    void loop() {
    if( serialEvent() == 1){
    MsTimer2::stop();
    digitalWrite(10, LOW);
    }
    if(serialEvent() == 0){
    MsTimer2::start();
    digitalWrite(10, HIGH);
    }
    debugging(serialEvent());
    delay(10);

    }


    boolean serialEvent(){
    if(Serial.available() > 0){
    int val = Serial.read();

    if( val == 1){
    return 1;
    }
    }
    else {
    return 0;
    }
    }

  2. 2014.11.30 11:50 신고

    안녕하세요. 제가 이 블로그에서 타이머 인터럽트를 배워서 아두이노로 뭔가를 하나 만들었습니다. msTimer 2 로 32초까지는 잘 작동하지만 설정 시간이 32초를 넘으면 작동을 안 합니다.

    즉 최대 설정가능 시간이 32초라는 이야기입니다.
    30분 정도를 설정하고 싶은데 방법이 없을까요?

http://arduino.cc 에서 arduino 소프트웨어를 다운받을 수 있다. Mac OS X, Linux, Windows를 모두 다 지원한다.

또한 OS용 디바이스 드라이버도 이 사이트에서 다운받을 수 있다.

다운받은 압축파일을 풀어주면 프로그램을 가지고 있는 폴더가 생긴다. 별도 설치 할 필요가 없이 그 폴더에서 arduino 프로그램을 바로 실행해주면 된다.

프로그램을 실행하면 다음과 같은 창이 열리게 된다..

먼저 arduino 보드에 맞게 환경설정을 해 주어야 한다. Tools 메뉴로 가 보면 아래와 같은 서브메뉴가 나온다.

먼저 통신에 사용할 시리얼 포트를 지정해 준다. Arduino보드를 USB 케이블에 연결하고 디바이스 드라이버가 제대로 설치되어 있으면 아래와 같이 포트가 보이게 된다. 아래 화면은 맥의 경우이고 윈도우 인 경우 COMx 란 이름으로 보이게 된다. 보드를 연결했는데도 포트가 보이지 않는다면 디바이스 드라이버를 다시 설치하고 프로그램을 실행하면 보일 것이다.

그 다음은 보드를 설정해 준다. Arduino도 여러 종류가 있어서 그에 해당하는 보드를 선택해주면 된다.


여기서는 아래의 보드를 사용할 것이기 때문에 Arduino Diecimila를 선택해주면 된다.


설정이 끝났으면 예제 프로그램을 실행시켜 보겠다. 아래 화면에서처럼 File -> Sketchbook -> Example -> Digital -> Blink 를 선택해 준다.

그러면 Blink 예제 파일이 열리고 내용을 볼 수 있게 된다. 여기서 맨 왼쪽의 플레이버튼을 누르면 프로그램이 컴파일 된다.

컴파일이 정상적으로 끝나면 화면 아래쪽에 다음과 같은 메세지가 나온다.

하지만 컴파일이 끝났어도 아직 프로그램이 arduino 보드로 옮겨진건 아니다. 프로그램을 arduino 보드로 전송하려면 오른쪽 두번째 버튼을 눌러준다.

그러면 arduino 보드의 TX, RX LED가 빠르게 번쩍이면서 프로그램이 전송되는걸 볼 수 있다. 전송이 끝나면 컴파일의 경우와 마찬가지로 메시지 창에 업로드가 끝났다는 메시지가 표시된다.

프로그램이 전송되고 나면 arduino 보드는 자동으로 reset이 되면서 프로그램이 바로 실행된다. 이 예제 프로그램은 보드에 있는 LED를 깜빡이게 하는 것이기 때문에 아래의 LED가 1초 간격으로 반짝이는걸 확인할 수 있을 것이다.

또한 arduino에는 시리얼 터미널 기능도 가지고 있다. 위의 예제에서는 시리얼 포트를 사용하지 않았지만 프로그램에 따라서는 시리얼 포트를 통해 데이터를 주고받을 수 있다. 맨 오른쪽의 아이콘을 눌러주면 아래쪽 메시지 윈도우가 시리얼 터미널 역활을 하게 된다.

검은 부분에 수신한 데이터가 표시되고 송신할 데이터는 입력창에 넣어주면 된다. 또한 통신속도도 임의로 변경할 수 있다. 물론 arduino보드의 시리얼 포트 설정속도와 동일하게 맞춰줘야만 한다.

Posted by nautes

댓글을 달아 주세요

이전버튼 1 이전버튼