<h3 class="post-title entry-title" itemprop="name" style="margin: 0.75em 0px 0px; position: relative; font-variant-numeric: normal; font-variant-east-asian: normal; font-weight: normal; font-stretch: normal; font-size: 22px; line-height: normal; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; color: #222222; background-color: #ffffff;">아뒤노에서 타이머 인터럽트 (Timer interrupt in Arduino)</h3>
<div class="post-header" style="line-height: 1.6; margin: 0px 0px 1.5em; font-size: 10.8px; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; background-color: #ffffff;">
   <div class="post-header-line-1">&nbsp;</div>
   </div>
<div class="post-body entry-content" id="post-body-8391996968504595727" itemprop="description articleBody" style="width: 700px; font-size: 13.2px; line-height: 1.4; position: relative; color: #222222; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; background-color: #ffffff;">
   <div class="imageblock center" style="text-align: center; clear: both;"><img alt="" src="https://lh6.googleusercontent.com/proxy/6f6KsyVr3-WKg8SPgfitGQJrKLkEtIX_SCvT8dHpEecA8PKOPYUb4w417URtriNs3AMTGjsM0DF1u7h7dICd2ZArxqtRmuRUgqeIAvg=s0-d" style="padding: 5px; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; border: 1px solid rgb(238, 238, 238); box-shadow: rgba(0, 0, 0, 0.1) 1px 1px 5px; width: 500px; height: 500px;" /></div>
   <br /><br />아뒤노가 임베디드 환경을 처음 접하는 사람들에게 매우 쉬운 환경임에 틀림없지만 조금만 복잡한 작업을 하려고만 하면 제약사항이 꽤 많아진다.&nbsp;<br />특히 가장 아쉬운게&nbsp;<span style="font-family: &quot;courier new&quot;, courier, monospace;">attachInterrupt()</span>를 통해서 외부 인터럽트 2개(Arduino Mega에서는 6개로 늘어났다)만 사용할 수 있다는 점이다.<br /><br />단순하게 센서값을 읽어서 그 값에 따라 LED나 모터를 구동하는건 별 문제가 없지만 동시에 여러개의 입력을 기다리면서 그와 별도로 작업을 처리하거나 해야 한다면 타이머 인터럽트는 거의 필수적이 되어 버린다.<br /><br />물론 atmega의 타이머 관련 레지스터(TCCR2, ASSR 등등)를 직접 제어하면 인터럽트를 사용할 수 있지만 이 경우 아뒤노의 장점(?)이 사라져 버린다.<br />그래서 아뒤노 라이브러리 섹션의 contributed libraries (아뒤노 사용자들이 만든 라이브러리들)에 보면 MsTimer2가 있다. Atmega의 timer 2를 사용해서 ms 단위의 해상도로 타이머 인터럽트를 걸어줄 수 있다.<br />현재 Atmega 1280, 328, 48/88/168, 128/8을 사용한 arduino 및 arduino clone에서 사용할 수 있다.<br /><br />이 라이브러리를 사용하려면&nbsp;<a target="_blank" href="http://www.arduino.cc/playground/Main/MsTimer2" style="text-decoration-line: none; color: #7c93a1;">MsTimer2</a>를 다운받아 압축을 해제한 다음 만들어 진 폴더를 아뒤노가 설치된 폴더 내의&nbsp;<span style="font-family: &quot;courier new&quot;, courier, monospace;">hardware/libraries</span>&nbsp;에 복사해 주면 그것으로 설치가 끝난다. 그리고 스케치북에&nbsp;<span style="font-family: &quot;courier new&quot;, courier, monospace; color: #ff0000;">#include &lt;MsTimer2.h&gt;&nbsp;</span>를 넣어주면 된다.<br /><br />set, start, stop 이렇게 단 3개의 메쏘드만 있어 사용법은 매우 쉽다.<br />먼저&nbsp;<span class="wikiword" style="font-family: &quot;courier new&quot;, courier, monospace;">MsTimer2</span><span style="font-family: &quot;courier new&quot;, courier, monospace;">::set(unsigned long ms, void (*f)())</span>&nbsp;을 사용해서 타이머를 설정해 준다. 이 함수에는 두개의 파라메터가 필요하다. 첫번째는 타이머 시간(ms 단위, 즉 여기에 1000을 넣어주면 1초마다 한번씩 타이머 인터럽트가 발생한다.), 두번째는 인터럽트 서비스 루틴(인터럽트가 발생했을 때 호출할 함수) 이름이다.<br />set()을 이용해서 타이머를 설정했으면&nbsp;<span style="font-family: &quot;courier new&quot;, courier, monospace;">MsTimer2::start()&nbsp;</span>를 호출해주면 타이머가 동작하기 시작해 정해진 시간마다 인터럽트 서비스 루틴이 실행된다.<br />타이머 동작을 멈추려면&nbsp;<span style="font-family: &quot;courier new&quot;, courier, monospace;">MsTimer2::stop()</span>을 호출해주면 된다.<br /><br />타이머 인터럽트가 왜 유용한가는 아래의 예제를 보면 잘 알수있다.<br />0.5초마다 LED를 깜빡이게 하는 프로그램이다.<br /><br />
   <pre style="font-family: &quot;courier new&quot;, courier, monospace;"><font size="2">boolean output = HIGH;</font></pre>
   <font size="2"><span style="font-family: &quot;courier new&quot;, courier, monospace;">void setup() {</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /></font>
   <pre style="font-family: &quot;courier new&quot;, courier, monospace;"><font size="2">  pinMode(13, OUTPUT);<br />}<br /><br />void loop() {<br />  digitalWrite(13, output);<br />  output = !output;<br />  delay(500);<br />}</font></pre>
   <font size="2"><span style="font-family: &quot;courier new&quot;, courier, monospace;">---------------------------------------</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /></font>
   <pre><font size="2"><span style="font-family: &quot;courier new&quot;, courier, monospace;">// Toggle LED on pin 13 each second</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><span style="font-family: &quot;courier new&quot;, courier, monospace;">#include &lt;MsTimer2.h&gt;</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><span style="font-family: &quot;courier new&quot;, courier, monospace;">void flash() {</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><span style="font-family: &quot;courier new&quot;, courier, monospace;">  static boolean output = HIGH;</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><span style="font-family: &quot;courier new&quot;, courier, monospace;">  digitalWrite(13, output);</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><span style="font-family: &quot;courier new&quot;, courier, monospace;">  output = !output;</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><span style="font-family: &quot;courier new&quot;, courier, monospace;">}</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><span style="font-family: &quot;courier new&quot;, courier, monospace;">void setup() {</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><span style="font-family: &quot;courier new&quot;, courier, monospace;">  pinMode(13, OUTPUT);</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><span style="font-family: &quot;courier new&quot;, courier, monospace;">  MsTimer2::set(500, flash); // 500ms period</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><span style="font-family: &quot;courier new&quot;, courier, monospace;">  MsTimer2::start();</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><span style="font-family: &quot;courier new&quot;, courier, monospace;">}</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><span style="font-family: &quot;courier new&quot;, courier, monospace;">void loop() {</span><br style="font-family: &quot;courier new&quot;, courier, monospace;" /><span style="font-family: &quot;courier new&quot;, courier, monospace;">}</span></font><br /></pre>
   둘 다 같은 동작을 한다. 그런데 위의 경우와 같이 타이머 인터럽트를 사용하지 않은 경우 0.5초동안 다른 일을 하지 못하고 단지 기다려야 한다. 그에 비해 아래쪽 프로그램의 경우는 LED를 토글하는걸 인터럽트 서비스 루틴(여기서는 flash())에서 처리해주기 때문에 따로 0.5초를 기다릴 필요가 없이 그 동안 다른 일을 할 수 있게 된다. (loop() 함수에서 아무일도 하지 않는걸 확인할 수 있다. 여기에 다른 작업을 넣어주면 된다.)<br /><br />예를 들어 동작중에 시리얼 포트를 통해 시간을 입력받아 LED가 깜빡이는 간격을 조정하도록 만들려면 상당히 힘들어 지지만 아래쪽 프로그램의 경우 시리얼 포트를 통해 데이터를 입력받는 부분은 loop() 안에서 처리하게 하고 그 입력받은 값에 따라 타이머 설정만 바꿔주면 실제 깜빡이는건 타이머 인터럽트가 담당해 주기 때문에 매우 간단해진다.</div>