루덴스코드 Blog

CH.03.아두이노 LED 깜박이기

이제 아두이노 IDE 설치까지 마쳤을테니 LED 를 깜박거려보겠습니다.

PC용 프로그램에서 가장 먼저하는 것이 Hello World 를 출력하는 것이라면 MCU(Micro Controller Unit) 프로그램에서 가장 먼저하는 것은 LED 를 켜고 끄는 것입니다. 이걸 할 수 있으면 절반은 한 것입니다.

즉, 컴파일러(크로스컴파일러)를 설치하고, 그것으로 프로그램을 짜서 실행코드를 만들고 만들어진 실행코드를 원하는 정해진 타켓(여기서는 아두이노)에 넣어서 정상적으로 작동(LED가 켜지고 꺼지게 하는 일)하게 하는 것까지 할 수 있으면 그 다음부터는 혼자서 천천히 하면 다 됩니다.

그러면 위의 한 문단에 적힌 말을 차분히 되새김질해 보겠습니다.

우리는 아두이노 IDE 를 가지고 아두이노에 사용될 수 있는 프로그램을 짭니다. 다시말해서 우리가 아두이노 IDE 를 가지고 짜는 프로그램은 PC 에서는 전혀 사용할 수 없는 프로그램이라는 뜻입니다. 그래서 아두이노와 같이 PC 가 아닌 것들을 있고, 그것들 안에 PC를 사용해서 실행시키고자 하는 명령코드를 넣을때 우리는 크로스컴파일한다고 말합니다. 아두이노 우노 보드에 붙어있는 MCU 는 ATMEGA328P 라는 칩입니다. 이 칩은 PC에 들어있는 인텔칩과는 전혀 다른 칩입니다. 그래서 PC 에 명령을 주듯이 명령을 주면 알아듣지 못합니다. 

이를테면 한국에서는 나이 어린 아이의 머리에 손을 올리는 것은 아이를 귀엽게 보고 있다는 뜻입니다. 하지만 상당수의 다른 나라에서는 얼굴이나 머리에 손을 대는 것을 극도로 싫어합니다. 어떤 문화권에서 엄지 손가락을 올리는 것은 최고라는 뜻을 나타내지만 호주 같은 곳에서는 욕이 됩니다. 미국에 가서 발표를 하려면 당연히 영어로 원고를 써야하겠지요. 아두이노에 명령을 주려면 아두이노가 알아들을 수 있는 명령어로 된 지시를 내려야 합니다. 그런데 그 지시문을 만들때 한국에서 만든 노트에, 한국에서 만든 펜을 사용한다고 이해하시면 좋을듯 합니다.

즉, PC 에 있는 문서편집기를 사용해서 아두이노에 줄 명령을 씁니다. 우선은 C 는 C++ 을 이용해서 명령을 기록합니다. 그리고 그것을 번역합니다. 보통 PC 프로그램에서 많이 했던 것처럼 PC가 알아듣는 말로 번역하는 대신 아두이노에 있는 ATMEGA328P 라는 칩이 알아들을 수 있는 말로 번역합니다. 그 번역기가 바로 AVR-GCC 가 됩니다. AVR-GCC 를 통해 나온 번역된 명령문은 bin 파일 또는 hex 파일로 저장이 됩니다. 단, 아두이노를 사용한다면 이 부분은 신경쓸 필요가 없습니다. 아두이노를 사용하기 전, 보통 bin 파일이나 hex 파일을 별도의 장치를 통해 MCU 안으로 강제로 밀어넣었습니다. 아주 오래전에는 롬라이터라는 기계를 써서 롬에 프로그램을 넣고 그 롬을 보드에 장착시켰습니다. 조금 시간이 지나면서 플래시메모리가 나왔습니다. 롬은 단 한번만 쓰고 다시는 지우거나 수정이 불가능했습니다. 그런데 플래시메모리는 약간의 제한은 있지만 쓰고 지우는 것이 가능했습니다. 현재 사용되는 대부분의 MCU 는 내부에 플래시메모리와 SRAM 을 가지고 있습니다. 보통 PC 에서 부르는 램은 SRAM 과 동일합니다. 그리고 PC 의 HDD 대신 MCU 는 플래시메모리를 가지고 있다고 보시면 됩니다. PC 는 내부에 CPU, HDD, RAM 을 가지고 있습니다. 반면 MCU 는 하나의 칩 안에 CPU, HDD, RAM 이 다 들어있습니다. 그래서 MCU 라고 부릅니다. MCU 안에 있는 플래시메모리에 어떤 명령문을 기록하기 위해 MCU 마다 특별한 방법을 제시합니다. 그런데 아두이노를 쓸때는 우리는 그것을 신경쓰지 않아도 됩니다. 아두이노안에 있는 하드웨어와 기본펌웨어에서 그것을 처리해줍니다. 대신 우리는 USB 선을 통해서 아두이노로 명령문을 보내주기만 하면 됩니다. 그러면 아두이노는 알아서 그 명령문을 받아서 내부에 있는 플래시메모리에 저장해둡니다.

이 내용은 추후 필요하다면 보충해보도록 하겠습니다. 그러면 이제 LED 를 켜고 끄는 프로그램을 작동시켜 보겠습니다.

아두이노 IDE 를 엽니다.


'파일' - '예제' - '01.Basic' - 'Blink' 를 선택합니다.


주석처리된 부분을 삭제하면 다음과 같습니다.

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

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


이 프로그램 코드를 보면 C 나 C++ 을 사용하셨던 분들은 처음에 많이 이상했을겁니다. 일반적으로 C , C++ 에서는 main() 이라는 함수가 처음에 나와야 하는데 아두이노엔 main() 이 없습니다. 

아두이노는 main() 을 없애고 대신 setup() 과 loop() 를 둡니다. setup() 은 처음 한번만 실행되는 함수입니다. 여기엔 처음 한번만 실행되면 충분한 설정값을 넣게 됩니다. loop() 는 전기가 흐르는 한 계속해서 해야 할 일을 넣게 됩니다. 위에서는 핀 13 번을 LED 를 켜고 끌수 있도록 출력으로 설정했습니다. 설정은 한번만 하면 되니까 setup() 함수 안에 넣었습니다.

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

그 다음 1초 간격으로 LED 를 켜고 끄는 작업을 무한 반복 합니다. 전기가 흐르는 한 이 일은 계속됩니다. 

a. 13번 핀에 +5V 를 흐르게 합니다.
b. 그 다음 1초동안 그 상태 그대로 있게 합니다.
c. 그리고 난 다음 13번 핀을 0V 가 되게 합니다.
d. 다시 1초동안 현재 상태를 유지하게 합니다. 그리고 다시 처음, a 로 갑니다.

    digitalWrite(13, HIGH); 

13번 핀을 현재 아두이노에 들어온 가장 높은 전압에 연결하라는 명령입니다. 아두이노에 들어온 전압이 5V 라면 핀에서 나오는 전압은 5V 가 될 것이고, 만약 3.3V 라면 핀이서 나오는 전압은 3.3V가 될 것입니다. 아두이노 우노는 5V 이므로 13번 핀은 5V 가 걸려있게 됩니다. 마찬가지로 가장 낮은 전압에 연결할 때는 digitalWrite(13, LOW) 를 사용합니다.

    delay(1000); 

이 내용은 delay() 함수를 이해해야 합니다. 일반적으로 PC 에서 프로그램을 한다면 이런 식으로 일부러 시스템의 자원을 낭비하는 일을 하지 않습니다. 하지만 때론 MCU 에서는 몇가지 이유로 이렇게 의도적으로 시간을 버리는(?) 코드를 쓰곤 합니다. 우선은 위의 경우 처럼 1초 동안 아무것도 하지 않아야 할 때 사용합니다. 또 다른 경우는 하드웨어적으로 하나의 신호가 들어간 후 일정시간이 지나야만 그 신호가 적용될 때 의도적인 delay() 를 사용하게 됩니다. 이 부분은 다음에 별도로 다루도록 하겠습니다.

setup() 는 단 1회만 실행되지만 loop() 는 무한반복됩니다. 우선 아두이노 프로그램을 처음하시는 분은 이걸 그냥 기억해두시면 좋겠습니다. 그리고 조금 더 깊이 main() 이 어디 갔는지 궁금하시 분들을 위해 사라진 main() 의 위치를 여기 적어두겠습니다.

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino

제 PC 의 경우 64비트 윈도우10 운영체제를 사용합니다. 아두이노는 위와 같은 경로에 설치되어 있고, 그 경로를 따라 들어가면 

\Arduino\hardware\arduino\avr\cores\arduino\main.cpp

가 있습니다. 주석과 일부를 제거하고 setup(), loop()와 관련된 부분을 보면,

#include <Arduino.h>

int main(void)
{
    init();
    initVariant();
    setup();


    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }


    return 0;
}

위와 같습니다. 결국 보이지는 않았지만 main() 안에 setup() 은 1회 실행으로, loop() 은 무한반복으로 운명지워져 있었던 것입니다.


이제 프로그램이 제대로 작동하는지 살펴보겠습니다.

우선 아래 그림처럼 아두이노우노를 선택하십시오.


그 다음 포트를 선택합니다. USB 케이블로 아두이노와 PC 가 연결되어 있다면 COM 포트가 하나 만들어졌을 것입니다.
 

아두이노 보드 설정이 바르게 되었고, 포트까지 바르게 연결되었다면 이제 프로그램을 컴파일해서 아두이노로 보내면 됩니다. 이 과정은 아래 사진에 있는 화살표를 클릭하면 됩니다. IDE 에서 컴파일을 하고 실행파일을 만든 다음 그것을 바로 USB 케이블 통해 시리얼통신으로 보냅니다. 아두이노 보드에서는 전송되어 온 값을 받아서 플래시메모리에 기록하게 됩니다.


아래 사진은 컴파일이 정상으로 되었고, 전송까지 잘 완료되었음을 보여줍니다.
 


이제 보드를 잘 보면 보드에 붙어있는 LED 하나가 1초 간격으로 깜박이고 있을 겁니다. 여기까지 하셨으면 아두이노 절반은 하신 겁니다. 축하합니다.


Comment +0

CH.02.아두이노 IDE 설치하기

아두이노 IDE 를 설치해보겠습니다. 우선 IDE 란 것이 무엇인지부터 살펴보겠습니다.

IDE 는 Integrated Development Environment 의 약자로 번역하면 '통합개발환경'이 됩니다. 
그런데 보통 통합개발환경이라고 불릴 정도가 되면 편집과 컴파일, 디버깅, 배포까지 소프트웨어에 관해서는 모든 작업이 그 안에서 다 이루어질수 있는 것으로 보아도 틀리지 않습니다. 

아래 두 그림은 각각 Code Composer Studio 라는 IDE 와 IAR 이라는 IDE 입니다.



창(window)의 갯수가 거의 10개에 이릅니다. 필요하면 이보다 더 많은 창을 열어서 사용할 수도 있습니다. 각각의 창이 하는 역할은 모두 다릅니다. 소스를 편집하는 것, 내부 레지스터의 값을 보이는 것, 결과값을 보이는 것, 로그를 보이는 것, 코드를 어셈블한 것을 보이는 것 등등 상당히 많은 창들이 사용됩니다. 

그에 비해 아두이노 IDE 는 다음과 같이 매우 단순합니다.

다른 IDE 들과 비교해보면 얼마나 단순한지 알 수 있습니다.
왜 이렇게 단순할까? 사용하다보면 더 필요한 기능들이 얼마나 많이 있는데, 이렇게 조촐하게 만들어진 IDE 를 가지고 쓸 사람이 있기나할까? 사실 처음 아두이노가 세상에 나왔을때 많은 사람들이 아두이노의 모습을 보고 던진 비웃음이 있었을 겁니다.

처음 소프트웨어가 세상에 나왔을때 이런 IDE 는 없었습니다. "통합"이라는 말이 붙는 개발환경 자체가 없었습니다. 개발하려는 사람은 매우 열악한 문서편집 소프트웨어(이를테면 지금의 윈도우 메모장보다 훨씬 불편한 vi 같은 문서편집 프로그램)를 썼습니다. 소스코드를 만들고 그것을 컴파일하고, 컴파일 된 파일들을 모아 다시 링크를 해서 실행파일을 만들었습니다. 종종 문제가 생기면 열심히 소스코드를 들여다보면서 어디가 잘못되었는지 찾았습니다. 눈으로 말이지요.

그러다가 소스편집과 컴파일, 링크를 통해 실행파일을 한번에 만드는 개발환경을 만들고 그 안에 디버깅할 수 있는 내용도 추가했습니다. 조금 더 편리하게 개발할 수 있는 환경을 프로그래머들이 만든것이지요. 그런데 전문적인 프로그래머의 입장에서는 가능한 많은 창을 한꺼번에 띄워두고 자기가 원하는 정보를 빨리 보는 것이 좋았습니다. 시간이 갈수록 IDE 는 복잡해졌습니다. 나중에는 IDE 자체를 사용하는 것이 쉽지 않은 일이 되고 맙니다.

예전에 8051 이라는 MCU 를 사용하기 위해 KEIL 과 IAR 이라는 컴파일러를 사용할 기회가 있었습니다. 프로그램을 쉽게 하기 위해 만들어진 IDE 를 이해하기 위해 상당히 두꺼운 메뉴얼을 프린트로 출력해서 영어로 된 원서를 더듬거리며 읽어야 했던 기억이 납니다. 

매일 이런 프로그램을 사용하는 전문가들에게는 어렵더라도 기능이 강력한 이런 IDE 가 아주 좋은 도구가 됩니다. 일주일이 걸릴 작업을 사나흘만에 해낼수도 있습니다. 하지만 이런 프로그램을 자주 사용하지 않는 일반인들에게는 오히려 강력한 IDE 의 등장은 현재 진행중인 기술과 담을 쌓게 되는 원인이 됩니다. 그저 전구에 불을 켜고 끄는 일을 1초에 한번씩 반복하는 간단한 작업을 하고 싶어도 수백페이지가 넘는 영어로 된 메뉴얼을 읽어야만 한다면 그는 차라리 다른 전문가에게 그 일을 의뢰하거나 혹은 포기하고 말겁니다. 게다가 KEIL 이나 IAR 같은 컴파일러들은 개인이 구입해서 사용해보기에는 많이 비쌉니다. 윈도우나 한글, 오피스 같은 범용 프로그램들은 일반인을 상대로 개발하고 많은 판매를 하기 때문에 구입하기로 마음먹어도 큰 부담은 없습니다. 하지만 KEIL, IAR, Code Composer 같은 전문가들이 사용하는 프로그램들은 부르는게 값이었고, 사용하기도 만만치 않았습니다.

하지만 다행스럽게도 gcc 라는 GNU 프로젝트에 의해 만들어진 공개된 컴파일러가 등장합니다. gcc 는 처음 리눅스환경에서 사용되었지만 지금은 거의 모든 환경에서 사용됩니다. 보통은 PC 환경만 생각합니다. 하지만 SDCC 라는 8051용 컴파일러도 있고, AVR-GCC 라는 AVR용 컴파일러도 있습니다. 이런 공개된 무료 컴파일러를 통해 누구라도 비용에 대한 걱정없이 8051 이나 AVR 을 사용할 수 있게 되었습니다. 

하지만 여전히 일반인이 넘기에는 어려운 벽이 있었습니다. SDCC 나 AVR-GCC 는 무료로 사용할 수 있었지만 통합개발환경이 아닌 컴파일러였기에 제대로 사용하기 위해서는 makefile 이라는 것을 만들어야 했습니다. 이 makefile 을 만드는 것이 무척 어렵고 성가신 일입니다. 이미 많이 만들어본 사람에게는 별것이 아니겠지만 처음 사용하는 사람에게는 makefile 을 만드는 것만 해도 머리에 쥐가 나는 것은 물론이고 "그냥 나 이대로 살래"란 말이 자연스럽게 나오게 만들 정도였습니다.

mcu 는 점점 속로가 빨라지면서 고성능화 되어가고, IDE 는 점점 비싸지면서 일반인들은 감히 건드리기도 힘든 아우라를 갖춘 복잡한 모양이 되어갑니다. SDCC 나 AVR-GCC 는 읽기도 힘든 영문매뉴얼을 읽어야하고, 게다가 makefile 이라는 난생 처음 들어보는 이상한 컴파일-링크 시스템을 사용자가 알아서 만들어줘야만 합니다. 에러가 나면 어디서 문제가 생겼는지 찾기도 힘들었습니다.

사실 그런 환경속에서 아두이노는 태어납니다. AVR-GCC 를 컴파일러로 사용하지만 외형은 전혀 그렇지않고 깔끔하고 간단하게 갖췄습니다. AVR 을 프로그램한다면 당연히 했어야하는 레지스터에 대한 것도 묻지 않습니다. 포트를 읽는 것으로 할 것인지 쓰는 것으로 할 것인지도 간단하게 바꿨습니다. 

예전식으로 프로그램을 하면 다음과 같습니다.

DDRA = 0x00;    //Set port a as input
x = PINA;       //Read contents of port a 
첫줄은 A 포트를 입력으로 사용하겠다고 레지스터를 설정하는 것입니다.
둘째줄은 포트A 로 들어온 값을 x 라는 변수에 입력시키는 것입니다. 포트 A 는 8개의 입력핀이 모인 곳이라고 하면 x 에 들어온 값은 이진수로 00000000 부터 11111111 까지의 어떤 값이 됩니다. 결국 x 들어온 값으로 각 핀의 값을 알려면 다시 x 를 비트연산자를 통해 각 핀의 값으로 읽어줘야만 합니다. 

DDRB = 0b11111111;        //set all pins of port b as outputs
PORTB = 0xFF;             //write data on port 

첫줄은 포트 B 의 모든 핀을 출력으로 설정하는 것입니다. 위에 입력으로 할때와 비교하면 이해가 될 것입니다. 그리고 두번째 줄은 포트 B에 값을 넣어서 각 핀을 통해 5V 또는 0V 를 보내는 것입니다. 여기서는 포트 B 의 8개 핀 모두에서 +5V 가 나오게 했습니다.

이것을 아두이노에서는 이렇게 프로그램합니다.

pinMode(13, OUTPUT);          // 13번 핀을 출력으로 설정
digitalWrite(13, HIGH);          // 13번 핀에 5V 출력
digitalWrite(13, LOW);          // 13번 핀에 0V 출력

pinMode(12, INPUT);                            // 12번 핀을 입력으로 설정
int buttonState = digitalRead(12);      // 12번 핀을 읽어 변수 buttonState 에 저장

이전 방식의 AVR 프로그램과 비교하면 아두이노의 프로그램은 훨씬 인간적입니다. 물론 이렇게 인간적인 프로그램이 되기 위해서 포기한 것이 있습니다. 레지스터를 직접 다루는 것을 포기했습니다. 결과적으로 프로그램의 속도나 효율도 떨어졌습니다. 하지만 프로그램이 쉬워졌습니다. IDE 도 복잡하면서 막강한 기능을 가지는 대신 단순하면서 최소의 기능에 만족했습니다. 마친 모든 MP3 들이 이퀼라이저에 칼라 LCD 에 심지어 움직이는 동영상까지 넣으려던 때에 애플이 동그랗고 커다란 버튼 하나만 달랑 붙은 아이팟을 내놓았을 때처럼 아두이노의 IDE 는 혁신적이었습니다.

기능의 부족함이 오히려 일반인들에게는 더 가까이 다가갈 수 있는 매력이 된 것입니다. 

지금 다수의 컴파일러들은 아두이노 IDE 와 유사해집니다. Ti 는 Code Composer Studio 라는 IDE 를 판매하고 있습니다. 아두이노의 열기가 뜨거워지고 현재 TI의 일부 범용 MCU (C2000, MSP430, etc.) 를 프로그램 할 수 있는 Energia 라는 오픈소스 IDE 가 나왔습니다. 모양은 아두이노 IDE 와 똑같습니다. 색깔만 빨간색입니다.


단순하기 때문에 성공한 것, 그것이 아두이노의 매력입니다.

이제 이 단순한 IDE 를 설치해 보겠습니다.

https://www.arduino.cc/ 로 가서 Download 라고 되어 있는 메뉴를 클릭하고 윈도우나, 맥, 리눅스 중 자신의 운영체제에 맞는 것을 다운받으시면 됩니다. 설치는 다운 받은 파일을 더블클릭해서 순서대로 따라가기만 하면 됩니다. [바로가기 링크]




Comment +0

CH.01.아두이노와 PC연결

다음과 같이 준비합니다.

1. 아두이노 우노
2. USB포트가 있는 컴퓨터로 리눅스, 맥, 윈도우 운영체제가 갖추어진 것
3. USB 케이블 (보통 우노를 구입할 때 함께 오는 것)
4. 브레드보드
5. 브레드보드용 케이블









우선 준비된 아두이노 Uno 를 PC 에 연결합니다. 다음 그림과 같이 USB 포트를 연결하면 됩니다.


연결이 되면 아두이노에 불이 들어옵니다. 


Comment +0

실기평가용 PADS 라이브러리입니다.

Comment +0