□ 사용자 라이브러리 구성 방법

스케치 파일(ino)에 소스를 작성하는 것은 비효율적인 경우가 많다.

한 예로, ino 파일을 다른 Editor (Visual Studio, eclipse 등 )에서 사용하는데 확장자로 인해서 번거롭고 별도 헤더파일 정의도 없어 라이브러리로 사용이 불편하거나 하는 등 여러 단점이 존재한다.

특히, 복잡한 프로그램을 개발하는 경우 다양한 사용자 라이브러리들을 별도의 파일로 만들어 사용하는 것은 불가결하다.

 

이런 이유로, 복잡한 프로그램은 두말할 것도 없고 단순 기능도 스케치 파일(ino)와 사용자 라이브러리(별도 소스파일)을 분리해서 개발하는 것은 좋은 방법이다.

아두이노에서 사용자 라이브러리를 사용하는 것은 간단하며 아래와 같은 형태로 쉽게 구성이 가능하다.

 

그림) 아두이노 사용자 라이브러리 구성도 

 

  Sample.ino

 프로그램 Sample에 대한 스케치

  Sample.h

 Sample.cpp 소스에 대한 헤더파일

  Sample.cpp

 실제 기능/클래스를 이용한 실행 소스 

- 실제 소스는 Sample.h와 Sample.cpp에서 작성하여 재사용성을 높이고 ino 파일은 스케치 역할과 프로그램 설명,
   저작권 설명 등 부수적인 역할만 수행

 

 

사용자 라이브러리를 위한 별도 소스파일에서 가장 먼저 지정해야하는 것은 #include “Arduino.h” 구문을 사용하는 것이다.

#include "Arduino.h"    

- 아두이노 표준 타입, 사전 정의된 상수, 함수들에 대한 헤더파일

- 아두이노 표준 제공 기능을 사용할 수 있도록 해준다.

 

해당 파일은 일반 스케치(ino 파일)에서는 암묵적으로 자동 추가되지만, 사용자 라이브러리 파일에서는 자동 추가되지 않아서 직접 지정해 주어야 한다.

주의해야할 사항으로는스케치 파일에서는 Arduino.h와 IDE에서 "새탭"으로 정의한 소스 및 헤더파일 들만 자동 추가된다.

따라서, 소스 내에서 Serial 클래스와 같은 #include <Wire.h> 등을 사용할 때나 다른 라이브러리 등을 사용할 경우에는 스케치 파일에도 반드시 명시적으로 기재해 주어야 한다.

또한, 사용되는 라이브러리들의 구성관계를 파악하기에 용이하므로 새탭 메뉴를 통해 정의된 사용자 라이브러리의 헤더파일도 명시적으로 선언(#include로 기재)해 주는 것이 좋다.

 

 Sample.ino

 

Sample.h 

 

 Sample.cpp

 

 // 프로그램 개요

 // 저작권 : ... ...

 // ... ...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 // 전처리 상수 선언

 #define PORT_NO 12

 #define TIME        1000

            ... ...

 

 // 함수 or 클래스 선언

 void userfunction1();

 void userfunction2();

            ... ...

 

 

 

 

 

 

 

 

 

 // 필수 추가

 #include "Arduino.h"

 #include "Sample.h"

            ... ...

 

 void setup() {

            ... ...

 }

 

 void loop() {

            ... ...

 }

 

 void userfunction1() {

            ... ...

 }

 

 - 주석을 이용해서 프로그램

    설명, 저작권 표기 등 가능

 

 - 헤더 파일

 - 상수선언, 함수, 클래스 선언

 

 

 - 실제 소스 구성 부문

 - 사용자 라이브러리

 

 

 

□ 예제를 통한 확인

아래 예제는 아두이노 IDE에서 제공되는 Basic 예제인 Blink를 이용한 사용자 라이브러리 사용방법이다.

충분한 확인을 위해  고의로 기존 Blink.ino 단일 파일을 복잡한 여러 파일로 분리했다.

 

 그림) Blink.ino 의 분리 

- 단일 스케치 파일을 여러  라이브러리로 구성하여 사용성을 높임

 

 

1) 원본 소스 Blink.ino 확인

   - "파일 메뉴 - 예제"를 통해서 Blink.ino를 불러 온다.

 

 

2) Test.ino 생성 

   - Blink.ino를 다른이름으로 저장하여 Test.ino를 생성한다.

   - 저장한 후 Test.ino의 내용은 맨 마지막에 삭제해도 되고 이 단계에서 삭제해도 된다.

   - 해당 예제에서는 맨 마지막에 삭제하는 것으로 설정했다.

 

 

3) 새탭 메뉴를 이용, 신규  파일 생성 

  - 스케치를 통한 파일의 연결은 새탭을 통해서 가능하다.

 

 

4) 신규 파일명 부여 후 저장 

  - 하단 입력창을 통해서 이름부여 후 저장한다.

 

 

5) 반복해서 필요한 파일 전체 생성 

  - 예제를 통해 확인해 필요한 모든 파일을 생성한다.

  - Test.h, Test.cpp, Blink.h, Blink.cpp

 

 

6) blink.ino에서 원본 소스 복사

아두이노 IDE에서 제공되는 Basic 예제 "Blink" 소스 - blink.ino에서 복사해서 수정을 시작한다.

편의 상 복사한 것으로 내용을 수기 입력해도 당연히 된다.

}
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
}

 

// the loop function runs over and over again forever
void loop() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                // wait for a second
  digitalWrite(13, LOW);   // turn the LED off by making the voltage LOW
  delay(1000);                // wait for a second

 

7) 원본 소스에서 Blink.h, Blink.cpp 구성

  - 테스트를 위해 Blink 소스를 아래와 같이 수정해서 Blink.cpp로 저장한다.

  - 해당 작업으로 좀 더 유연하게 사용가능한 blinkInit, LEDon, LEDoff 함수를 만들 수 있다.

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

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

 

 

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

    
  digitalWrite(13, LOW);   
  delay(1000);               
}

 

 

 

 

 

void LEDon() {
  digitalWrite(13, HIGH);   
}

 

void LEDoff {

  digitalWrite(13, LOW);   
}

 

  - Blink.h와 Blink.cpp의 최종소스는 아래와 같다.

Blink.h

 Blink.cpp

void blinkInit();
void LEDon();
void LEDoff();

 

 

 

 

 

 

 

 

 

#include "Arduino.h"
#include "Blink.h"
 
void blinkInit() {
  pinMode(13, OUTPUT);
}

void LEDon() {
  digitalWrite(13, HIGH); 
}

 

void LEDoff() {
  digitalWrite(13, LOW);  
}

 

8) 원본소스에서 Test.h, Test.cpp 구성

  - 원소스인 Blink.ino에서 아래와 수정해서 메인 프로세스에 해당하는 Test.cpp도 생성한다. 

  - test.cpp는 Main 프로세스(C의 Main함수)에 해당하는 것으로 아래처럼 보다 직관적으로 구성이 가능해졌다.

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

void setup() {
  blinkInit(); 
}

 

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

    
  digitalWrite(13, LOW);   
  delay(1000);               
}

 

 

 

 

 

void loop() {
  LEDon();
  delay(1000);              

 

  LEDoff();
  delay(1000);             
}

 

  - Test.h와 Test.cpp의 최종소스는 아래와 같다.

Test.h

 Test.cpp

// Test.cpp에 사용자 함수가 없으므로

// Test.h에는 아무 것도 선언할 내용이 없다.

 

 

 

 

 

 

 

 

 

  

 

 

#include "Arduino.h"
#include "Test.h"
#include "Blink.h"

 

void setup() {
  blinkInit(); 
}

 

void loop() {
  LEDon();
  delay(1000); 


  LEDoff();
  delay(1000); 
}

 

10) 분리 완료(사용자 라이브러리 생성 완료 및 Test.ino 내용 삭제)

  - 최종적으로 Test.ino 의 모든 내용을 지운다. Test.ino는 어떠한 코드도 사용할 필요가 없게 된다.

  - 이후 Test.ino 파일의 용도는 프로그램 설명, 저작권 등에 대한 내용을 기재하는데 사용하면 된다.

 

11) 컴파일 및 확인

  - 컴파일이 성공적으로 끝난 것을 확인이 가능하며, 업로드하여 테스트해도 기존 Blink.ino와 동일한 내용 확인이

    가능하다.

 

 

 

 

12) 결론

  - Blink.ino 파일은 스케치파일(ino)와 메인파트(Test.cpp)와 사용자 라이브러리(Blink.cpp)로 분리가 되어

    보다 유연한 구조를 가지게 되었음을 알 수 있다.

  - 해당 예제는 고의로 복잡한 구성을 만들었다. 다만, 예제에서 알 수 있듯이 간단한 소스도 스케치 파일과

     소스파일을 분리하는 것이 구조 상 활용시 장점이 많게 된다.

 

끝으로, 이미 위에서 언급한 바와 같이 스케치 파일에서는 Arduino.h와 IDE에서 "새탭"으로 정의한 소스 및 헤더파일 들만 자동 추가된다. 따라서,

 

1. 소스 내에서 Serial 클래스와 같은 #include <Wire.h> 등을 사용할 때나 다른 라이브러리 등을 사용할 경우에는 

   스케치 파일에도 반드시 명시적으로 선언(#include로 기재)해 주어야 한다.

 

2. 사용되는 라이브러리들의 구성관계를 파악하기에 용이하므로 새탭 메뉴를 통해 정의된 사용자 라이브러리의

    헤더파일도 명시적으로 선언해 주는 것이 좋다.

 

를 유의해서 작성하는 것이 필요하다. 

 

즉, ino 파일은 프로그램의 전체 구조에 대한 맵과 같아서 사용되는 모든 라이브러리들을 명시적 선언해 주는 것이 좋은 방법이다.

 

 

샘플소스 :Test.zip

 

 

 

반응형

+ Recent posts