'Embedded Lecture/Arduino'에 해당되는 글 13건

  1. 2017.03.12 인터럽트의 처리(1)
  2. 2017.03.12 LED 깜박이기
  3. 2017.03.12 아두이노(Arduino) 코딩의 시작
Embedded Lecture/Arduino2017. 3. 12. 20:40

 

프로그램은 사용자가 편의를 위해서 코딩합니다. 즉 무엇인가 자동으로 일괄처리를 하기 위함인데 이는 마이크로 프로세서에서도 마찬가지 입니다. 하지만 프로그램 혹은 알고리즘(algorithm)은 일방적이기 보다는 주로 사용자와 대화형이고 키보드 뿐만 아니라 다양한 입출력 장치들과 각종 센서들에서 입력되는 정보로 프로그램과 대화하게 됩니다.


프로그램이 진행 중, 사용자에게 요구 사항이 있으면 팝업 창을 띄우고 묻기 위해 대기할 수 있지만, 사용자나 센서가 문득 프로그램에 어떤 입력을 주고 싶은 경우도 있습니다. 이를 '끼어든다'고 하여 인터럽트(interrupt)라 부르고 프로그램은 하던 작업을 멈추고 가급적 빨리 이를 처리하고 원래 수행하던 작업으로 되돌아가야 합니다. 이처럼 즉시 처리해야 하는 특수한 이벤트인 인터럽트가 발생하면, 프로세서는 그 이벤트를 처리할 작업들이 수록된 함수를 호출하는데, 이 함수를 인터럽트 서비스 루틴(ISR; interrupt service routine)이라고 합니다.

 


예를 들어, 키보드에 특정 키가 눌러저 있는지 이벤트를 감지하려면 모든 프로그램은 아두이노의 loop() 함수 같이 반복 수행되는 루프 내에서 항상 이 키의 상태를 검사해야 합니다. 이를 '소프트웨어 인터럽트' 혹은 '폴링(polling) 방식'이라고 하고 마이크로 프로세서의 경우에는 보다 정확하고 신속한 '하드웨어 인터럽트(인터럽트 방식)'도 제공하는데, 이를 이용하면 소프트웨어적으로 이 버튼의 상태를 항상 검사할 필요가 없다는 것입니다. 때문에 프로그램은 불필요한 부분에 시간을 낭비할 필요가 없게 됩니다. 그러므로 폴링 방식은 단일 이벤트 처리에 적합하고 인터럽트 방식은 다중 이벤트 처리에 효율적입니다. 


즉, MCU는 다른 작업을 하고 있다가 '키가 눌려지면' 그 즉시 하드웨어 인터럽트를 발생하여 하던 일을 멈추고 이를 처리할 ISR 함수를 호출하고, ISR이 끝나면 하던 일로 되돌아가게 됩니다. Arduino Uno 보드의 경우 인터럽트를 처리할 수 있는 핀은 2번과 3번 핀으로 이는 MCU에서 지원하기 때문이며 각각 INT0, INT1이라고 부릅니다.


ISR을 사용하기 위해서는 attachInterrup()라는 함수로 미리 알려야 합니다.


attachInterrupt( pin, ISR, mode)

pin : 첫 번째 인자로 인터럽트로 사용할 핀을 지정합니다. INT0의 경우 '0', INT1의 경우 '1'이 됩니다.

ISR : 두 번째 인자로 인터럽트가 걸렸을 때 호출할 함수의 이름으로 사용자가 만든 함수 이름입니다.

mode : 세 번째 인자로 RISING, FALLING, CHANGE, LOW 중 하나가 됩니다.



'RISING'이란 인터럽트 핀에 신호가 '0'에서 '1'로 변하는 순간이며 'FALLING'은 그 반대입니다. 'CHANGE'는 RISING과 FALLING 모두를 의미하며 'LOW'는 logical '0'값일 때를 의미합니다. ISR 함수는 입력 인수를 받을 수 없고 반환값도 void형이어야 하며, attatchInterrupt() 함수는 통상 setup() 함수 안에서 사용되어 초기에 인터럽트를 설정하게 됩니다.


다음은 터치 센서를 한 번 터치하면 LED가 점등하고 다시 터치하면 LED가 커지도록 동작하는 스케치를 예를 들어 봅니다. 이를 위해서 Ardunio Uno 보드의 11번에 부저를 연결하고, 3번 핀(INT1)에 터치 센서를 연결하여 하드웨어 인터럽트를 사용할 것입니다. 소스 코드는 다음과 같습니다.


#define TS 3

#define BUZ 11

void setup() {

    pinMode(LED_BUILTIN, OUTPUT);

    pinMode(BUZ, OUTPUT);

    pinMode(TS, INPUT);

    attachInterrupt(INT1, toggleLed, RISING);

}

void loop() {

    digitalWrite(BUZ, HIGH);

    delay(50);

    digitalWrite(BUZ, LOW);

    delay(450);

}

void toggleLed() {

    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));

}


setup()함수 내에 attachInterrupt(INT1, toggleLed, RISING)를 삽입하여 INT1을 사용하였고 ISR로써 toggleLed() 함수를 추가하였습니다. 세 번째 인자인 mode가 RISING 이므로 toggleLed() 함수는 외부 인터럽트인 3번 핀의 신호가 '0'에서 '1'로 바뀌는 rising edge에서 하드웨어적으로 자동 호출됨을 의미합니다.


loop() 함수에서는 부저를 단지 0.5초마다 한 번씩 울리는 일이 전부이며, 터치 센서가 눌러질 때마다 toggleLed() 함수 내에 digitalWrite() 함수가 실행되고 이는 아두이노 보드 내 이전의 LED 값에 따라 그 반대의 값을 쓰게 됩니다. 즉 켜져 있으면 크고 커져 있으면 켜게 됩니다. 참고로 digialRead() 함수는 단일 인자를 가지며 읽고자 하는 핀 번호를 인자로 넘겨주면 그 logical 값을 반환합니다.



'Embedded Lecture > Arduino' 카테고리의 다른 글

인터럽트와 volatile 지시자  (1) 2017.03.18
아두이노의 TWI(I2C) 통신  (0) 2017.03.18
아두이노의 시리얼 통신  (0) 2017.03.18
LED 깜박이기  (0) 2017.03.12
아두이노(Arduino) 코딩의 시작  (0) 2017.03.12
Posted by Nature & Life
Embedded Lecture/Arduino2017. 3. 12. 17:41


Arduino Uno 보드는 LED가 실장되어 있으며 이는 디지털 입출력 핀 13번에 연결되어 있습니다. 이 LED를 깜박이는 예제는 이미 아두이노 IDE에서 제공되고 있으며 '파일|예제'에서 'Blink'를 선택하여 불러올 수 있으며, 다양한 예제들은 여기서 확인할 수 있습니다.



읽어들인 소스 코드인 스케치 파일은 다음과 같습니다.


int led = 13;

void setup() {

    pinMode(led, OUTPUT);

}

void loop() {

    // turn the LED on (HIGH is the voltage level)

    digitalWrite(led, HIGH);

    delay(1000); // wait for a second

    // turn the LED off by making the voltage LOW

    digitalWrite(led, LOW); 

    delay(1000); // wait for a second

}


setup() 함수 내에서 pinMode() 함수는 첫 번째 인자로 핀의 번호를, 두 번째 인자는 입출력 모드를 지정하게 되는데, 입력이면 'INPUT'을 출력이면 'OUTPUT'을 설정하게 됩니다. 그러므로 pinMode(led, OUTPUT)는 13번 핀을 출력으로 사용하겠다는 의미입니다. 참고로 아두이노에서 제공하는 함수의 문법(Syntax)이나 인자(Parameter)에 대한 자세한 설명은 아두이노 홈페이지에서 확인할 수 있습니다.


https://www.arduino.cc/en/Reference/HomePage 


사실 전통적인 표준 라이브러리 AVR libc의 문법으로는 위의 pinMode 함수는 DDRD = 0b01000000; PORTD = 0b01000000; 이들 두 문장을 대체하게 됩니다. 아두이노에서 같은 기능을 하기 위해 고유 서브함수를 호출한 반면, 표준 라이브러리는 단순한 매크로(macro)들의 사용만으로 속도나 실행 크기면에서 우수하다는 것입니다. 하지만 표준 라이브러리는 ATmega328P에 대한 전문적인 지식이 요구되어 초보자에게 결코 쉽지 않다는 것입니다.


특히 속도의 측면에서 빠른 처리나 인터럽트 처리를 요구하는 장치를 동작시키는 경우에는 아두이노는 표준 라이브러리에 비해서 상당한 열쇠에 놓이게 됩니다. AVR 칩이 C 언어를 지원함에도 불구하고 아직도 어셈블러(Assembler)로 개발하는 경우가 있는데, 이것도 같은 이유에서라는 것입니다. 하지만 점차 MCU의 속도는 끊임없이 진화하고 리소스도 풍부해지기 때문에 크게 문제는 되지 않을 것입니다.


loop() 함수내에서 digitalWrite() 함수는 첫 번째 인자로 지정된 핀에, 두 번째 인자로 HIGH 혹은 LOW 값을 쓰는데 사용하는 함수로 digitalWrite(led, HIGH)는 이미 출력으로 지정된 13번 핀에 HIGH 값을 내보냄을 의미합니다. 입출력의 지정없이 이 함수를 사용할 수는 없으며 전원 전압이 5V이면 13번 핀은 5V의 전압이 인가되어 LED를 점등하게 됩니다.


또한 delay() 함수는 입력된 시간만큼 동작을 멈추는 용도로 사용되어 delay(1000)은 1000ms 동안 지연을 줄 목적으로 사용됩니다. 여기서 단위는 ms임을 주목해야 합니다.


결국 loop() 함수 내의 동작은 13번 핀을 점등하고 1s를 기다렸다가 다시 소등하고 1s를 기다리는 코드로, loop() 함수는 영원히 반복하게 되므로 끊임 없이 LED를 1초 간격으로 점등과 소등을 반복하게 됩니다,



'Embedded Lecture > Arduino' 카테고리의 다른 글

인터럽트와 volatile 지시자  (1) 2017.03.18
아두이노의 TWI(I2C) 통신  (0) 2017.03.18
아두이노의 시리얼 통신  (0) 2017.03.18
인터럽트의 처리(1)  (0) 2017.03.12
아두이노(Arduino) 코딩의 시작  (0) 2017.03.12
Posted by Nature & Life
Embedded Lecture/Arduino2017. 3. 12. 01:12


아두이노(Arduino) 코딩(coding)을 위해서 아두이노 통합 환경 즉, IDE(Integrated development envirionment)를 다음의 링크에서 사용자의 OS 환경에 맞게 설치하여 합니다.


https://www.arduino.cc/en/Main/Software


사실 IDE에는 2가지가 존재합니다. 첫번째는 사용자 PC에 직접 설치하는 전통적 환경이며, 두번째는 Arduino Web Editor으로 온라인 버젼입니다. 일반적인 설치 버젼은 아두이노가 업데이트 되면 업데이트 작업이 매번 필요하지만, Web Editor 버젼은 항상 아두이노 보드의 모든 라이브러리나 지원 사항을 포함하여 최신 버젼을 유지하고 클라우드에 스케치(sketch)를 저장하게 됩니다. 여기서 스케치는 자신이 코딩한 소스 파일을 의미합니다.


이외에도 사용자의 로컬 PC에서 설치 버젼을 사용시 빠른 속도와 편의기능 등이 있으에도 불구하고 온라인 버젼이 출시되는 이유는 여러 사람이 코딩이 함께 하는 협업에 유리하고 자신의 작성한 코드나 라이브러리를 공유할 수 있으며, 이러한 코드를 효율적으로 안전하게 관리할 수 있기 때문이라는 것입니다.



이는 아두이노 IDE의 첫 화면이며 여기서 프로그램의 코딩과 컴파일(compile) 그리고 아두이노 보드가 PC에 USB를 통해서 제대로 연결되었다면 아두이노 보드로의 다운로드 까지 가능하게 됩니다. 아두이노 보드를 PC에 연결하려면, USB로 아두이노 보드와 연결하고 IDE를 실행한 다음, 메뉴에서 '도구|보드'에 자신이 연결한 아두이노 보드의 종류를 선택하고, '도구|시리얼 포트'에 가상 시리얼 포트의 번호를 선택합니다. 참고로 아두이노 포트 번호는 Windows의 경우 장치관리자에서 확인할 수 있습니다.



위의 아두이노 IDE의 첫 화면에서 아래와 같이 아두이도 코딩의 프로토타입(prototype)을 보여줍니다. 사실 사용자가 이마저도 직접 써야 하지만, 아두이노는 친절하게 반드시 있어야 할 코드는 미리 써주었다는 것입니다. C 언어에 익숙한 사용자라면 프로그램은 반드시 main() 함수로 시작해야 한다고 알고 있는데, 이는 없는 것이 아니고 아두이노 IDE가 사용자 편의를 위해서 내부적으로 처리하게끔 하였다는 것입니다.


void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

일반적인 C 프로그램과 달리 아두이노 하드웨어 프로그램은 위의 2가지 함수인 setup()과 loop()가 반드시 필요합니다. 코딩이란 사용자가 이들 함수를 기반으로 새로운 코드나 함수를 삽입하여 원하는 기능이나 동작을 구현하는 과정이라는 것입니다. setup() 함수는 아두이노 보드의 MCU가 처음 시작할 때 단 한번 실행됩니다. loop() 함수는 setup() 함수가 실행된 이후에 영원히 반복하게 됩니다. 이런 무한 반복을 하드웨어적으로 멈추게 하는 것은 아두이노 MCU의 'RESET' 버튼을 누르는 것인데, 이때 하드웨어는 다시 초기화되고 처음 setup() 함수부터 실행하게 됩니다.





'Embedded Lecture > Arduino' 카테고리의 다른 글

인터럽트와 volatile 지시자  (1) 2017.03.18
아두이노의 TWI(I2C) 통신  (0) 2017.03.18
아두이노의 시리얼 통신  (0) 2017.03.18
인터럽트의 처리(1)  (0) 2017.03.12
LED 깜박이기  (0) 2017.03.12
Posted by Nature & Life