디버깅(Debugging)이란 프로그램에서 버그를 찾아 수정하거나 에러를 처리해나가는 과정을 말한다. 일반적으로 소프트웨어 디버깅의 경우 비주얼 스튜디오 등의 툴을 활용해 터미널 환경에서 쉽게 디버깅 메세지를 출력할 수 있는 반면 임베디드 환경에서는 외부에 출력하기도 힘들고 하드웨어적인 부분까지 같이 고려해야 하므로 다소 어렵다. 때문에 하드웨어를 디버깅 할때는 JTAG 등의 전용 디버깅 장비를 활용하여 프로세서를 특정 시점에서 멈추게 하거나 각각의 명령어 단위로 하나씩 실행시키는 방법으로 진행하는데 이러한 방식을 하드웨어 디버깅, 혹은 소스 레벨 디버깅(Source Level Debugging)이라고 한다. 


이번 포스팅에서는 프로테우스 툴을 활용하여 전에 사용했던 외부 인터럽트 코드와 회로를 가지고 소스 레벨 디버깅하는 방법에 대해 다뤄보겠다.



1. 필요 파일


앞서 소스 레벨 디버깅을 위해서는 JTAG 같은 전용 장비가 필요하다고 언급했었다. 하지만 프로테우스에서는 cof 파일이나 elf 파일을 보드에 넣어주면 실제 컴파일러에서 디버깅 하는 것과 유사하게 소스 레벨 디버깅을 할 수 있는 기능을 지원한다. 그렇다면 여기서 cof와 elf 파일이 무엇이길래 위와 같은 일들을 가능하게 하는 것일까? 


cof 파일은 COFF(Common Object File Format) 형식의 파일을 말하는 것으로 어셈블러를 거쳐서 만들어진 오브젝트 파일에서 공통된 성질의 것들을 모아 관리하는 포맷을 의미한다. 잘 이해가되지 않는다면 프로그램의 컴파일 과정에 대해 떠올려보자. 개발자가 작성한 .c 파일은 어셈블러에 의해 기계어로 변환된 .o 오브젝트 파일로 생성되고 이렇게 생성된 각각의 오브젝트 파일을 링커가 합쳐서 실행 파일로 만들어진다. 그런데 이렇게 생성된 실행 파일은 수많은 프로그램들이 합쳐져 있기 때문에 프로그램 메모리에 일일이 분산시켜 옮기는 과정이 매우 번거롭고 많은 시간이 필요하는 문제점이 있다. 때문에 이러한 문제를 해결한 것이 바로 COFF 형식이다. 


COFF는 합쳐진 모든 프로그램과 데이터를 각각의 세션별로 구분하는 역할을 한다. 이 세션에는 컴파일된 코드가 들어가는 프로그램 코드 세션, 데이터가 저장되는 상수 데이터 세션 및 사용자 정의 데이터 세션 등 공통된 성질을 가지는 것들이 분류별로 나뉘어지며, 이로 인해 세션 별로 관리하기 용이하고 각 세션이 배치된 메모리의 영역과 크기도 확인할 수 있다. 또한 단순하게 기계어로 되어있는 HEX 파일에 비해 여러가지 프로그램에 대한 정보를 가지고 있기 때문에 디버깅에 유용하게 사용할 수 있다.


ELF (Executable and Linking Format) 의 개념도 마찬가지로 COFF와 비슷하며 단지 기존 형식의 단점을 개선하여 좀 더 복잡하고 그만큼 유연하게 동작할 수 있는 형식이다. 사실 임베디드 환경에서 COFF가 강력하기는 하지만 지금 사용하기에는 너무 오랜된 형식이며 컴파일러에 따라 해석이 조금씩 달라질 수 있는 문제점이 있기 때문에 가능하면 ELF 형식의 파일을 사용할 것을 권한다. 아래는 ELF 형식의 구성도이며 2가지 형태로 나눌 수 있는데, 먼저 왼쪽의 Linkable File은 Link 하기 전의 오브젝트 파일을 칭하고 오른쪽의 Executable File은 Link가 끝나고 실행 가능한 형태의 elf 파일을 말한다.  



보다 세부적인 내용들은 그 개념이 방대하기 때문에 따로 검색해볼 것을 추천하며 여기서는 우리가 시뮬레이션할 때 사용했던 HEX 파일과 어떤 차이점이 있는지만 명확하게 알고 넘어가도록 하자.



2. 디버깅 기능


코드비전에서는 기본적으로 cof 파일이, avrstudio에서는 elf 파일이 프로젝트 빌드시 자동으로 생성되며 필자는 코드비전 컴파일러를 사용하기 때문에 cof 파일로 디버깅을 진행하였다. 이전 포스팅에서 사용했던 회로를 가져오고 HEX 파일 대신 cof 파일을 보드에 넣어보자. 그리고 시뮬레이션을 시작한뒤 Debug 메뉴를 살펴보면 다음과 같은 항목들이 나타날 것이다.





이 기능들은 소스 레벨 디버깅에 있어서 많은 도움이된다. 먼저 소스 코드 항목을 눌러보면 신기하게도 우리가 컴파일한 코드가 그대로 프로테우스에서 확인할 수 있다. 왼쪽 숫자는 각 명령어의 주소를 가리키며 순차적으로 PC 레지스터에 저장된다. 여기서 명령어를 하나씩 실행시키면서 프로그램이 수행되는 순서를 모두 추적해볼 수 있고 명령어 라인 위에다 마우스를 더블 클릭하면 BreakPoint가 지정되어 시뮬레이션 수행 도중 해당하는 포인트에서 멈추게 할 수도 있다. 또한 Ctrl + D 단축키를 누르면 해당 소스 코드를 어셈블리어 레벨에서 해석도 가능하다.



다음은 2번째 항목인 Variables 이다. 여기서는 소스 코드에서 전역으로 설정한 변수들의 이름과 주소, 그리고 값을 표시해주며, 마우스 오른쪽 버튼을 눌러서 Add to Watch Window를 클릭하면 시뮬레이션 도중에 Watch Window 창을 통해 해당 변수들의 값이 바뀌는 것을 즉시에 확인해 볼 수 있다. 중간에 .bss 변수의 경우에는 COFF 세션의 한 종류이며 초기화되지 않은 전역 변수들이 들어가는 부분이니 고려하지 않아도 된다.



세번째는 CPU Register 항목으로 ATmega128에서 사용하는 레지스터들의 값들을 확인할 수 있다. 먼저 PC 레지스터에서는 현재 연산중인 명령어의 주소가 나오며, INSTRUCTION 에는 연산중인 명령어가 어셈블리어로 어떤 레지스터에 어떻게 연산되는지 보여준다. 그리고 SREG 레지스터는 현재 상태에 대한 것들을 보여주며, 그 옆에 ITHSVNZC 는 SREG 레지스터 각 비트의 값들을 표시한다. 마지막으로 CYCLE COUNT 는 각 명령어를 얼마나 실행했는지 알려주는 역할을 하게 된다.



간단하게나마 이렇게 주요 디버깅 기능들에 대해 설명해 보았으며 나머지 기능들도 상황에 따라 유용하게 쓰일 수 있으므로 따로 확인해볼 것을 권한다.



3. 디버깅 하기


그러면 이제 위 기능들을 활용하여 프로테우스 툴에서 디버깅을 진행해보도록 하자. 코드와 회로는 모두 전 포스팅을 참고하기 바라며 ATmega128에 cof 파일을 넣고 다음과 같이 세 부분에 Break Point를 설정하여 외부 인터럽트 0번의 동작 과정을 살펴보는 것이 목표이다.



시뮬레이션을 시작해서 외부 인터럽트에 연결된 버튼을 누르고 각 값들이 어떻게 바뀌는지 확인해보자.



가장 먼저 SREG 가 15로 바뀐 것이 눈에 보인다. 이는 외부 인터럽트가 동작할 때 다른 외부럽트가 접근하지 못하도록 설정되어 있기 때문에 자동으로 바뀐 것이며, 만약 중복 인터럽트를 허용하고 싶다면 코드 안에 SREG 레지스터의 I 비트를 다시 1로 설정해주면 가능하다. 또한 INSTRUCTION에 LDR R30, $01 이라는 명령어는 R30 레지스터에 1의 상수를 전송하는 역할을 한다. 이제 다음 Break Point로 넘어가보자.



이번에는 인터럽트 코드 안을 벗어나면서 SREG 레지스터가 다시 허용되었음을 확인할 수 있으며 status 변수에도 1의 값이 쓰여졌다. 이 값들이 어디에 있는지 확인하기 위해 변수 주소를 따라가면 위와 같이 Data Memory 기능에서 각각 500번지와 502번지에 1이 쓰여져 있음을 알 수 있다. 여기서는 501번지가 왜 0인지가 중요한데, 그 이유는 status가 2바이트인 int 자료형이기 때문이며 또한 ATmega128이 Little-endian 방식이기 때문에 하위 비트가 먼저 쓰여져 500번지에는 01이, 501번지에는 00이 쓰여졌다고 알아두도록 하자.


다음으로 넘어가면 temp 에는 0x02의 값이 쓰여지고 LED가 Shift 되게 된다. 그 다음에 status 가 0이 되면서 앞서 설정했던 Break Point가 모두 끝나게 되며 여기서 한가지 재밌는 부분이 status 가 0으로 초기화 될 때의 명령어 주소가 없다는 점이다. 실제로 명령어를 하나씩 실행해 나가면 status 변수가 2일 때의 코드 맨 밑에 있는 명령어로 동작하게 되는데, 필자의 생각으로는 같은 명령어가 중복되기 때문에 컴파일러가 코드를 최적화 하면서 2개의 명령어를 하나로 합치지 않았나 하는 생각이 든다. 정확히는 모르겠으나 재밌는 상황인건 분명하다.



이렇게 ATmega128의 소스 레벨 디버깅 방법에 대해서 프로테우스 툴을 사용하여 알아보았다. 사실 어렵게 보이긴 해도 가장 기초적인 부분만 소개했기 때문에 막상 해보면 별거 아니다라는 생각이 들 것이다. 펌웨어 단에서는 소프트웨어 뿐만 아니라 하드웨어도 매우 중요하기 때문에 이러한 디버깅 방법을 잘 익혀둬서 유용하게 써먹을 수 있기를 바란다.

 [출처] COFF|작성자 gwoook



'Electronic > AVR' 카테고리의 다른 글

외부 인터럽트  (0) 2017.06.08
인터럽트 이해하기  (0) 2017.06.06
프로테우스 사용하기  (1) 2017.06.02


외부 인터럽트(External Interrupt)는 앞서 확인했던 인터럽트 벡터 테이블에서 RESET을 제외한 가장 우선순위가 높은 인터럽트로, 하드웨어에 가해지는 전압의 변화에 따라 발생하게 된다. 외부 인터럽트가 있으니 내부 인터럽트도 있지 않을까 하고 생각할 수 있지만 사실 내부 인터럽트라는 개념은 없으며 단지 MCU의 I/O 포트를 통해 외부에서 인터럽트를 수신하기 때문에 외부 인터럽트라고 한다. 


ATmega128에서는 총 8개의 정해진 핀에서만 사용할 수 있으며 간단한 설정을 통해 바로 사용해볼 수 있으므로 프로테우스 툴을 사용하여 내부적으로 어떻게 동작하는지 확인해보자.



1. 레지스터 설정


외부 인터럽트를 사용하기 위해서는 먼저 각 핀에서의 인터럽트 발생을 허용해야 한다. 이러한 역할을 하는 레지스터가 바로 EIMSK (External Interrupt Mask Register) 이며 각 비트별로 단순하게 어떤 핀을 외부 인터럽트 핀으로 사용할 것인가를 결정한다. 사용하고자 하는 인터럽트가 있으면 해당 비트에 1을 세트시키면 된다.



다음으로 EICRA (External Interrupt Control Register A) 는 이름에서 알수 있듯이 실제 인터럽트가 발생하는 시점을 결정하는 레지스터로 INT0 ~ INT3 까지의 외부 인터럽트 발생 시점을 결정한다. 각 비트들을 살펴보면 인터럽트 별로 두 비트씩 할당되어 있음을 알 수 있으며 나머지 인터럽트는 EICRB 레지스터에 같은 규칙으로 적용되어 있다.



비트 설정에 따라 인터럽트가 발생하는 시점은 아래 표와 같으며, 쓰지 않는 Reserved를 제외하면 총 3가지의 신호를 통해 인터럽트를 제어할 수 있다. 예를 들어 ISC01=1, ISC00=1 로 설정하면 포트 0번을 0V에서 5V로 변할때, 즉 상승 엣지(Rising Edge)에서 인터럽트가 발생하게 된다.  



다음은 인터럽트 요청이 발생했을때 해당 비트가 1로 세트되고 인터럽터 종료시 0으로 클리어되는 EIFR (External Interrupt Flag Register) 레지스터이다. 사실 잘 쓰이진 않는 레지스터이며 특이하게도 1이 세트되어 있는 상태에서 다시 1을 써주면 0으로 클리어되는 방식으로 동작한다. 마치 내부적으로 ~(input)  과 같이 동작하는 것 처럼 보인다. 그리고 클리어 되었다고 해도 단순히 해당 플래그가 0으로 바뀔뿐 인터럽트는 이 레지스터와 별개로 계속해서 발생할 수 있다.   



활용 예를 간단하게 보여주고 싶은데 찾아봐도 마땅한 것이 안보인다. 정말 특수한 목적이 있지 않은 이상 위 레지스터를 건드릴 이유는 딱히 없을듯 싶다.


마지막으로 모든 인터럽트를 허용하는 레지스터인 SREG (Status Register) 이다. SREG 레지스터에서 전역적으로 인터럽트 발생을 허용하는 비트는 7번 비트이며 나머지 비트들은 산술 연산이나 논리 연산에 사용되는 비트이므로 이 레지스터에 접근할 때 다른 비트들을 건들지 않도록 주의해야한다. 예를 들어 단순히 대입 연산을 해버리면 다른 비트의 값들을 잃어버릴 수 있으므로 SREG |= 0x80 같은 방식으로 7번 비트만 세트시키거나 컴파일러에서 지원하는 함수인 sei 함수를 사용하면 된다. 



정리하면 각각의 핀에 따라 개별적으로 인터럽트를 허용하고, 인터럽트의 발생 시점을 설정한 후 모든 인터럽트의 발생을 허용하면 그 시점 부터 인터럽트를 발생시킬 수 있게 된다.



2. 예제 코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <io.h>
 
volatile int status = 0;
volatile char temp = 0x01;
 
interrupt [EXT_INT0] void ext_int0_isr(void)
{
    status = 1;
}
interrupt [EXT_INT1] void ext_int1_isr(void)
{
    status = 2;
}
 
void main(void)
{
    EIMSK = 0x03;
    EICRA = 0x0A;
    DDRB = 0xFF;
    PORTB = 0x01;
    #asm("sei")
 
while (1)
      { 
        if(status == 1)
        {
            temp = temp << 1;
            if( temp == 0x00)
                temp = 0x01;
            PORTB = temp;
            status = 0;
        }
        else if(status == 2)
        {
            temp = temp >> 1
            if( temp == 0x00)
                temp = 0x80;       
            PORTB = temp;
            status = 0;
        }
      }
}
cs


위 코드는 버튼을 누를 때 마다 불이 켜진 LED 위치를 좌우로 바뀌는 간단한 코드이다. INT0과 INT1을 하강 엣지 신호로 처리하고 있으며, 컴파일러가 자동으로 최적화 시키는 것을 방지하기 위해 2개의 변수를 volatile로 선언하였다.또한 인터럽트 수행시 걸리는 시간을 최소화하기 위해 내부적으로 동작하는 코드를 main에 두고 플래그(flag) 변수만 사용하여 인터럽트의 발생 유무를 확인할 수 있게 했다. 이러한 작업은 단순해 보여도 코드 최적화 부분에서 매우 중요하기 때문에 되도록이면 인터럽트 루틴에 걸리는 시간을 최소화 시키는 것이 좋다.



3. 시뮬레이션



간략히 외부 인터럽트의 개념에 대해 설명해 보았다. 다음 포스팅에서는 프로테우스의 디버깅(Debugging) 기능을 활용하여 외부 인터럽트가 내부적으로 어떻게 동작하는지 확인해보자.


'Electronic > AVR' 카테고리의 다른 글

소스 레벨 디버깅  (0) 2017.06.14
인터럽트 이해하기  (0) 2017.06.06
프로테우스 사용하기  (1) 2017.06.02


인터럽트(Interrupt)란 프로그램이 동작하는 도중에 발생하는 비정상적인 사건을 말한다. 사실 여기서 비정상적인 사건이란 표현은 너무 딱딱한 어투의 말처럼 들리기 때문에 ‘기존의 흐름과는 다른 일’ 혹은 ‘의도하지 않은 일’, ‘생각하지 못한 문제’ 정도로 순화해서 생각하면 이해하기 편할듯 싶다. 그러면 이러한 인터럽트가 사용되게 된 이유는 무엇일까? 이 물음을 대답하려면 운영체제에 대한 개념을 빼놓을 수 없다.



컴퓨터의 운영체제는 외부 장치의 동작과 자신의 시스템 동작을 보다 수월하게 조정하기 위해 인터럽트를 사용한다. 예를 들어 어떤 프로그램이 동작하고 있는 상황에서 키보드와 마우스 같은 입력이 들어오게 되면 현재 프로그램의 상태를 저장하고 각각의 입력을 구분해서 처리해야 한다. 만약 여러 입력장치가 동시에 동작한다고 해도 데이터를 손실하지 않고 수행해야 하므로 언제 어떤 장치에서 입력이 들어왔는지 일일이 확인할 수 있어야 한다. 이때 사용되는 개념이 바로 인터럽트이며 컴퓨터의 프로세서는 외부 장치의 인터럽트 요청 회선 (IRQ, Interrupt Request Line)을 통해 각 장치의 상태를 확인한다. IRQ는 데이터 제어선의 일종으로 해당 입력이 발생했을 때만 전송되기 때문에 프로세서가 각 장치의 상태를 직접 점검할 필요가 없게 된다.


IRQ가 들어오게 되면 운영체제에서는 해당 인터럽트에 대해 적절한 처리를 하게 되는데 이때 발생 원인에 따라 적절한 처리 루틴을 수행하는 것이 바로 인터럽트 서비스 루틴(ISR, Interrupt Service Routine)이다. 쉽게 말해 운영체제에서 프로그램을 수행하는 도중 IRQ가 발생하면 현재 상태를 저장하고 ISR로 분기하여 해당 인터럽트를 처리하고 다시 돌아오는 과정을 거치게된다. 이를 그림으로 표현하면 다음과 같다.



처리 과정을 간략히 설명하자면 메인 프로그램이 동작하는 도중에 IRQ가 발생했을 때 운영체제에서는 현재 명령어를 종료하고 모든 레지스터의 값을 스택 영역에 저장한다. 이때 PC(Program Count) 레지스터에는 ISR이 처리할 프로그램의 시작 위치를 저장하고 인터럽트 프로그램에 제어권을 넘겨 실행한다. ISR에서 프로그램 수행이 완료되면 스택 영역에 저장해 두었던 레지스터를 복원하고 메인 프로그램의 위치에서 다시 시작하는 것으로 인터럽트 처리가 완료된다.


위 일련의 과정은 마치 서브 루틴의 호출과도 유사해 보인다. 하지만 큰 차이점 하나가 있는데 바로 현 상태 저장 유무이다. 서브 루틴의 경우 호출된 프로그램과 연관된 기능을 수행하고 그대로 종료되지만, 인터럽트는 호출된 프로그램과 관련이 없을 수 있기 때문에 다시 돌아갈 수 있도록 관련 레지스터들을 모두 저장해놓고 분기해야 된다. 이 때 중요한 역할을 하는 것이 바로 PC 레지스터이며, 이 레지스터가 다음 수행할 명령어들의 주소값을 모두 저장해놓기 때문에 인터럽트가 끝나면 안전하게 다시 원래 수행 위치로 돌아갈 수 있다. 따라서 위와 같은 과정을 통해 메인 프로그램은 인터럽트의 영향을 받지 않고 수행을 재개하게 된다.


간략하게 인터럽트의 개념에 대해서 알아보았는데 그러면 MCU를 제어하기 위해 사용하는 인터럽트도 마찬가지로 운영체제의 인터럽트와 같은 개념일까? 사실 같으면서도 약간 다르다고 볼 수 있다. 앞서 운영체제의 인터럽트는 ‘의도하지 않은 일’을 처리하는 것으로, 예를 들어 사용자의 의도치 않은 입력이 발생하거나 잘못된 명령어를 수행하려고 할 때 운영체제가 알아서 처리해주는 소프트웨어적인 개념으로 생각하면 된다. 반면에 MCU를 제어하기 위해 사용하는 인터럽트는 ‘언제든 발생할 수 있는 일’을 ‘미리 설정된 대응 방법’ 대로 처리하는 것을 의미한다. 여기서 ‘발생할 수 있는 일’이란 미리 설정해둔 입력 정도로 이해하면 되고 ‘대응 방법’은 해당 입력에 대해 어떻게 처리할 것인가에 대한 구체적인 해결 방법 정도로 이해하면 좋을듯 싶다.

 

그런데 두 개의 개념이 별개가 되는 것으로 이해하면 곤란하다. 보다 정확히 말하자면 운영체제는 인터럽트를 모두 포괄하는 개념으로, 예를 들어 컴퓨터의 리셋 버튼 같은 경우에는 MCU의 인터럽트 개념을 내포하고 있다. 위에서는 하드웨어 인터럽트를 좀 더 강조하기 위해 강제로 구분했을 뿐 실상 인터럽트는 운영체제의 탄생과 같이 시작된 개념이기 때문에 여기서는 하드웨어적인 인터럽트의 기본적인 정의만 숙지하고 넘어가도록 하자.

 

다음으로는 우리가 사용할 MCU인 AVR을 제어하기 위해 사용하는 인터럽트에 대해 살펴보자. ATmega128의 인터럽트 벡터 테이블은 다음과 같다.

 

 


위 표는 ATmege128에서 사용할 수 있는 모든 인터럽트의 종류를 나타내며, 보드 종류에 따라 지원하는 인터럽트의 종류와 벡터 주소값이 다르기 때문에 프로그램이 호환되지 않음을 알고있어야 한다.(해당 보드에 맞춰 다시 컴파일을 시켜주면 된다) 여기서 주의 깊게 봐야할 부분들이 몇 가지 있는데 먼저 ATmega128이 8bit 프로세서 임에도 불구하고각 벡터의 주소 크기가 2바이트로 설정되어 있음을 확인할 수 있다. 사실 일반적으로 메모리의 기본 단위는 1바이트인데 ATmega128 에서는 프로그램 메모리의 기본 단위가 1워드(2바이트)이며 주소 또한 1워드 단위로 부여된다. 이는 ATmega128의 모든 명령어 단위가 1워드를 기반으로 하기 때문에 보다 프로그램 처리 효율성을 높이기 위한 측면에서 그러한 것으로 이해하자.

 

다음으로 인터럽트의 주소는 0x0000 ~ 0x0044 까지 할당되어 있음을 확인할 수 있으며 이 주소의 값은 모두 프로그램 메모리의 주소에 해당 된다. 그리고 각각의 벡터 번호는 우선 순위를 나타내는 것으로 만약 인터럽트가 동시에 걸릴 경우 위 테이블의 번호에 따라 가장 우선 순위가 높은 인터럽트 부터 먼저 처리하게 된다. 테이블을 보면 0x0000에 해당하는 리셋 인터럽트가 가장 최우선 순위임을 확인할 수 있다.


그렇다면 인터럽트가 수행되는 도중에 또다른 인터럽트가 걸리게 되면 어떻게 될까? 8051 같은 MCU의 경우에는 중복 인터럽트가 허용되지만 ATmega128에서는 인터럽트 수행중에는 다른 인터럽트의 접근이 금지되어있다. 따라서 수행중인 인터럽트가 완료된 후 우선 순위에 따라 다음 인터럽트를 처리하게 된다. 물론 이를 인터럽트 처리 코드 안에서 허용할 수는 있지만 이렇게 되면 구현하려는 시스템이 복잡할수록 불안정하고 제어하기 힘들어질 수 있으므로 그다지 권장하지 않는 부분이다. 


'Electronic > AVR' 카테고리의 다른 글

소스 레벨 디버깅  (0) 2017.06.14
외부 인터럽트  (0) 2017.06.08
프로테우스 사용하기  (1) 2017.06.02


프로테우스는 가상 실험을 통해 회로를 설계하고 점검할 수 있을 뿐만 아니라 완성된 회로를 PCB 제작까지 할 수 있는 통합 시뮬레이션 프로그램이다. 회로 시뮬레이션 하면 Orcad나 Multisim 같은 툴들이 생각나겠지만 프로테우스는 하드웨어가 주가 아닌 소프트웨어와 주변 회로 해석에 중점을 두고 있기 때문에 앞서 언급한 툴들과 성격이 약간 다르다. 특히 최근 버전인 8.6에서는 8051, AVR 등의 오래된 프로세서부터 아두이노, STM32M0, M3 까지 다양한 MCU 들을 지원하기 때문에 소프트웨어 점검과 디버깅을 빠르게 진행할 수 있고 공부하는 입장에서 또한 유용하게 쓰일 수 있다. 



본 포스팅에서는 간단하게 프로테우스 8.6 툴의 사용법과 기본 설정 및 테스트를 진행해볼 것이며 앞으로 AVR 관련 글들도 모두 프로테우스를 활용할 예정이다.



1. 프로젝트 생성



프로테우스를 실행하면 위와 같은 첫 화면이 나타난다. 좌측 상단에 File 을 누르고 New Project를 클릭하여 원하는 이름의 프로젝트를 생성하도록 하자. 생성 과정에서 화면 크기는 Landscape A3 정도가 무난하며 PCB layout은 본 포스팅에서 다루지 않기 때문에 그냥 넘어가도록 한다.



위 화면은 프로테우스 툴에서 직접 펌웨어까지 개발할 것인가를 묻고 있다. Create Firmware 선택시 사용할 MCU와 컴파일러를 설정할 수 있으며 사실 이 부분도 선택사항이긴 하지만 프로테우스 툴에서 코드를 짜는 것 보다 다른 컴파일러를 사용하는 것이 편하기 때문에 No Firmware Project 를 선택하도록 하자. 그럼 다음과 같은 초기 화면이 나타날 것이다.




2. 단축키 설정


다른 회로 시뮬레이션 툴을 사용한 경험이 있다면 프로테우스를 사용하는데 있어서 그다지 어렵지 않으며 몇번 사용하다보면 쉽게 익숙해질 수 있다. 그런데 특이하게도 한 가지 불편한 점이 있는데, 바로 단축키 부분이다. 필자가 많은 툴들을 다뤄본 것은 아니지만 이제까지 살면서 가장 기본적인 Ctrl + C 와 Ctrl + V 단축키 조차 디폴트로 지정되어 있지 않은 툴은 처음 봤다. 따라서 가급적 기본적인 단축키 정도는 지정하고 툴을 사용하기를 바란다. 단축키는 메뉴에서 System 탭의 Set Keyboard Mapping 항목에서 설정할 수 있다.


 

설정 방법은 위와 같이 명령어를 클릭하고 밑의 No Key Set 부분에 설정할 단축키를 입력한 뒤 Assign을 클릭하면 할당이 완료된다. 추가적으로 도형을 회전시키는 Rotate 키를 R 로 설정해두면 보다 편하게 사용할 수 있으며 나머지는 툴을 직접 사용하면서 불편한 부분만 개인적으로 설정하기 바란다.



3. LED 점멸


그럼 프로테우스 툴을 사용하여 ATmega128 보드에 간단한 LED 점멸 코드를 삽입하고 시뮬레이션을 진행해보자. ATmega128 보드 및 기타 모든 부품들은 단축키 P를 눌러서 찾을 수 있다.



마찬가지로 Led와 저항을 찾아서 다음과 같은 회로를 구현하도록 한다. 이때 LED는 Active 라이브러리를 선택해야 시뮬레이션에서 시각적으로 불이 켜지는지 확인할 수 있다. (LED-BLUE, LED-RED 등의 부품을 선택하면 된다) 또한 저항을 더블 클릭하면 저항 값을 바꿀 수 있으며 접지나 파워는 부품이 아니므로 왼쪽 메뉴에서 Terminals Mode 탭을 클릭하면 가져올 수 있다. 완성된 회로는 다음과 같다.



실행 코드는 다음과 같으며 필자는 CodeVision 컴파일러를 사용하였다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <io.h>
#include <delay.h>
 
void main(void)
{
    char temp = 0x01;
    DDRB = 0xFF;
 
while (1)
    {
        PORTB = temp;
        delay_ms(300);
        temp = temp << 1;
        if( temp == 0x00)
            temp = 0x01;
    }
}
cs

프로테우스의 AVR에 위 프로그램 코드를 집어넣으려면 해당 코드의 HEX 파일이 필요하다. HEX 파일은 컴파일러를 통해 프로그램을 빌드하면 자동으로 생성되며 위 그림에서 atmega128을 더블 클릭하여 설정창으로 이동한 후 Program File 항목에 HEX 파일의 경로를 설정하도록 하자.



그리고 기본 설정이 내부 RC 클락으로 동작하게 되어 있으므로 위 빨간색 부분에 외부 클락으로 설정한 뒤 밑에 16MHz로 설정해두면 시뮬레이션에 필요한 초기 설정이 모두 완료되었다. 이제 설정창을 닫고 메인화면 밑에 시뮬레이션 시작 버튼을 클릭하여 프로그램이 잘 동작하는지 확인해보자.




간단하게 프로테우스 사용법에 대해 알아보았다. 사실 본 포스팅에서는 가장 기초적인 부분만 다루었으며 방대한 부품들을 지원할 뿐만 아니라 오실로스코프, 로직 아날라이저, 터미널 등 다양한 부가 기능들을 지원하기 때문에 MCU를 사용한 회로 설계에 있어서 유용하게 사용할 수 있을 것이다. 앞으로 AVR 관련된 포스팅들을 준비하면서 하나하나 소개하도록 하겠다.

'Electronic > AVR' 카테고리의 다른 글

소스 레벨 디버깅  (0) 2017.06.14
외부 인터럽트  (0) 2017.06.08
인터럽트 이해하기  (0) 2017.06.06

1. 무선통신기술

 스마트폰이 등장하면서 현 음악 시장과 오디오 시장을 혁신적으로 바꾼 것은 반박의 여지가 없는 사실이다. 1993년에 MPEG-1의 오디오 규격에 맞게 개발된 압축 포맷인 MP3가 등장하게 되면서 더 이상 LP나 CD로 음악을 듣는 것은 구시대적 이야기가 되어 버렸고 여기에 스마트폰이 개발되면서 음악 시장을 송두리째 바꾸어 버렸다. 때문에 이러한 시대적 흐름에 따라 음반 가게는 찾아보기 힘들게 되었고 CD또한 잘 팔리지 않았으며, CD 플레이어나 턴테이블 같은 오디오 장비는 고리타분한 골동품으로 가치가 떨어지게 되었다. 대신에 그 자리를 스마트폰 같은 기기들이 차지하면서 음악 감상을 단순한 취미 생활이 아니라 사람들 생활 속의 일부로 대중화시키게 되었다.

 이처럼 음악이 대중화되고 생활화 되면서 사람들은 손실 없는 아날로그의 고음질을 추구하기 보다는 조금 음질이 떨어지더라도 음악을 언제 어디서나 간편하게 들을 수 있는 편리함을 추구하는 방향으로 수요가 변화하게 되었는데 이러한 흐름이 지속되면서 ‘무선통신’ 기술이 발전하게 되는 계기를 마련해주었다. 실제로 아래 통계를 살펴보면 무선통신기술을 활용한 오디오 시장이 기존의 스피커나 이어폰 시장보다 훨씬 커졌다는 사실을 알 수 있으며 또한 출하량과 사용 현황 그래프를 통해 예전에 LP나 CD에서 MP3로 트랜드가 변화한 것처럼 이제는 일반 오디오 장비에서 무선 기술을 활용한 시스템으로 사람들의 수요가 바뀌고 있음을 짐작할 수 있다.


Fig 1. 오디오 기기 시장 변화 추이


 그렇다면 무선통신기술이란 대체 무엇일까? 무선통신이란 이름 그대로 별다른 선 필요 없이 보다 음악을 편리하게 들을 수 있도록 해주는 것을 말한다. 단순히 스마트폰과 무선으로 연결해줄 수 있는 오디오 장비만으로도 간단하게 음악을 즐길 수 있게 되는 것이다. 이러한 기술은 비단 휴대성만 갖춘 것이 아니라 활용 가치 또한 매우 높다. 예를 들어 공연장에서 마이크나 악기에 무선통신기술을 적용하여 케이블 없이 공연을 할 수 있다는 것이나 여러 대의 스피커를 하나의 네트워크로 연결하여 같은 음악을 듣거나 각기 다른 음악을 듣는 등 음악이 필요한 모든 분야에 확장성 있게 적용 가능하다. 따라서 이러한 점들을 볼 때 무선통신분야는 앞으로 발전가능성이 무궁무진하며 하나의 트랜드로서 자리매김할 수 있을 것이라 기대해볼 수 있다.


2. 무선통신시스템 구조

 무선통신기술을 활용한 시스템은 통신 방법에 따라 차이가 있기는 하지만 기본적으로 다음과 같은 구성 요소를 공유한다. 먼저 오디오 소스란 오디오 신호를 포함하는 장치, 즉 음원을 저장하고 전송할 수 있는 스마트폰 같은 기기를 의미하며 오디오 송신부를 통해 신호를 무선으로 전송하게 된다. 다음으로 싱크 라고도 불리는 오디오 수신부가 전송된 신호를 수신하게 되고 이를 재생할 수 있는 재생장치로 전달함으로서 무선 오디오 전송이 완료된다.


Fig 2. 무선통신시스템 구조


 위 같은 구조의 가장 적절한 예가 바로 FM 라디오이며 비록 오디오 음질이 좋지는 않지만 전송 시스템이 비교적 간단하기 때문에 작은 송신기만으로도 신호를 전송할 수 있으며 전파가 도달하는 범위 이내라면 언제 어디서든지 수신기를 통해 신호를 들을 수 있다는 장점을 가진다.

Fig 3. FM라디오 구조


3. 무선통신기술 종류

▪ 블루투스 통신

 블루투스(Bluetooth) 통신은 본래 오디오 신호 전송이 아닌 근거리 데이터 통신을 위해 개발된 기술이다. 때문에 초기에는 이러한 물리적 기반을 바탕으로 무선 키보드나 마우스, 혹은 디바이스간 데이터 전송을 위해 사용되었으며 오디오 신호 전송과 관련해서는 HFP라는 휴대전화 통신간에 음성을 송수신할 수 있는 프로파일을 지원하였다. 하지만 이러한 부분은 단순한 음성 전달에 불과했으며 주파수 대역폭이 불과 8Khz로 제한되기 때문에 고음질의 오디오 전송을 위한 용도는 아니었다. 따라서 오디오에 대응할 수 있도록 만든 블루투스용 프로파일이 별도로 만들어지게 되었는데 이것이 바로 A2DP(Advanced Audio Distribution Profile) 이다.

 A2DP란 블루투스 통신의 대역폭 내에서 오디오 신호를 전송할 수 있도록 신호를 SBC(Sub Band Coding) 코덱을 통해 압축하여 보내는 프로파일을 의미하며 이렇게 보낸 신호는 오디오 수신부에서 다시 SBC 코덱을 통해 디코딩하여 소리를 재생시킬 수 있다. 비록 신호를 압축하는 과정에서 음질의 저하가 있지만 오디오 신호의 무선 전송을 가능하게 했기 때문에 스마트폰과 블루투스 스피커 및 헤드셋에 표준기능으로 적용되었다.


Fig 4. Source-Sink 간 블루투스 통신 과정


 그런데 사실 SBC 코덱은 다른 코덱에 비해 압축 효율이 뛰어나지 않으며 음질이 초창기 MP3 수준에 불과하여 비효율적인 요소가 많다. 또한 대역폭 자체가 좁아서 고역대의 소리를 제대로 전송하기 힘들다는 단점을 지닌다. 때문에 최근에는 보다 효율적인 압축 알고리즘을 활용한 애플의 AAC(Advanced Audio Coding)이나 소니의 LDAC가 대안으로 활용되고 있으며 이 가운데에서 오디오 대역폭을 늘리고 지연시간을 최소화한 CSR의 apt-X 코덱이 가장 대중적인 주목을 받고 있다.


Fig 5. apt-X Codec


 우리의 귀는 어느 한 주파수에서 큰 소리가 울릴 때, 이와 동시에 발생하는 주변 주파수의 약한 소리가 들리지 않는 특성을 가진다. 이를 마스킹 효과(Masking effect)라고 하는데 apt-X 코덱은 이와 같은 특성을 응용하여 마스킹되는 주파수의 정보를 삭제하여 데이터량을 줄일 수 있는 알고리즘을 토대로 구현되었다. 이는 결과적으로 보다 효율적인 데이터 전송을 가능하게 해주었을 뿐만 아니라 CD수준의 고음질 오디오 신호를 무선으로 전송할 수 있게 하였다.

 그리고 코덱에 따른 차이는 비단 음질뿐만이 아니라 지연시간에서도 나타난다. SBC 코덱은 패킷이 전송될 때 정해진 양의 패킷이 전송되기 전까지 디코딩을 진행하지 않는 방식인 반면에, apt-X코덱의 경우 ‘apt-X 워드’ 라는 작은 데이터로 분할 전송하고 이를 수신 단계에서 순차적으로 받아서 처리하는 방식으로 동작한다. 이러한 차이는 각 코덱의 지연시간을 보면 명확해지는데 apt-X 코덱의 지연시간이 40ms인 것에 비해 SBC 코덱은 250ms로 확연하게 차이가 난다는 사실을 알 수 있다.

 물론 아직까지 통상적인 블루투스 오디오 장비들은 대부분이 SBC 방식이며 apt-X 방식의 경우 같은 코덱의 장비끼리만 적용이 가능하다는 단점이 있기는 하지만 사람들의 음악에 대한 편리함과 음질에 대한 수요가 점점 증가하는 추세를 감안해 봤을 때 앞으로 기술이 점점 더 발전하여 압축 코덱의 표준으로 인정받을 수 있을 것이라 기대해볼 수 있다.


▪ Wi-Fi 통신

 와이파이 통신은 알다시피 IEEE 802.11을 기반으로 서로 다른 장치들 간의 데이터 전송 규약이다. 즉 네트워크 개념을 토대로 이더넷 방식의 랜 연결을 통해 데이터를 주고받는 통신이다. 음향분야에서는 이 데이터가 오디오와 비디오를 전송하는 기술을 표준으로 만들어진 DLNA (Digital Living Network Alliance) 방식을 기반으로 한다. DLNA란 쉽게 말해 와이파이 공유기를 중심으로 각 기기들을 호환하여 연결시키는 가정용 네트워크를 의미하며 전자 기기들 간에 AP(Wireless Access Point)를 경유해 오디오와 비디오를 재생할 수 있게 해준다. 이와 같은 기술은 TCP/IP 기반의 네트워크상에서 UPnP(Universal Plug and Play)라는 자동으로 무선 장비를 인식하고 추가해주는 프로토콜을 통해 기기간의 접속이 이루어져 데이트를 주고받게 된다.


Fig 6. DLNA/UPnP Media Server


 위와 같은 특징 덕분에 DLNA 방식은 데이터 재생에 있어서 대역폭의 제한이 거의 없다. 앞에서 설명한 블루투스 통신의 경우 정해진 대역폭 내에서 오디오 신호를 전송해야 했기 때문에 SBC나 apt-X 코덱 같이 압축 알고리즘이 중요했던 반면 와이파이 통신은 오디오의 변형 없이 원본 그대로 전송이 가능하다. 즉 인코딩이나 디코딩이 필요 없이 원본 파일 그대로 무선으로 보낼 수 있다는 점에서 음질 부분이 비교할 수 없을 정도로 뛰어나다는 장점을 가진다.


 

Bluetooth

Wi-Fi 

주파수 

2.4GHz

2.4 / 5GHz 

요구조건 

1:1 Paring

같은 네트워크 상에서

연결된 Device 

전송음질

16bit 44.1KHz 

24bit 192KHz 

통신범위 

~10m 

~100m 

대역폭 

512Kbps 

수십 Mbps 

소비전력 

매우 낮음 

중간 

Fig 7. 블루투스-와이파이 통신 비교


 정확한 수치를 통해 블루투스 통신과 와이파이 통신을 비교해보면 차이점을 확연히 알 수 있다. 블루투스 통신의 경우 아무리 좋은 코덱과 압축 알고리즘을 사용한다고 해도 기본적으로 16bit 44.1KHz의 CD 수준의 음질에서 벗어날 수 없으며 대역폭 또한 A2DP 방식에서 전송폭의 상한선이 512Kbps로 제한된다. 반면에 와이파이 통신의 경우 전송 대역폭이 수십 Mbps 수준으로 매우 넓고 이로 인해 음질 또한 24bit 192KHz의 고음질 및 고용량 음원 전송이 가능하다.

 물론 음질이나 대역폭 같은 특성들을 가지고 어떤 통신이 좋은지 판단할 수는 없다. 중요한 것은 제한된 기술이든 기능이 좋은 기술이든 그 쓰임새에 맞게 쓰여야 된다는 것이다. 하이파이를 대체할 오디오 시스템을 찾는다면 블루투스 스피커는 반드시 피해야할 제품일 것이다. 반면에 스마트폰과 연계되는 간편하게 들고 다닐 수 있는 스피커를 찾는다면 무선 랜 연결이 필수적인 와이파이 스피커는 쓸모가 없다. 이러한 점들을 볼 때 단순히 기술적인 부분뿐만 아니라 사용 편의성과 사용 용도 같은 요소들을 먼저 파악하는 것이 선행되어야 할 것이며 용도와 목적에 맞게 쓰는 것이 효과적으로 자기에게 맞는 기술을 사용하는 법이다.


4. 오디오 시장의 향후 전망

 서두에서도 언급했지만 오디오 시장이 급격히 축소된 이유에는 몇 가지 이유가 있다. 먼저 스마트폰의 등장으로 사람들이 보다 편리하게 음악을 듣고 싶어 하는 추세로 바뀌었고 값비싼 오디오 시스템을 구입하기 보다는 스마트폰에 연결하여 간편하게 들을 수 있는 오디오 장비를 구입하게 되었다. 또한 현대에 들어오면서 1인 가구, 핵가족화 되면서 가족 구성원 수가 줄어들어 인원이 적다보니 자연스럽게 주거공간이 작아지게 되었고 이 때문에 덩치 큰 오디오 시스템을 필요로 하는 이가 줄어들었다.

 오디오 기기 관련 매출을 살펴보면 스마트폰과 더불어 헤드폰·이어폰의 판매량이 큰 폭으로 늘었고 소형 오디오 기기들과 사운드바의 판매량이 크게 늘었다. 입문용 소형 오디오 시스템과 무선통신 기술이 접목된 오디오 기기들의 판매는 늘었지만, 유선으로 동작하며 설치가 복잡하고 덩치 큰 제품의 수요는 상대적으로 감소한 것이다.


Fig 8. 스피커 시장 규모 및 향후 전망


 이러한 점들을 종합해볼 때 앞으로 오디오 시장은 ‘무선 오디오 시스템’시대가 본격적으로 도래 할 것으로 전망된다. 과거에는 스피커 자체 기술이 중요했기 때문에 오디오 전문 업체가 시장을 주도했지만, 디지털음원의 등장과 IT기술을 활용한 사용 편의성 및 디자인 등에 강점을 지니고 있는 IT기업으로 주도권이 넘어가고 있는 것이다. 무선통신기술 또한 과거에 비해 발전을 거듭해 오면서 더 이상 유무선의 차이를 느끼지 못할 정도 음질 부분에서 많은 성과를 거두고 있다. 음향 오디오 시장에서 무선통신분야가 얼마나 빠른 속도로 성장할 수 있을 것인지 그 가능성에 대해 앞으로 주목해 볼 필요가 있을 것이다.

자 이제 본격적으로 스마트홈 구축을 위한 프로그래밍을 진행해보자. 앞에서 언급했던 것 처럼 파이썬은 지그비 통신을 활용하여 온습도 데이터를 수신받아 데이터베이스화 할 것이며 PHP로 구축된 웹페이지에서 이 DB를 활용하여 차트로 도식화 한다. 이러한 프로그램 각각의 역할과 코드의 기능에 대해 정확히 알고 있어야 본 예제를 입맛에 맞게 수정하거나 응용할 수 있으므로 모쪼록 잘 이해하고 넘어가주길 바란다.



1. MySQL


MySQL을 다루려면 기본 SQL(Structured Query Language) 명령어를 어느정도 숙지하고 있어야 한다. 여기서 SQL은 데이터베이스의 자료를 검색하고 추가및 삭제 등의 조작을 할 수 있도록 고안된 컴퓨터 언어이다. 사람이 사용하는 언어와 문법 자체가 비슷하기 때문에 이해하기 쉽고 사후 관리도 편리하다. 또한 Query 라는 이름에서도 알 수 있듯이 검색 부문에 특화되어있는 데이터베이스이다.


구조 자체가 어렵진 않으니 여기서는 간단히 사용되는 명령어만 서술할 것이며 자세한 내용은 인터넷 상에 자료가 많으므로 검색해 볼 것을 추천한다.


  # MySQL 접속

mysql -u user -p password


위에서 user 부분은 사용자명을 뜻하며 따로 설정을 하지 않았다면 기본값인 root를 적어주며 password 부분은 MySQL을 설치할 때 생성한 비밀번호를 적어준다.


# 데이터베이스 생성

  CREATE DATABASE db_name;


# 데이터베이스 목록 표시

SHOW DATABASES;


# 데이터베이스 사용

USE db_name;


# 테이블 생성

  CREATE TABLE table_name(ddate datetime, zone text, temp float, humi float);


# 테이블 목록 표시

SHOW TABLES;


# 테이블 구조 표시

DESCRIBE table_name;


위 명령어 들을 사용해보면 데이터베이스를 만들거나 관리하는 것이 그렇게 어려운 부분이 아니라는 것을 알게 될 것이다. 자세한 설명은 생략하며 아래처럼 테이블까지 만들어서 파이썬을 통해 데이터베이스에 현재 시간과 장소, 온습도 데이터를 넣을 준비를 하자. 필자는 db의 이름을 testdb, 테이블의 이름을 tempdata로 지정했으며 다른 이름을 사용해도 무방하다.




2. Python


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import serial
import MySQLdb
import datetime
 
# Xbee 모듈과 시리얼 통신
port = serial.Serial("/dev/ttyAMA0""9600")
 
# MySQL 접속
db = MySQLdb.connect("localhost""User_name""User_password""testdb")
curs = db.cursor()
 
ZONE = "HOUSE"
print 'Start Monitor'
 
while True:
        try:
            # 지그비 통신을 통한 데이터 수신
            data = port.readline()
 
            print("House temp/humi is ")
            print(data)  
 
            # 수신한 데이터와 현재 시간 및 장소를 SQL 쿼리문으로 전송
            curs.execute("""INSERT INTO tempdata (ddate, zone, temp, humi) VALUES (%s,%s,%s,%s)""",
                (datetime.datetime.now().strftime('%Y-%m-%d %H:%M'), ZONE, data.split(',')[0], data.split(',')[1].strip()))
            db.commit()
 
        except KeyboardInterrupt:
                break
 
port.close()
db.close()

cs


파이썬 코드의 경우 먼저 지그비 통신을 하기 위해 Xbee 모듈과 시리얼로 연결된다. 그리고 MySQL에 접속하여 수신 받은 데이터를 SQL 쿼리문 형태로 전송하여 앞서 생성한 DB에 데이터를 입력하게된다. 제대로 동작한다면 다음과 같이 1분마다 DB에 데이터가 입력되는 것을 볼 수 있다.




3. Highcharts


다음은 저장된 DB를 가지고 그래프로 출력하는 법을 알아보겠다. 사실 DB와 연동하여 PHP 만으로도 꽤나 괜찮은 그래프를 만들어볼 수 있긴 하지만 여기서는 그보다 간단하면서 깔끔하게 나타낼 수 있는 오픈소스를 사용해보자. 차트를 만들어 볼 수 있는 오픈소스로는 Google chart나 Nwagon, chart.js 등의 다양한 종류가 있으며 여기서는 개인 홈페이지에서는 무료로 사용할 수 있으며 모바일 부분도 잘 지원해주는 highchart 소스를 활용할 것이다. 


주소는 다음과 같으며 해당 소스를 다운로드한 후 라즈베리파이의 웹서버 경로인 /var/www/html 에 압축을 풀어주면 된다.



http://www.highcharts.com/



4. PHP + HTML


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
 
// PHP 에러 코드 확인
ini_set('display_errors''On');
error_reporting(E_ALL|E_STRICT);
 
// MySQL 접속
$mysql_host = 'localhost';
$mysql_user = 'User_name';
$mysql_password = 'User_password';
$mysql_db = 'testdb';
$conn = @mysql_connect($mysql_host$mysql_user$mysql_password);
$dbconn = mysql_select_db($mysql_db$conn);
 
// DB에서 원하는 데이터 검색
$sql="
select * from (
SELECT DATE_FORMAT( ddate,  '%m-%d %HH' )  mdh , COUNT( * ) cnt, SUM( temp ) , 
round(SUM( temp ) / COUNT( * ),1)  atemper, round(SUM( humi ) / COUNT( * ),1)  ahumier
FROM  `tempdata`
GROUP BY DATE_FORMAT( ddate,  '%Y%m%d%H' )
order by ddate desc
limit 12
) t_a
order by t_a.mdh
";
 
$result = mysql_query($sql) ;
 
$str_mdh="";
$str_atemper="";
$str_ahumier="";
 
// 온습도 문자열 연결
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
 $str_mdh .="'".$row['mdh']."',";
 $str_atemper .="".$row['atemper'].",";
 $str_ahumier .="".$row['ahumier'].",";
}
 
// 오른쪽 공백 제거
$str_mdhsubstr($str_mdh,0,-1);
$str_atempersubstr($str_atemper,0,-1);
$str_ahumiersubstr($str_ahumier,0,-1);
 
?>
cs


highchart 웹페이지에서 예제 소스를 보면 아래 HTML 코드의 xAxis-categories 부분에 시간이나 날짜가, series-data 부분에 y축을 나타내는 데이터가 각각 쉼표와 함께 들어간다는 사실을 알 수 있을 것이다. 따라서 차트를 따라 그리려면 데이터가 알맞게 들어갈 수 있도록  PHP 코드상에서 한 문자열로 만들어주어야 한다. 


위 코드는 이러한 방식을 구현한 코드로서 select 문을 통해 db에서 데이터를 순서대로 가져온 후 while 문을 통해 각각의 날짜와 시간을 변수 str_mdh에 저장한다. 또한 온도와 습도 데이터는 변수 str_atemper와 str_ahumier 에 쉼표와 함께 한 문자열로 연결하고 최종적으로 뒤의 공백을 제거함으로서 완성한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<!DOCTYPE HTML>
<html>
<head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>House Monitor</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
        <style type="text/css">${demo.css}</style>
        <script type="text/javascript">
 
$(function () {
    $('#temp').highcharts({
        chart: {
            type: 'line'
        },
        title: {
            text: 'Temperature'
        },
        subtitle: {
            text: 'http://creamp.tistory.com'
        },
        xAxis: {
            categories: [<?php echo $str_mdh?>]
        },
        yAxis: {
            title: {
                text: 'Temperature (°C)'
            }
        },
        plotOptions: {
            line: {
                dataLabels: {
                    enabled: true
                },
                enableMouseTracking: false
            }
        },
        series: [{
            name'HOUSE',
            data: [<?php echo $str_atemper?>]
        }]
      });
    $('#humi').highcharts({
        chart: {
            type: 'line'
   },
        title: {
            text: 'Humidity'
        },
        xAxis: {
            categories: [<?php echo $str_mdh?>]
        },
        yAxis: {
            title: {
                text: 'humidity (%)'
            }
        },
        plotOptions: {
            line: {
                dataLabels: {
                    enabled: true
                },
                enableMouseTracking: false
            }
        },
        series: [{
            name'HOUSE',
            data: [<?php echo $str_ahumier?>]
        }]
    });
});
        </script>
</head>
<body>
        <script src="https://code.highcharts.com/highcharts.js"></script>
        <script src="https://code.highcharts.com/modules/exporting.js"></script>
        <div id="temp" style="width: 900px; height: 440px; margin: 30px auto"></div>
        <div id="humi" style="width: 900px; height: 440px; margin: 30px auto"></div>
</body>
</html>
cs




5. 결과 화면


이제 모든 과정이 완료되었다. 라즈베리파이의 웹서버에 접속하여 위와 같은 화면이 제대로 나오는지 확인해보자.

 


본 포스팅에서는 라즈베리파이와 아두이노를 지그비 통신을 활용하여 무선으로 연결하고 이를 통해 온습도 센서 데이터를 전송받아 파이의 웹서버에 차트로 뿌려주는 프로젝트에 대한 내용을 서술하려고 한다. 또한 여기에 추가적으로 웹서버 접속을 통해 집밖에서도 전등을 제어할 수 있도록 할 것이다.(여기서는 실제 전등 대신 LED로 대체) 말은 거창하지만 실상 그다지 어려운 부분은 없으며 최대한 상세하게 설명하고자 하니 파이를 활용한 스마트홈 구축이나 기타 IOT와 관련된 프로젝트를 진행하고자 하는 사람들에게 도움이 되길 바란다.

 

우선 지그비 통신에 대한 기본 개념과 설정 방법의 경우에는 아두이노 카테고리에 자세히 포스팅 해놓았기 때문에 꼭 참고하기 바라며 지그비 모듈에 대한 모든 설정이 마쳐진 상태에서 시작하도록 하자. 필요 준비물은 라즈베리파이와 아두이노, 설정이 완료된 지그비 모듈 2개, 마지막으로 온습도센서(여기서는 DHT11 사용)가 필요하다.

 

 

1. 동작흐름도


시작하기에 앞서 어떤 방식으로 어떻게 구현할 것인지 소개하기 위해 간단하게 흐름도를 만들어보았다. 먼저 센서부의 경우에는 아두이노와 온습도 센서로 구성되며 센서 데이터를 측정하고 라즈베리파이에 지그비 모듈을 통해 전송하게 될 것이다. 그리고 라즈베리파이에서는 파이썬 프로그램을 통해 전송받은 센서 데이터를 MySql DB로 저장하게 되며 마지막으로 php 기반의 자체 웹서버와 저장된 DB를 연결하여 아두이노로 부터 받은 센서 데이터를 차트로 도식화하여 보여주게 된다.

 

 

2. 아두이노 설정 



아두이노 회로 구성에 경우 위와 같이 온습도 센서(DHT11)와 지그비 모듈을 결선하도록 하며 코드는 다음과 같다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <DHT11.h>
#include <SoftwareSerial.h>
SoftwareSerial xbee(23); 
int pin=4;
DHT11 dht11(pin); 
 
void setup()
{
  xbee.begin(9600); 
}
 
void loop()
{
  int err;
  float temp, humi;
  if((err=dht11.read(humi, temp))==0)
  {
    xbee.print(temp);
    xbee.print(",");
    xbee.print(humi);
    xbee.println();
    delay(60000);
  }
}
cs


 

3. 라즈베리파이 설정


필자도 이 부분에서 많이 애를 먹었다. 아두이노에서는 간단하게 코드 몇 줄이면 지그비 모듈을 사용할 수 있는 반면에 라즈베리파이의 경우 UART 통신을 하려면 따로 설정이 필요하기 때문이다. 또한 파이1에서는 2로 넘어오면서 설정 방법이 바뀌는 바람에 시간을 많이 날려버렸다. 여기서는 파이2에 대한 방법을 서술하도록 하겠다.

 

먼저 초기 설정값을 default로 만들기 위해 ttyAMA0에 대한 모든 설정을 삭제하도록 한다. 여기서 ttyAMA0는 우리가 지그비 통신을 위해 사용하게될 시리얼 포트 이름이다.


  $ sudo nano /boot/cmdline.txt


모두 삭제가 완료되면 다음과 같은 코드만 남아있어야 한다. 물론 기존의 것이 아래와 같다면 수정할 필요는 없다.


  dwc_otg.lpm_enable=0 rpitestmode=1 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait


또한 라즈베리파이 아크 리눅스 환경에서는 ttyAMA0 포트가 이미 설정된 상태로 시스템 콘솔에서 동작하고 있다. 따라서 포트를 사용하기 위해서는 기존의 동작하고 있는 상태를 disable 시켜주어야 하므로 터미널에 다음과 같은 명령어를 쳐서 포트를 정지시키도록 한다.


  $ sudo systemctl mask serial-getty@ttyAMA0.service


마지막으로 라즈베리파이의 회로 구성은 다음과 같이 진행하여 설정을 모두 마치도록 하자.




4.  웹서버 환경 구축


라즈베리파이를 외부에서도 접속하고 관리할 수 있도록 웹서버를 구축해보도록 하자. 여기서는 웹서버의 표준 구성이라고 할 수있는 APM(Apache + PHP + MySQL)을 설치하려고한다. APM은 라즈베리파이를 강력한 웹서버로 활용할 수 있게 해줄 뿐만아니라 웹사이트를 보다 쉽게 운영하고 관리할 수 있도록 도와줄 것이다. 따라서 파트별로 간단하게 어떤 역할을 하는지와 설치 방법을 알아보도록 하며 언어 문법이나 보다 자세한 내용은 따로 검색해 볼 것을 추천한다.


1) Apache

아파치는 우리가 구축할 웹서버을 동작시키는데 있어서 가장 중요한 역할을 하는 웹 서버 어플리케이션이다. 리눅스 기반으로 만들어져 있으며 확장성이 좋아 여러 모듈을 통해 수많은 기능을 덧붙일 수 있다.(PHP, MySQL 등) 또한 매우 단순하면서 강력한 무료 웹서버를 무료로 제공하기 때문에 서버 애플리케이션 중에서 가장 인지도가 높다.


$ sudo apt-get update

$ sudo apt-get install apache2


위 명령어를 통해 설치가 완료되면 자동으로 설정되는 기본위치인 /var/www경로를 사용할 수 있도록 권한 설정을 하자.


$ sudo chown pi -R /var/www

$ sudo chmod 0777 /var/www


마지막으로 라즈베리파이가 부팅시에 프로그램이 가동될 수 있도록 설정해준다.


  $ sudo update-rc.d apache2 defaults


2) MySQL

데이터베이스(DB)란 데이터를 쉽게 저장하고 검색할 수 있는 시스템을 말하며 이 데이터를 삽입하고 검색할 수 있는 언어가 바로 SQL이다. 따라서 MySQL은 데이터를 보다 쉽게 관리하게 해주며 데이터 저장에 특화되어 있는 오픈소스 애플리케이션이다.


  $ sudo apt-get install mysql-server mysql-client libmysqlclient-dev


설치가 완료되면 MySQL 접속에 필요한 비밀번호를 2번 입력하도록 한다. 또한 외부에서 데이터베이스에 접속할 수 있게 바인드 어드레스를 비활성화 한다. 여기서 바인드 어드레스란 해당 주소에서만 접속을 허용하며 그 외는 접속을 차단해주는 주소를 의미한다.


  $ sudo nano /etc/mysql/my.cnf



위처럼 bind-adreess 앞에 #을 붙여주면 주석처리되어 비활성된다.


3) PHP

PHP는 웹페이지에 동적 기능을 불어넣어 주는 서버단에서 동작하는 프로그래밍 언어이다. 사실 HTML 만으로는 사용자의 입력에 유연하게 반응하지 못하기 때문에 PHP는 이러한 정적 HTML에 동적으로 동작할 수 있도록 개발되었다. 때문에 HTML의 처리에 강점을 가지며 다양한 데이터베이스를 지원하기 때문에 데이터베이스와 사용자간의 중간 다리 역할도 훌륭히 수행한다.


  $ sudo apt-get install php5


설치 후 PHP를 효과적으로 관리할 수 있도록 도와주는 PHP MyAdmin도 설치하도록 하자. 이때 웹서버 인증은 apache2를 선택하고 웹에서 사용할 비밀번호를 3번 정도 입력하면 설치가 완료된다.


  $ sudo apt-get install phpmyadmin



4) Python 

마지막으로 파이썬의 경우 지그비 통신을 통해 온습도 데이터를 수신받는 역할을 할 것이며 이 데이터를 MySQL의 데이터베이스로 만들어 줄 것이다. 따라서 파이썬에서 MySQL로 접속할 수 있도록 연동해주어야하며 아래와 같은 라이브러리 설치가 필요하다.


  $ sudo apt-get install libmysqlclient-dev

$ sudo apt-get install python-dev

$ sudo pip install MySQL-python


설치가 모두 마무리되면 제대로 동작하는지 확인을 위해 파이썬 쉘을 실행시키고 import MySQLdb 를 입력해보자. 에러없이 그대로 임포트 된다면 성공적으로 설치가 완료 되었으므로 파이썬에서 DB를 생성할 수 있다. 반면에 에러 발생시에는 실수한 것은 없는지 순서대로 확인해보도록 한다.


이제 필요한 모든 설정을 마쳤다. 다음 포스팅에서는 위 프로그래밍 언어들을 사용하여 온습도 데이터를 기반으로 하는 스마트홈 구축과 관련된 내용을 서술하도록 하겠다.


이번에는 본격적으로 지그비 통신을 활용하여 무선통신을 실습해보도록 하겠다. 아직 지그비 통신에 대한 정확한 개념을 잡지 못했다면 전에 포스팅한 글을 꼭 참고하기 바란다. 실습에서는 지그비 설정 툴인 X-CTU에 대한 사용법을 숙달하고 컴퓨터 상에서 간단하게 통신을 테스트해본 뒤에 아두이노 2개를 가지고 서로 데이터를 주고받아보는 순으로 진행할 것이다. 또한 지그비 검색 결과 XBee S1 모듈에 대한 예제들은 많이 있었지만 S2 모듈 설정에 대한 글은 찾기가 매우 힘들었다. 따라서 여기서는 미약하나마 도움이 될 수 있도록 S2 모듈을 가지고 진행하려고 한다.



1. 지그비 통신 준비


- XCTU 프로그램

XCTU 프로그램은 XBee 모듈을 다루고 설정하기 위해 필수로 필요한 소프트웨어이다. XBee 모듈에 대한 ID, CH 등을 설정하고 테스트할 수 있는 환경을 제공해주며 최근 1~2년 사이에 새로 업데이트 되면서 UI 부분이 많이 바뀌었다. 전 버전과 동일한 기능을 수행할 수 있으므로 이번 실습에서는 최신 버전의 프로그램을 사용하도록 한다.

다운로드 : http://www.digi.com/products/xbee-rf-solutions/xctu-software/xctu 


- XBee S2 모듈

안테나 유무나 PRO 등에 관계없이 S2 모듈이기만 하면 상관없다.


- 아두이노


- XBee Breakout 보드

XBee 모듈은 소형으로 제작되어 핀 배열이 좁기 때문에 활용하기 힘들다. 따라서 아두이노로 간단하게 사용할 수 있도록 위와 같은 보드가 필요하다.


- XBee FTDI 보드(인터페이스 보드)

모듈을 설정하기위해 필요한 인터페이스보드. 소켓 헤더와 led, USB 2 Serial 보드를 내장하고 있으며 제조사마다 다양한 제품이 있으므로 어떤 것을 사용해도 무방하다. 만약 아두이노 XBee 쉴드가 있다면 굳이 필요는 없지만 정신건강을 위해 하나 사는 것을 추천한다. 간단한 테스트환경을 제공해주며 안정된 통신을 보장한다.



2. XCTU 프로그램 설정


아래 화면은 XCTU 프로그램의 메인화면으로 왼쪽 상단의 Add devices 버튼을 클릭하면 XBee 모듈을 추가할 수 있다.



버튼을 클릭하면 현재 컴퓨터에 연결된 디바이스 정보가 표시된다. 해당하는 포트 선택후 아래 옵션은 그대로 놔둔채 Finish 버튼을 클릭한다.



성공적으로 XBee 모듈을 불러왔다면 불러온 모듈을 한번 클릭해주자. 그러면 해당하는 모듈의 다양한 정보가 표시될 것이며 설정된 값을 수정할 수 있다.



먼저 설정페이지 상단을 살펴보자. 여러개의 버튼 밑에 모듈 정보가 표시되는게 보일 것이다. 이는 각각 연결된 XBee 모듈의 명칭과 네트워크 역할, 펌웨어 버전을 의미하며 여기서 가장 중요한 것이 바로 네트워크 역할을 의미하는 Function set 이다. 앞서 지그비 개념 관련 포스팅에서 언급했던 네트워크 토폴로지의 개념이 여기서 적용되는 것으로 사용자는 이 부분을 변경함으로서 Star, Mesh 등 자신의 네트워크 환경에 적합한 토폴로지를 구축할 수 있다. Zigbee 통신에서 설정할 수 있는 Function set은 대표적으로 3가지가 있으며 서로 다른 역할을 하게 된다.


 Coordinator

  네트워크의 구성 및 보안을 담당하며 라우팅 구축을 지원해준다.

 Router

  거리가 멀어 직접 통신할 수 없는 노드 사이에서 데이터를 전달해주는 역할을 한다. 

 End Device

  데이터를 수집하거나 간단한 제어를 담당하며 수집된 정보를 전송해준다.



변경 방법은 상단 버튼 중 Update 버튼을 클릭하여 진행할 수 있으며 여기서 AT 모드, API 모드 설정과 함께 해당하는 최신 펌웨어 업데이트를 동시에 할 수 있다.


모듈의 기본적인 설정이 완료되었다면 이제 설정 페이지 밑의 다양한 항목들을 확인해보자. XCTU 프로그램은 지그비 통신의 주소, 접속, 제어 등을 처리하기 위한 여러가지 구성 설정을 제공해준다. 이를 통해 사용자는 모뎀 구성, 통신 테스트, 루프백 등으로 활용할 수 있다. 자세한 설정 방법이나 명령어들은 XBee 매뉴얼을 참고하기를 바라며 여기서는 중요한 설정값 몇개만 살펴보도록 하겠다.


CH

  지그비 통신의 2.4GHz의 대역내에서 동작 주파수 채널을 설정할 수 있는 항목이다. XBee 모듈

  서는 통신할 모듈끼리 채널이 같아야하기 때문에 중요한 지표이지만 S2 모듈의 경우에는 같지않 

  아도 통신이 가능하 설정값 또한 변경할 수 없다.

ID

  실질적인 네트워크 ID를 설정할 수 있는 항목을 지칭하며 이부분을 다르게 설정함으로서 각각의

  네트워크를 구별하는데 활용할 수 있다. 

DH, DL

  데이터가 전송되는 목적지 주소를 나타내며 데이터 전송 노드를 정의하기 위해 사용된다.

SH, SL

  XBee 모듈 고유의 시리얼 넘버를 말하며 수정할 수 없다. DH, DL과 같이 쓰인다.

MY

  노드 자체의 주소(나의 주소)를 설정하는 항목이다.



3. 테스트 환경 구축


그럼 이제 XBee 모듈 2개를 서로 다르게 설정하여 지그비 통신할 수 있도록 해보자. 모듈이 2개이므로 간단한 Peer to Peer 토폴로지로 네트워크를 구축할 것이며 하나는 기본 노드인 Coordinator AT로 설정하고 다른 하나는 Router AT로 구성하도록 한다. 앞서 언급했던 것 처럼 Update 버튼을 통해 설정할 수 있으며 펌웨어는 최신버전으로 업데이트 하도록 한다. 또한 2개의 모듈이 서로 통신할 수 있도록 다음과 같이 설정값을 변경하고 Write 해야 한다.


 

 Coodinator

Router 

 ID

 1234

1234

 DH

Router의 SL 값

Coordinator의 SH 값

 DL

Router의 SH 값

Coordinator의 SL 값


위와 같이 Coordinator와 Router의 DH, DL을 맞춰주면 2개의 노드가 오직 서로만 통신하게 된다. 이렇게 되면 설정은 모두 완료되었다. 만약 XBee 인터페이스 보드 혹은 아두이노 쉴드가 2개 있다면 설정된 모듈을 모두 연결하여 간단하게 통신이 정상적으로 되는지 테스트 해보자. 프로그램 상단 오른쪽에 터미널 모양의 버튼을 클릭하고 두 개의 모듈을 모두 Open 한다. 



그리고 콘솔에 글자를 입력하게 되면 정상적으로 데이터 송신과 수신이 되고 있음을 알 수 있다. 만약 테스트가 성공적이라면 이제 설정은 모두 완료되었다. 이제 우리는 Peer to Peer 토폴로지를 활용하는 모든 프로젝트에서 본 XBee 모듈을 활용할 수 있다.



4. 지그비 통신 실습


그러면 이제 배운 것들을 토대로 아두이노간의 지그비 무선 통신 실습을 진행해보도록 하자. 사실 실습이라 하기에는 그저 간단한 테스트에 불과하지만 성공한다면 이를 응용하여 할 수 있는 것들이 매우 다양해질 것이다. 회로는 아두이노 2개를 각각 다음과 같이 구성하도록 하며 지그비 모듈은 전원이 3.3V에서 동작하도록 설계되어 있으므로 5V 전원 인가시 고장날 수 있기 때문에 이 점에 유의해서 연결하도록 한다.


코드는 심플하다. 송신부에서는 1초마다 A 문자를 전송하며 수신부에서는 문자를 받을때 마다 조건 판별후 테스트 성공 문자를 시리얼 모니터에 출력하는 방식이다. 



1
2
3
4
5
6
7
8
9
10
11
12
// Node1_지그비 송신 코드
 
#include <SoftwareSerial.h>
SoftwareSerial xbee(23); 
 
void setup() {
xbee.begin(9600); 
}
void loop() {
xbee.print('A');
delay(1000);
}
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Node2_지그비 수신 코드
 
#include <SoftwareSerial.h>
SoftwareSerial xbee(23); 
 
void setup() {
Serial.begin(9600);
xbee.begin(9600); 
}
void loop() {
if(xbee.available()){
  char data = xbee.read();
  if(data == 'A'
    Serial.print("Zigbee test OK!"); 
  }
}
cs


이로서 지그비 통신에 대한 개념 포스팅을 모두 마친다. 내용이 부실하고 미흡하지만 그래도 필요로하는 사람들에게 도움이 되길 바라는 바이다. 다음에는 라즈베리파이와 아두이노를 지그비로 연결한 스마트홈 구축을 주제로 포스팅해볼 예정이며 후에 시간이 가능하다면 지그비 통신의 API 모드 설정법과 활용 방안에 대해서도 글을 올려보고 싶다.



'Electronic > Arduino' 카테고리의 다른 글

XBee 모듈 정보 및 종류  (0) 2016.01.17
지그비 통신의 개념 (네트워크의 이해)  (8) 2016.01.16
[Galileo] 초음파센서 사용하기  (0) 2016.01.08

1. XBee 모듈 종류

XBee 모듈은 크게 Series1과 Series2 두 종류로 나눌 수 있다. 두 시리즈 제품은 기본적으로 동일한 특징들을 많이 가지고 있지만 몇 가지에서 서로 다른 차이점을 보이는데 먼저 S1 같은 경우에는 별도의 설정이 필요하지 않기 때문에 즉시에 사용할 수 있다는 편리성이 있으며 IEEE 802.15.4 프로토콜을 사용한다. 이 프로토콜은 무선 개인 영역 네트워크로 노드 사이의 데이터 처리를 1초당 250Kbps까지 제공하는 특징이 있다. 또한 네트워크 토폴로지의 경우에는 P2P 또는 스타 네트워크 사용이 가능하다. 반면에 S2의 경우에는 802.15.4 프로토콜에 네트워크 계층과 응용 계층을 더 추가한 지그비 프로토콜을 지원한다. 이로 인해 초기에 사용하기 위해서는 별도의 설정이 필요하며 더 적은 전력으로 사용할 수 있고 추가적인 기능과 네트워크 사용이 가능하다.

 

Series 1

Series 2

통신규약

IEEE 802.15.4

Zigbee

토폴로지






 


     

실내 통신거리

30m

40m

실외 통신거리

100m

120m

공급전압

2.8~3.4V

2.8~3.6V

공급전류

45mA

40mA


XBee 모듈은 일반 모듈과 프로 모듈로도 구분할 수 있다. 두 모듈의 차이는 크기와 무선전력의 차이가 있으며 작동과 기능은 거의 동일하다고 볼 수 있다. 프로 모듈의 경우 일반 모듈보다 크기가 크고 소비전력을 많이 소비하며 그만큼 더 먼 거리까지의 통신을 지원한다.

마지막으로 XBee 모듈은 안테나를 통해서도 구분할 수 있는데 사실 안테나 종류에 따른 다양한 모델들이 있긴 하지지만 성능을 따져봤을 때 큰 의미는 없다. 즉 어떤 제품이든지 간에 잘 동작한다는 소리이다. 물론 안테나 유무에 따라서 신호의 세기를 감지하는 패턴이 달라지기 때문에 사용 용도에 따라 구분할 수 있겠지만 이 또한 그다지 큰 성능 향상을 기대하기 힘들다. 따라서 이 부분은 개인의 취향대로 구매하면 될 듯하다.


 Wire Antenna

Chip Antenna

u.FL Antenna 

Trace Antenna 


2. XBee 통신 모드

XBee모듈은 AT모드와 API모드를 모두 지원한다. 먼저 AT모드의 경우 전달 모드(Transpatent)라고도 불리며 간단하게 메시지 데이터를 보내고 받을 수 있다. 쉽게 말해 RX와 TX를 통해 데이터를 주고받는 직렬 데이터의 단순한 전송과 수신이 가능해진다. 따라서 별도의 프로그래밍이나 패키지화가 필요하지 않으며 간단하게 무선 통신을 진행할 수 있다는 장점이 있다. 반면에 API모드의 경우에는 AT모드에서 주고받는 직렬 데이터뿐만 아니라 도착 주소, 패킷 형태, 신호 강도 등의 정보를 같이 패키지화하여 전송한다. 이는 사용자가 필요로 하는 다양한 정보를 설정을 통해 데이터와 함께 보낼 수 있는 개념으로 각 노드간에 유연성있고 다이나믹한 통신망을 구축할 수 있게 해주며 상황에 따라 신뢰성 또한 크게 향상시킬 수 있게 해준다.

두 노드간 서로 통신을 설정할 때는 양측이 모두 같은 모드일 필요는 없으며 API모드에서 AT 모드로 데이터 전송이 가능하고 그 반대도 가능하다. 모드는 XBee 모듈 사이에서 결정하는 것이 아니라 메인 컨트롤러와 XBee 모뎀 사이의 연결을 정의하는 것이기 때문이다.


3. XBee 핀 배치



1) DOUT/DIN

직렬데이터 송수신 핀. 이 데이터는 XBee의 환경 설정을 설정하고 읽을 수 있으며 기본 데이터 속도는 비동기 직렬 통신을 사용하여 9600baud이다.

2) CTS/RTS/DTR

일반적으로 XBee 모듈에 펌웨어 업데이트를 다운로드할 때 사용되며 오직 Serial 통신을 활용한 XBee 어댑터 보드를 사용할 때만 동작한다.

3) DIO

표준 3.3V 디지털 입력 및 출력으로 사용되며 핀의 상태의 설정을 조절할 수 있다.

4) AD

10비트의 아날로그를 디지털로 변환하여 XBee에 입력하는 역할을 하며 값을 읽을 수는 없지만  전압의 양(PWM)으로 나타낼 수 있다.

5) RSSI

PWM 출력으로 수신된 신호의 강도를 확인할 수 있다.

6) PWM

아날로그 출력에 사용할 수 있는 10비트 펄스 폭 변조 출력을 위해 설정 할 수 있다.

7) ASSOC

XBee가 기존의 네트워크에 가입할 수 있도록 설정하고 할당할 수 있는 매개 변수 이다.


'Electronic > Arduino' 카테고리의 다른 글

지그비 무선 통신하기  (13) 2016.01.26
지그비 통신의 개념 (네트워크의 이해)  (8) 2016.01.16
[Galileo] 초음파센서 사용하기  (0) 2016.01.08


최근에 무선통신 기술중 지그비 통신을 활용하게 되어 관련된 자료를 찾아보았는데 괜찮은 정보를 찾기가 매우 어려웠다. 제대로 검색하지 못한 필자의 탓일 수도 있지만 찾아본 대부분의 자료들은 대체 핵심은 어디 갖다 팔아먹었는지 그저 이러저러 해라 식의 단순 지식만 늘어놓고 있었으며 중복되는 내용 또한 심심찮게 발견할 수 있었다. 이러한 글을 읽고 제대로 이해될리 만무하다. 물론 구글을 활용해 해외 사이트에서 검색한다면 원하는 정보를 쉽게 찾을 수 있겠지만 국내에서 지그비와 관련된 간단한 설정법조차 찾기 힘들다는 사실은 매우 안타까울 뿐이다.


때문에 답답한 나머지 지그비 통신에 대해서 필자가 찾아보고 공부한 내용을 정리하여 공유하고자 한다. 순서는 네트워크와 지그비에 대한 개념부터 시작해서 지그비 모듈 종류 및 설정 방법, 아두이노를 활용한 무선 통신 실습 순으로 포스팅할 생각이며 부디 처음으로 지그비 통신을 공부하고 활용하고자 하는 사람들에게 도움이 되길 바란다.



1. 네트워크 이해


지그비에 대한 개념을 설명하기 앞서 네트워크에 대한 이야기를 잠시 해볼까 한다. 워낙 방대한 주제인 만큼 여기서는 간단하게 개념만 짚고 넘어가도록 하자. 네트워크란 Net + Work의 합성어로 컴퓨터들이 통신기술을 이용하여 그물망처럼 연결된 형태를 의미한다. 쉽게 말해 여러 대의 컴퓨터들이 서로 통신하는 것을 말하는 것으로 여기서 통신기술이란 프로토콜(Protocol)을 뜻하며 사전적으로 '규약', '약속'등을 의미한다. 컴퓨터 네트워크에서 서로 통신하기 위한 사전의 약속같은 것으로 해석할 수 있다. 예를 들어 식당에서 음식을 주문하는 상황을 가정해보자. 한 손님이 메뉴판에서 자신이 먹을 음식을 결정했고 바로 주문하려고한다. 하지만 웨이터는 다른 손님의 주문을 받고 있으며 다른 웨이터들 또한 보이지 않는다. 당신이라면 이 상황에서 어떻게 하겠는가? 아마도 당신이 조금의 기다림을 참지 못하는 몰상식한 사람이 아니라면 웨이터가 주문을 다 받을때 까지 기다린 후에야 자신의 주문 내용을 말할 것이다. 


그렇다. 방금 당신은 훌륭하게 사람들 간에 지켜야 할 프로토콜을 잘 지킨 셈이다. 만약 프로토콜을 지키지 않고 웨이터를 억지로 불렀다면 자신과 웨이터 뿐만 아니라 다른 손님과의 소통 또한 제대로 될리가 없다. 이렇듯 사람들이 말을 할 차례를 지켜 주는 것이 중요한데 이러한 개념은 네트워크 통신에서도 똑같이 적용된다. 네트워크 측면에서 위와 같이 통신의 순서를 정해주는 것을 미디어 접근(Media Access)라고 하며 동시에 여러 통신이 발생하는 상황을 다중 접근(Multi Access)라고 한다. 그리고 이러한 상황과 유사한 프로토콜이 바로 CSMA/CD 이다.


   · CSMA/CD (Carrier Sense Multi Access / Collision Detection)

   LAN(이더넷)에서 각 단말기 간 자료를 전송하고 있는 동안 회선을 감시하여 충돌이 감지되면 즉각 전송을 멈

   추고 재전송을 위해 기다렸다가 다시 시도하는 방식


위 방식은 여러 단말기가 통신을 시도했을 때의 충돌 상황을 완화시키는 역할을 한다. 쉽게 말해 앞서 언급한 웨이터의 일이 끝날때 까지 기다려 서로의 통신이 끊어지지 않도록 도와주는 것이다.


또한 네트워크 통신에서 단말기간 특정 주소를 가지는 개념은 매우 중요하다. 각 컴퓨터가 자신의 고유 주소인 IP를 할당받는 이유는 다른 컴퓨터와 구별되기 위해서임을 우리는 이미 알고있다. 따라서 각 단말기간 어떤 통신이 진행되기 위해서는 특정한 수신자의 주소가 지정되 있어야 데이터 보내기가 가능하다. 이러한 주소는 네트워크상에서 숫자로 할당받게 된다.



2. 네트워크 토폴로지(Network Topology)


네트워크 토폴로지란 단말기 상호 간에 데이터를 전송할 수 있도록 연결된 형태를 말한다. 이는 데이터가 잘 보내지고 받을 수 있도록 어떻게 네트워크를 구축할 것인가 라는 네트워크 전략과도 일맥상통하며 어떤 형태를 구축하느냐에 따라서 데이터의 흐름이 결정되게 된다. 따라서 다양한 형태와 방법이 존재하지만 여기서는 지그비 통신과 관련된 몇가지만 소개하고자 한다.


일대일 통신 (Peer to Peer)

일대일 네트워킹은 두 노드 (여기서 노드는 연결점을 의미하며 단말 장치나 통신 처리 장치 등을 뜻한다.) 사이에 데이터를 전송하기 위한 가장 간단한 형태이다. 다양한 채널을 사용할 수 있으며 서로 다른 주파수에 작동하는 무선조종자동자가 좋은 예이며 또한 개인과 개인이 직접 연결되어 파일을 공유하는 P2P도 이러한 개념의 연장선이라고 이해할 수 있다.



스타형 토폴로지 (Star Topology)

스타형은 이더넷 LAN에 가장 널리 사용되는 물리적 네트워크 구조로 중앙의 연결 지점에 허브나 라우터 같은 중심 노드(Coordinator)가 배치되어 모든 노드들을 관리하게 된다. 모든 데이터가 중앙 지점으로 모여지는 중앙 제어 방식이기 때문에 관리가 편하고 확장이 용이하지만 그만큼 부하가 많이 걸리게 되며 중앙 노드에 장애가 발생하면 전체 네트워크 사용이 불가능하게 되는 단점이 있다.


 메쉬형 토폴로지 (Mesh Topology)

메쉬형은 모든 노드가 네트워크상에서 혹은 개별적으로 현결된 그물망 형태로 다수의 노드 쌍이 동시에 통신할 수 있다. 이는 특정 노드의 장애가 다른 노드에 영향을 주지 않기 때문에 장애에 유연한 대처가 가능해지고 가용성이 극대화 되는 장점으로 작용한다. 하지만 그만큼 회선구축 비용이 많이 들게 되며, 새로운 노드를 추가할 시에 선로 구성이 복잡해지고 비용부담이 발생한다.

                        


토폴로지는 상황에 맞게 적절한 방식을 선택하는 것이므로 좋고 나쁨을 떠나 자신이 구축할 네트워크 환경에 적합한 것을 써야 한다.


3. ZigBee 통신


서론이 생각보다 길었다. 그럼 이제 본격적으로 지그비 통신이 무엇인지 알아보도록 하자. 지그비는 근거리 저전력 무선 통신을 위한 프로토콜을 일컫는다. 앞서 프로토콜의 개념을 제대로 이해하였다면 지그비 통신 또한 여러 개의 노드가 서로 통신하기 위해 만들어진 통신 규약이라는 것을 알 수 있을 것이다. 그럼 다른 무선 통신 방법과 비교하여 지그비의 특징을 살펴보자.


 

Zigbee

 Bluetooth

Wi-Fi 

NFC 

전송거리

 ~100m

~10m 

~100m 

~20cm

 전송속도

~250Kbps 

~24Mbps 

 11M / 54Mbps

106~848Kbps 

최대 채널 수

 32000

 14

 1

 소비전력

Very Low

Medium

High

Low

복잡성

Low

Low

High

Low

 비용

Low

Low

High

Low


위 표를 통해 지그비 통신은 복잡하지 않은 시스템 구조로 구성되어 있으며 적은 소비전력으로 인해 소형화가 가능함을 알 수 있다. 비록 전송 속도면에서 블루투스나 와이파이 통신이 우수하긴 하지만 가격이 비싸기 때문에 상대적으로 저렴하고 간단한 무선 네트워크를 구축할 수 있다. 또한 네트워크 규모도 방대하기 때문에 다수의 센서를 활용하거나 모듈을 사용하는 시스템에 적합한 형태를 보인다.


지그비 통신 모듈은 시중에서 다양한 형태로 판매되고 있으나 여기서는 가장 대중적인 제품인 Digi 사의 XBee모듈에 대해서 설명하겠다.  Xbee란 지그비 프로토콜을 바탕으로 보다 쉬운 설정과 사용을 위해 개발된 별개의 프로토콜이다. 따라서 지그비 통신을 기반으로 하고는 있지만 XBee 전용의 프로토콜을 따로 제공하고 있다는 점을 염두해 두어야 한다. 이러한 XBee 모듈의 설명은 다음 포스팅에서 이어서 설명하도록 하겠다.


'Electronic > Arduino' 카테고리의 다른 글

지그비 무선 통신하기  (13) 2016.01.26
XBee 모듈 정보 및 종류  (0) 2016.01.17
[Galileo] 초음파센서 사용하기  (0) 2016.01.08