조도센서제어 이번장에서는 ZigbeX 에장치되어있는센서들중에서조도센서에대해공부하고, TinyOS의 Oscilloscope 프로그램을통해측정된조도값을확인하는방법에대해알아보도록하겠다. 한백전자
ZigbeX 의조도센서 2
ZigbeX 의조도센서 조도센서 CDS ZigbeX에장치되어있는조도센서 CDS는 Atmega 128(ZigbeX의 8bit CPU) 의 INT0 과 ADC0 사이에연결되어있다. 조도센서인 CDS는주변의광량에따라자신의저항이변하게된다. 결국, 출력포트인 ADC0에서는변화된전압의양에의해광량을감지할수있다. 조도센서제어컴포넌트 TinyOS에서는조도센서를제어하기위해 Photo 컴포넌트라는것을제공하고있다. 3
Photo 컴포넌트 조도센서로활성화된 ADCC 컴포넌트에서제공하는함수들 photo 컴포넌트를사용하는상위프로그램에서는조도데이터를얻기위해 ADC.getData() 함수를호출한후, 그값은 event 형태로반환되는 ADC.dataReady(uint16_t data) 함수를통해받게된다. ADCC 컴포넌트에서제공하는함수들 ADC 의값얻기 ADC.getData() - 앞에서설정된 ADC 포트로부터측정된값을얻기위해호출된다. event ADC.dataReady(uint16_t data) - ADC 가측정한값을 event 형태로반환한다. 4
조도값얻기 조도값측정예제 // 상위컴포넌트 xxx_function() { call ADC.getData() // 상위컴포넌트 event ADC.dataReady(uint16_t data) { //data -> 측정된조도값 Photo 컴포넌트 5
Oscilloscope 예제를이용하여 조도값측정 6
Oscilloscope 예제 Oscilloscope 예제프로그램 Oscilloscope 예제는 125ms 마다조도센서로부터측정값을받은후, 그내용을시리얼케이블을통해 PC 로전달하는프로그램이다. Oscilloscope 예제프로그램의위치 c: Programfiles UCB cygwin opt tinyos 1.x contrib zigbe x Osilloscope 폴더에있는 Oscilloscope.nc 와 OscilloscopeM.nc, OscopeMsg.h 파일을참조. 7
Oscilloscope.nc Oscilloscope.nc Osilloscope 예제에서사용되는컴포넌트들 PC 와의시리얼통신을위한 UART Comm 컴포넌트 조도센서값을얻기위한 DemoSensorC 컴포넌트 주기적인알람과동작여부의체크를위한 TimerC와 LedsC 컴포넌트 configuration Oscilloscope { implementation { components Main, OscilloscopeM, TimerC, LedsC, DemoSensorC as Sensor, UARTComm as Comm; Main.StdControl > OscilloscopeM; Main.StdControl > TimerC; OscilloscopeM.Timer > TimerC.Timer[unique("Timer")]; OscilloscopeM.Leds > LedsC; OscilloscopeM.ADC > Sensor; 8
시리얼통신컴포넌트 UARTComm 컴포넌트 UARTComm 컴포넌트는 PC와의시리얼통신을위해만들어진컴포넌트이다. ReceiveMsg 인터페이스와 SendMsg 인터페이스를통해다음과같은함수를제공한다. UARTComm 컴포넌트에서제공하는함수들 ReceiveMsg SendMsg event TOS_MsgPtr receive(tos_msgptr m) - 시리얼케이블을통해 PC로부터어떠한메시지를받았을경우 Event 형태로호출되는함수로, TOS_Msg 형태의포인터를반환한다. send(...) - 센서노드에서 PC로 TOS_Msg 형태의파일을보내기위해호출되는함수이다. senddone(...) - send(...) 함수를통해메시지가모두전송되었을때 Event 형태로호출되는함수이다. 9
OscilloscopeM.nc OscilloscopeM.nc 파일 (1) includes OscopeMsg; module OscilloscopeM { provides interface StdControl; uses { // 사용할여러인터페이스선언 implementation { // 사용할여러변수들선언 OscilloscopeM.nc 에서는먼저 include 명령어를통해 Oscilloscope.h 에있는내용을참조한후, module 안에 StdControl 인터페이스를 provide로선언한다. 그리고 OscilloscopeM 내에서사용할인터페이스들을 use안에기술한다. implementation 에서는위에서선언된인터페이스를이용하여실제프로그램을기술한다. command result_t t StdControl.init() { // 변수및컴포넌트초기화 return SUCCESS; Main 컴포넌트에의해제일먼저실행되는 StdControl.init() 함수에서 LED, SensorControl, CommControl 컴포넌트들및여러변수들을모두초기화한다. 10
OscilloscopeM.nc OscilloscopeM.nc 파일 (2) command result_t t StdControl.start() { call SensorControl.start(); call Timer.start(TIMER_REPEAT, 125); call CommControl.start(); return SUCCESS; command result_t t StdControl.stop() { return SUCCESS; event result_t Timer.fired() { return call ADC.getData(); StdControl.start() 에서는 SensorControl, Comm Control 를시작하고 Timer 를 125ms 마다한번씩 signal 을발생시키도록 Timer.start(TIMER_REPEAT, 125) 함수를호출한다. StdControl.stop() 에서는 SensorControl, Comm Control을정지하게하고 Timer도정지시킨다. Timer 컴포넌트에의해 125ms 마다 signal 이발생하여 Timer.fired() 가호출되어지고, 그함수내부에는 ADC.getData() 함수를호출하여 ADC[0] 에있는조도측정값을요청한다. 11
OscilloscopeM.nc OscilloscopeM.nc 파일 (3) async event result_t ADC.dataReady (uint16_t data) { struct OscopeMsg *pack; atomic { pack = (struct OscopeMsg *) msg[currentmsg].data; pack >data[packetreadingnumber++] = data; readingnumber++; dbg(dbg_usr1, "data_event n"); if (packetreadingnumber == BUFFER_SIZE) { post datatask(); if (data > 0x0300) call Leds.redOn(); else call Leds.redOff(); 조도값의측정이끝나면 result_t ADC.data Ready(uint16_t data) 함수가 event 형태로 OscilloscopeM 파일내에서호출된다. 이함수내에서는받은조도측정값을시리얼통신을통해 PC에전달하기위해 Oscope Msg.h에정의된패킷포맷형식으로데이터를변환시킨다. 그후, task로된 datatask() 함수를호출하여 ADC.dataReady (uint16_t data) 함수로부터받은측정값을 DataMsg. send() 함수를통해시리얼로 PC에게전송한다. return SUCCESS; 12
OscilloscopeM.nc OscilloscopeM.nc 파일 (4) task void datatask() { struct OscopeMsg *pack; atomic { pack = (struct OscopeMsg *)msg[currentmsg].data; packetreadingnumber = 0; pack >lastsamplenumber = readingnumber; pack >channel = 1; pack >sourcemoteid = TOS_LOCAL_ADDRESS; if (call DataMsg.send(TOS_UART_ADDR, sizeof(struct OscopeMsg), &msg[currentmsg])) { atomic { currentmsg ^= 0x1; call Leds.yellowToggle(); event result_t DataMsg.sendDone (TOS_MsgPtr sent, result_t success) { return SUCCESS; datatask() 함수에서는 ADC.dataReady (data) 함수에서설정한 msg변수를 DataMsg.send ( ) 함수를사용하여시리얼통신을통해 PC로전달한다. PC로의전송이끝나면, DataMsg.send Done 함수가 event 형식으로호출된다. 13
Oscilloscope 예제실습 준비물 : host PC, 모트 1개, ISP프로그램툴, 프린터케이블 14
Oscilloscope 예제실습방법 1 먼저 cygwin 을시작한다. 다음과같이입력하여예제폴더로이동한다. cd /opt/tinyos 1.x/contrib/zigbex cd Oscilloscope 이제 make zigbex 를입력하여컴파일을한다. 15
Oscilloscope 예제실습방법 2 ISP 프로그래머를이용하여 ZigbeX 에다운로드하기 컴파일한후, build/zigbex라는폴더가만들어지고그안에 main.hex 라는파일이생성된다. PonyProg 프로그램을실행한후 main.hex 파일을연다. main.hex의파일의경로는다음과같다. c: Programfiles UCB cygwin opt tinyos 1.x contrib zigbex Oscilloscope build zigbex 16
Oscilloscope 예제실습방법 3 main.hex 를읽은결과 프로그램하기위한풀다운메뉴의사용법 17
자바어플리케이션실행 자바어플리케이션 시리얼케이블을통해 Zigbex 노드로부터전송된데이터를확인하기위해서오실로스코프자바어플리케이션을실행시킨다. 자바어플리케이션을시작하기에앞서, 모트에연결된프린트케이블을분리시킨후, 다시시리얼케이블과시리얼젠더를이용하여 PC 와연결한다. cygwin에서 /opt/tinyos 1.x/tools/java로이동한다. 명령어는아래와같다. export MOTECOM=serial@COM1:57600 cd /opt/tinyos 1.x/tools/java java net.tinyos.oscope.oscilloscope 18
결과 Oscilloscope 예제결과 자바어플리케이션을통해아래와같이데이터가시리얼로전달되는것을확인할수있고빛의양에따라데이터를나타내는선이변화되는것을볼수있다.( 그래프가잘보이지않으면 scrolling을체크 ) 19