2009년 5월 7일 목요일

Oscilloscope 어플리케이션 되짚어 보기.

Oscilloscope 어플리케이션 예제에서는 센싱 데이터가 2바이트씩 10개의 값을 보내도록 구현되어 있다. OscopeMsg 패킷의 형식을 보면 버퍼 사이즈 즉, 샘플링 데이터를 10개 수집하도록 되어 있기 때문이다. 하나씩 뜯어보도록 하자.

Tinyos에서 기본적으로 사용되는 TOS_Msg를 살펴보면
(/opt/tinyos-1.x/tos/platform/telos/AM.h)


#define TOSH_DATA_LENGTH 28
typedef struct TOS_Msg{
uint8_t length;
uint8_t fcfhi;
uint8_t fcflo;
uint8_t dsn;
uint16_t destpan;
uint16_t addr;
uint8_t type;
uint8_t group;
uint8_t data[TOSH_DATA_LENGTH];
uint16_t strength;
uint8_t lqi;
bool crc;
bool ack;
uint16_t time;
} TOS_Msg;

여기서 데이터가 저장되는 페이로드 부분은 int8_t data[TOSH_DATA_LENGTH]; 부분으로 총 28바이트의 크기를 가진다.
그리고 Oscilloscope에서 사용되는 OscopeMsg의 경우 TOS_Msg의 이 페이로드 부분, 즉 28바이트 크기를 가지는 data부분에 실려서 전송되며 별도의 헤더를 가진다.

enum {
BUFFER_SIZE = 10
};
struct OscopeMsg {
uint16_t sourceMoteID;
uint16_t lastSampleNumber;
uint16_t channel;
uint16_t data[BUFFER_SIZE];
} OscopeMsg;

총 28byte의 페이로드 중 6바이트를 OscopeMsg의 헤더로 사용하고 BUFFER_SIZE 크기 만큼인 20byte를 2바이트씩 10개의 데이터로 채운다. 즉, OscopeMsg 형태의 패킷을 사용하면 2바이트짜리 데이터가 패킷당 10개씩 들어오는 것이다.
왜 2바이트짜리를 사용하는가. 그것은 센서 노드에서 10~12bits의 ADC를 사용하기 때문이다. 즉, ADC를 거쳐 아날로그에서 디지털로 변환된 데이터의 크기는 10~12bits이고 이를 저장하기 위해서는 2바이트가 필요한 것이다. ADC에서 데이터를 변환하여 결과값이 나왔을때 호출되는 함수를 보면 async event result_t ADC.dataReady(uint16_t data); 와 같은 형식을 취하는데 인수로 넘어오는 uint16_t data가 ADC의 결과가 된다. 이 값을 보내기 위해서 당연히 2바이트 짜리 변수를 사용해서 보내는 것이다.

[TIP]
OscopeC 컴포넌트는 /opt/tinyos-1.x/tos/lib/Oscope에 위치해 있으며, 이 컴포넌트를 이용하여 (OscopeM.nc, Oscope.h와 함께) Oscilloscope에서 발생한 센서 데이터들을 센서 타입별로 OscopeMsg 형태로 만들어 RF로 전송하는 기능을 가진 컴포넌트이다.
/opt/tinyos-1.x/apps에 있는 Oscilloscope 어플리케이션은 오직 하나의 센서에 대해서만 처리하기 때문에 앞에서와 같은 기능 분리가 필요 없으나, /contrib/moteiv/apps에 있는 Oscilloscope 어플리케이션은 여러 개의 센서들에 대해서 샘플링하고, 이를 각각 OscopeMsg로 만들어서 전달하여야 하므로 위와 같은 기능을 분리한 것이다. 물론 사용자 어플리케이션에서 모든 것을 처리할 수도 있겠지만, 같은 것의 반복을 parameterized 인터페이스를 통해 좀 더 간결하고 쉽게 해결하기 위해 OscopeC 컴포넌트를 사용한다.

댓글 없음:

댓글 쓰기