Presentation is loading. Please wait.

Presentation is loading. Please wait.

Ubiquitous Computing Practice - Part 2(Sensors, Serial, RF) -

Similar presentations


Presentation on theme: "Ubiquitous Computing Practice - Part 2(Sensors, Serial, RF) -"— Presentation transcript:

1 Ubiquitous Computing Practice - Part 2(Sensors, Serial, RF) -
Spring Semester, 2010 Ubiquitous Computing Practice - Part 2(Sensors, Serial, RF) - Laboratory of Intelligent KUT ( Created by: Heon-Jong Lee Presenter: Yong-hwan Kim

2 목차 2. Timer를 이용한 LED 제어 3. 조도 센서 제어 4. 온/습도 센서 제어
Timer component를 이용하여 일정 시간마다 LED On/Off 3. 조도 센서 제어 빛의 광량을 측정하는 조도 센서의 동작 및 센싱 데이터 처리 및 확인 4. 온/습도 센서 제어 SHT11을 이용하여 온/습도를 얻고 시리얼 통신으로 확인 5. Photo 센서 제어(RF 통신) BS520 Photo 센서를 이용하여 빛과 적외선을 측정하고 그 결과를 RF 무선통신을 통해 다른 노드에 전송 Ubiquitous Computing

3 2. Timer를 이용한 LED 제어 Timer component를 이용하여 일정 시간마다 LED On/Off
Ubiquitous Computing

4 (generic configuration)
configuration BlinkTimer { } implementation { components MainC, BlinkTimerM, LedsC, new TimerMilliC (); BlinkTimerM.Boot -> MainC; BlinkTimerM.Leds -> LedsC; BlinkTimerM.Timer -> TimerMilliC; BlinkTimer.nc BlinkTimer.nc MainC (configuration) TimerMilliC (generic configuration) Boot Timer implementation startPeriodic(); startOneShot(); BlinkTimerM (module) LedsC (configuration) Boot implementation Boot.booted(); Timer.fired(); Leds Leds implementation Leds.init(); Leds.redOn(); Timer

5 기본 지식(TimerMilliC component)
경로: \opt\tinyos-2.x\tos\system\TimerMilliC.nc Timer interface 사용 Timer interface에서 제공하는 함수들 command uint32_t getdt () 설정된 타이머의 주기를 리턴 command uint32_t getNow () 현재 시간을 리턴 command uint32_t gett0 () 타이머가 호출된 시간인 t0를 리턴 command bool isOneShot () 한 번 호출로 종료되는 타이머인지 확인 command bool isRunning () 현재 타이머가 설정되어 실행중인지 확인 *command bool startOneShot (uint32_t dt) dt 시간 후에 한번 이벤트를 발생 command bool startOneShot (uint32_t t0, uint32_t dt) t0 + dt 시간 후에 이벤트를 발생 *command bool startPeriodic (uint32_t dt) dt 시간을 주기로 계속 반복하여 이벤트 발생 command bool startPeriodic (uint32_t t0, uint32_t dt) t0 시간부터 dt 주기로 반복하여 이벤트 발생 command void stop () 현재 진행중인 timer를 정지 event void fired () 정해진 타이머가 끝났음을 알림 Ubiquitous Computing

6 BlinkTimer.nc Timer component를 이용하여 일정 시간마다 LED On/Off 하는 예제
configuration BlinkTimer { } implementation { components MainC, BlinkTimerM, LedsC, new TimerMilliC (); BlinkTimerM.Boot -> MainC; BlinkTimerM.Leds -> LedsC; BlinkTimerM.Timer -> TimerMilliC; 중복적으로 사용될수 있는 컴포넌트를 지원하기 위한 기법 Ubiquitous Computing

7 BlinkTimerM.nc module BlinkTimerM { uses { interface Boot;
interface Leds; interface Timer<Tmilli>; } implementation { event void Boot.booted() { call Timer.startPeriodic(1000); event void timer.fired () { call Leds.led0Toggle (); //시간단위를 ms로 함 //1초마다 Timer.fired event 함수 호출 Ubiquitous Computing

8 Blink 예제 실습 $ cd /opt/tinyos-2.x/contrib/zigbex/BlinkTimer
$ make zigbex Ubiquitous Computing

9 Blink 예제 실습 USB-ISP와 ZigbeX노드를 결합 USB-ISP mode는 ISP로 설정
AVR Studio에서 Tools → Program AVR → Auto Connect 메뉴를 선택 … 버튼을 눌러 BlinkTimer\build\zigbex\main.hex 선택 후 Program 버튼을 눌러 프로그램함 프로그램 직후 red LED가 1초마다 toggle 되는 것을 볼 수 있음 Ubiquitous Computing

10 Blink 예제 실습 응용 Timer를 3개 사용하여 BlinkTimer2 작성 1000ms 마다 빨간색 led Toggle
Ubiquitous Computing

11 3. 조도 센서 제어 빛의 광량을 측정하는 조도 센서의 동작 및 센싱 데이터 처리 및 확인
Ubiquitous Computing

12 조도 센서 CDS 조도 센서 CDS ZigbeX-II에 장치되어 있는 조도 센서 CDS는 ATmega 128(ZigbeX-II의 8bit CPU)의 INT0과 ADC0 사이에 연결되어있다. 조도 센서인 CDS는 주변의 광량에 따라 자신의 저항이 변하게 된다. 결국, 출력포트인 ADC0에서는 변화된 전압의 양에 의해 광량을 감지할 수 있다. Ubiquitous Computing

13 기본 지식 SerialControl interface(원형은 SplitControl) AMSend interface 함수 기능
command error_t start () 호출하는 component의 하부 component 시작 command error_t stop () 호출하는 component의 하부 component 중지 event void startDone (error_t error) 시작이 완료되면 이벤트를 발생함 event void stopDone (error_t error) 중지가 완료되면 이벤트를 발생함 함수 기능 command error_t cancel (message_t *msg) msg의 전송을 취소한다 command void* getPayload (message_t *msg) msg의 payload 영역의 포인터를 반환 command uint8_t maxPayloadLength () tinyOS에서 설정된 payload가 가지는 최대 크기를 반환 command error_t send (am_addr_t addr, message_t *msg, uint8_t len) addr 주소로 len만큼의 payload 길이를 갖는 msg를 addr로 전송 event void sendDone (message_t *msg, error_t error) 메시지의 전송이 완료되었을 경우 호출 Ubiquitous Computing

14 기본 지식 Receive interface Read interface 함수 기능
command void* getPayload (message_t *msg, uint8_t *len) msg의 Payload 영역의 포인터를 반환 command uint8_t payloadLength (message_t *msg) msg의 payload 영역의 길이를 반환 event message_t* receive (message_t *msg, void *payload, uint8_t len) 데이터가 수신되어 있을 때 발생하는 이벤트로 수신된 메시지인 msg, payload, payload 길이를 전달 함수 기능 command error_t read () 해당 센서의 측정값을 요청 event void readDone (error_t result, val_t val) 측정된 값을 val 변수에 넣어 이벤트 함수로 반환 Ubiquitous Computing

15 OscilloscopeAppC.nc Timer component를 이용하여 일정 시간마다 조도값을 읽어 시리얼통신하는 예제 1
2 3 4 5 6 7 8 9 10 11 12 13 configuration OscilloscopeAppC { } implementation { components OscilloscopeC, MainC, LedsC, new TimerMilliC (), new PhotoSensorC () as Sensor, SerialActiveMessageC as Comm; OscilloscopeC.Boot -> MainC; OscilloscopeC.SerialControl -> Comm; OscilloscopeC.AMSend -> Comm.AMSend[AM_OSCILLOSCOPE]; OscilloscopeC.Receive -> Comm.Receive[AM_OSCILLOSCOPE]; OscilloscopeC.Timer -> TimerMilliC; OscilloscopeC.Read -> Sensor; OscilloscopeC.Leds -> LedsC; } 별칭하여 사용 CDS 센서값 위한 component PC와 Serial 통신을 위한 component 참고) Main에서 초기화 한 후 조도 패킷을 받기 위해 필요한 컴포넌트들의 관계를 연결해주면 OscilloscopeM 컴포넌트에서 사용하는 컴포넌트들을 몽땅 불러와 구현을 한다. OscilloscopeM 입장에서는 그냥 구현되어 있는 컴포넌트들을 인터페이스를 통하여 사용하기만 하면 된다. Receive와 AMSend는 패킷을 저장하고 보내는 역할을 하며 눈에 보이지 않는 내부적인 처리이다. 문서화를 통해 컴포넌트들의 관계를 보면 알겠지만 따지고 들어가면 한이없다. 한없이 따지고 들어가면 결국 미아가 되어 버리고 만다. 그냥 사용하는 거다. 컴포넌트들을 연결만 해주면 조도 패킷을 받을 수 있고 Led를 마음대로 제어할 수 있다. 만약 이것을 C로 구현한다면 아마 엄청난 날코딩을 해야 할 것이다.  상수값 0x93, 같은 type의 interface 간에만 송/수신 Ubiquitous Computing

16 OscilloscopeC.nc OscilloscopeC.nc 파일 경로: 함수 실행순서
/opt/tinyos-2.x/contrib/zigbex/Oscilloscope/OscilloscopeC.nc 함수 실행순서 Boot.booted() → SerialControl.start () SerialControl.startDone () → startTimer () startTimer () → Timer.startPeriodic () 반복 Timer.fired () → Read.read () → 조도값 측정 → Read.read Done() → AMSend.send () Ubiquitous Computing

17 OscilloscopeC.nc 1: #include "Timer.h"
2: #include "Oscilloscope.h" 3: module OscilloscopeC 4: { 5: uses { 6: interface Boot; 7: interface SplitControl as SerialControl; 8: interface AMSend; 9: interface Receive; 10: interface Timer<TMilli>; 11: interface Read<uint16_t>; 12: interface Leds; 13: } 14: } 15: implementation 16: { 17: message_t sendbuf; 18: bool sendbusy; 19: oscilloscope_t local; 20: uint8_t reading; 21: bool suppress_count_change; 1~2: OscilloscopeC.nc 에서는 먼저 include 명령어 를 통해 Timer.h, Oscilloscope.h 에 있는 내용을 참 조한다. 5~13: uses에는 Module파일에서 사용할 인터페이스 들을 기술하고 있다. 17~21: 사용될 구조체변수 및 각종 변수들을 선언한 다. Ubiquitous Computing

18 OscilloscopeC.nc 22: void report_problem() {
23: call Leds.led0Toggle(); 24: } 25: void report_sent() { 26: call Leds.led1Toggle(); 27: } 28: void report_received() { 29: call Leds.led2Toggle(); 30: } 31: event void Boot.booted() 32: { 33: local.interval = DEFAULT_INTERVAL; 34: local.id = TOS_NODE_ID; 35: if (call SerialControl.start() != SUCCESS) 36: report_problem(); 37: } 38: void startTimer() 39: { 40: call Timer.startPeriodic(local.interval); 41: reading = 0; 42: }  22~24: 해당 함수 호출 시 적색 LED를 토글시킨다. 25~27: 해당 함수 호출 시 녹색 LED를 토글시킨다. 28~30: 해당 함수 호출 시 황색 LED를 토글시킨다. 31~38: Boot.booted 함수에는 oscilloscope.h 헤더 파일에 정의된 oscilloscope_t 구조체 변수 local의 interval 과 id를 초기화 한다. 이어서 Serial통신을 하기 위해 SerialControl.start() 를 호출하여 시리얼을 시작한다. 시리얼 start 함수 호 출 시 성공하지 못했을 경우에는 report_problem()함 수를 호출하여 적색LED를 토글시킨다. Ubiquitous Computing

19 OscilloscopeC.nc 43: event void SerialControl.startDone
(error_t error) { 44: startTimer(); 45: } 46: event void SerialControl.stopDone 47: } 48: event message_t* Receive.receive (message_t* msg, void* payload, uint8_t len) { 49: oscilloscope_t *omsg = payload; 50: report_received(); 51: if (omsg->version > local.version) 52: { 53: local.version = omsg->version; 54: local.interval = omsg->interval; 55: startTimer(); 56: } 43~45: 시리얼 컴포넌트의 시작이 완료되면 SerialControl.startDone() 이벤트 함수가 호출된다. 이제 시리얼이 초기화되어 통신이 가능하므로 여기에 주기적인 동작을 위해 Timer를 시작한다. 46: SerialControl.stopDone() 은 사용하지 않더라도 구현해야 한다. 왜냐하면 SplitControl (SerialControl) interface를 사용하기 때문이다. Ubiquitous Computing

20 OscilloscopeC.nc 57: if (omsg->count > local.count) 58: {
58: { 59: local.count = omsg->count; 60: suppress_count_change = TRUE; 61: } 62: return msg; 63: } 64: event void Timer.fired() { 65: if (reading == NREADINGS) 66: { 67: if (!sendbusy && sizeof local <= call AMSend.maxPayloadLength()) 68: { 69: memcpy(call AMSend.getPayload (&sendbuf), &local, sizeof local); 70: if (call AMSend.send (AM_BROADCAST_ADDR, &sendbuf, sizeof local) == SUCCESS) 71: sendbusy = TRUE; 72: } 64~82: 타이머 만기시 Timer.fired() 이벤트 함수가 호출되고, 이 함수에서는 oscilloscope_t 구조체의 데이터를 저장하는 readings변수에 10개의 CDS데이 터가 다 입력됐을 경우, AMSend.send함수를 통해 데이터를 전송한다. 성공시 bool형 변수인 sendbusy 에 TRUE 값을 준다. 성공 하지 못했을 경우에는 report_problem()를 호출하여 적색 LED를 토글시킨 다. Payload에 접근할 때 AMSend.getPayload (&sendbuf)를 호출하면 Payload의 시작주소를 리턴 하게 된다. 그리고 함수의 마지막에 Read.read() 를 호출하여 CDS센서의 ADC 값을 요청한다. 실패 시에는 report_problem()를 호출하여 적색 LED 를 토글시킨다. Ubiquitous Computing

21 OscilloscopeC.nc 73: if (!sendbusy) 74: report_problem();
75: reading = 0; 76: if (!suppress_count_change) 77: local.count++; 78: suppress_count_change = FALSE; 79: } 80: if (call Read.read() != SUCCESS) 81: report_problem(); 82: } 83: event void AMSend.sendDone (message_t* msg, error_t error) { 84: if (error == SUCCESS) 85: report_sent(); 86: else 87: report_problem(); 88: sendbusy = FALSE; 89: } 83: Serial 전송이 완료되면 녹색 LED 토글시킨다. Ubiquitous Computing

22 OscilloscopeC.nc 90: event void Read.readDone(error_t result , uint16_t data) { 91: if (result != SUCCESS) 92: { 93: data = 0xffff; 94: report_problem(); 95: } 96: local.readings[reading++] = data; 97: report_received(); 98: } 99: } 90~98: 조도 측정이 완료 되면 Read.readDone 이벤 트 함수가 호출되고 파리미터로 넘어온 조도 ADC값 을 local구조체의 readings 필드에 입력한다. 그런 후 report_received() 함수를 호출하여 황색 LED를 토글 시킨다. Ubiquitous Computing

23 Oscilloscope.h Oscilloscope.h 에 정의된 데이터 포멧 enum{
NREADINGS = 10, /* Number of readings per message */ DEFAULT_INTERVAL = 256, /* Default sampling period. */ AM_OSCILLOSCOPE = 0x93 }; typedef nx_struct oscilloscope { nx_uint16_t version; /* Version of the interval. */ nx_uint16_t interval; /* Samping period. */ nx_uint16_t id; /* Mote id of sending mote. */ nx_uint16_t count; /* The readings are samples count * NREADINGS onwards */ nx_uint16_t readings[NREADINGS]; } oscilloscope_t; Ubiquitous Computing

24 Oscilloscope 예제 실습 $ cd /opt/tinyos-2.x/contrib/zigbex/Oscilloscope
$ make zigbex Ubiquitous Computing

25 Oscilloscope 예제 실습 USB-ISP와 ZigbeX노드를 결합 USB-ISP mode는 ISP로 설정
AVR Studio에서 Tools → Program AVR → Auto Connect 메뉴를 선택 … 버튼을 눌러 Oscilliscope\build\zigbex\main.hex 선택 후 Program 버튼을 눌러 프로그램함 Ubiquitous Computing

26 데이터 확인(serial 통신) SerialForwarder
모트가 전송한 데이터를 시리얼 포트로부터 받아 처리 port를 확인(명령어 motelist 또는 장치관리자 이용) background program으로 수행(명령어 끝에 & 붙임) java program(Oscilloscope/java 내에 존재) 위 프로그램이 분석한 정보를 바탕으로 화면에 비주얼하게 보여주는 프로그램 USB-ISP의 스위치는 UART로 설정 $ java net.tinyos.sf.SerialForwarder –comm & $ cd /opt/tinyos-2.x/contrib/zigbex/Oscilloscope/java $ make $ ./run Ubiquitous Computing

27 Ubiquitous Computing

28 (참고) java compile java 프로그램 호환과정 1. javac 설치 폴터 환경변수 추가
2. Cygwin에서 tos-install-jni 수행 후, 결과 디렉토리를 환경변수 추가 3. /opt/tinyos-2.x/support/sdk/java 에서 make 4. chmod -R 755 /opt/Java 5. 2의 디렉토리에서 getenv.dll과 toscomm.dll을 찾아 window/system32/로 복사 Ubiquitous Computing

29 4. 온/습도 센서 제어 SHT11을 이용하여 온/습도를 얻고 시리얼 통신으로 확인 Ubiquitous Computing

30 온, 습도 센서 SHT11 온, 습도 센서 SHT11 SHT11은 ZigbeX의 CPU와 직접적으로 연결되어 있다.
SHT11는 측정한 아날로그 신호를 디지털 신호로 바꾸어주는 ADC 기능을 내장하고 있어, CPU에 데이터를 바로 전송할 수 있다. SHT11은 2개의 선을 통해 클럭(Clock)과 Data를 ATmega 128에 전송한다. Ubiquitous Computing

31 SensirionSht11C component에서 제공하는 함수들
기본 지식 SensirionSht11C component 온, 습도 제어 component SensirionSht11C component에서 제공하는 함수들 습도값 얻기 Humidity.read () – SHT11 센서에게 command 명령으로 습도값을 요청 Humidity.readDone (…) – SHT11 센서가 측정한 습도값을 event 형태로 반환 온도값 얻기 Temperature.read () – SHT11 센서에게 command 명령으로 온도값을 요청 Temperature.readDone (…) – SHT11 센서가 측정한 온도값을 event 형태로 반환 Ubiquitous Computing

32 OscilloscopeSHT11 예제의 구성
TimerC: 500ms 마다 Timer.fired() 호출 SensirionSht11C : 온/습도의 측정값을 얻을 수 있는 component로, Sensor로 변경된 이름 사용 SerialActiveMessageC: 시리얼 통신을 위한 component로, Comm으로 변경된 이름 사용 Ubiquitous Computing

33 OscilloscopeAppC.nc configuration OscilloscopeAppC { } implementation
components OscilloscopeC, MainC, LedsC, new TimerMilliC (), new SensirionSht11C () as Sensor, SerialActiveMessageC as Comm; OscilloscopeC.Boot -> MainC; OscilloscopeC.Timer -> TimerMilliC; OscilloscopeC.Read_Humidity -> Sensor.Humidity; OscilloscopeC.Read_Temp -> Sensor.Temperature; OscilloscopeC.Leds -> LedsC; OscilloscopeC.SerialControl -> Comm; OscilloscopeC.AMSend -> Comm.AMSend[AM_OSCILLOSCOPE]; OscilloscopeC.Receive -> Comm.Receive[AM_OSCILLOSCOPE]; } //SensorSht11C는 온도와 습도 각각의 Read interface를 제공하므로 두 개의 interface를 wiring해야 함 Ubiquitous Computing

34 OscilloscopeC.nc OscilloscopeC.nc 파일 경로: define 문에 따라 온도/습도 값을 전송
/opt/tinyos-2.x/contrib/zigbex/ OscilloscopeSHT11/OscilloscopeC.nc define 문에 따라 온도/습도 값을 전송 함수 실행순서(반복) Timer.fired () → Read_Temp.read () → 온도값 읽기 Read_Temp.readDone () → Read_Humidity.read () → 습도값 읽기 Read_Humidity.readDone () → calc_SHT11(온도와 습도를 알맞게 변환) → AMSend.send () #define GET_HUMIDITY_DATA 0 이면 온도값 전송 #define GET_HUMIDITY_DATA 1 이면 습도값 전송 Ubiquitous Computing

35 OscilloscopeC.nc 1: #include "Timer.h" 2: #include <stdio.h>
3: #include "Oscilloscope.h" 4: #define GET_HUMIDITY_DATA 0 //0이면 온도 1이면 습도 5: module OscilloscopeC 6: { 7: uses { 8: interface Boot; 9: interface SplitControl as SerialControl; 10: interface AMSend; 11: interface Receive; 12: interface Timer<TMilli>; 13: interface Read<uint16_t> as Read_Humidity; 14: interface Read<uint16_t> as Read_Temp; 15: interface Leds; 16: } 17:} 18: implementation { 19: void calc_SHT11(uint16_t p_humidity , uint16_t p_temperature); 20: 3: include 를 통해 Oscilloscope.h 내용을 참조. 4: 온도 값을 전송할지, 습도 값을 전송할지 구분. #define GET_HUMIDITY_DATA 0 이면 온도값 #define GET_HUMIDITY_DATA 1 이면 습도값 7~16: OscilloscopeC 내에서 사용할 인터페이스들을 uses안에 기술한다. 18: implementation에서는 위에서 선언된 인터페이스 를 이용하여 실제 프로그램을 기술한다. Ubiquitous Computing

36 OscilloscopeC.nc 21: event void Timer.fired() {
22: if (reading == NREADINGS) 23: { 24: if(!sendbusy && sizeof local <= call AMSend.maxPayloadLength()) 25: { 26: memcpy(call AMSend. getPayload(&sendbuf), &local, sizeof local); 27: if(call AMSend.send (AM_BROADCAST_ADDR, &sendbuf, sizeof local) == SUCCESS) 28: sendbusy = TRUE; 29: } 30: if (!sendbusy) 31: report_problem(); 32: reading = 0; 33: if (!suppress_count_change) 34: local.count++; 35: suppress_count_change = FALSE; 36: } 37: if(call Read_Temp.read() != SUCCESS) 38: report_problem(); } 21~76: SHT11센서는 습도를 계산하기 전에 온도에 대한 정보를 필요로 한다. Timer.fired 이벤트 함수에 서 call Read_Temp.read()로 온도값을 요청하고, 해당 값이 반환되는 call Read_Temp.readDone() 이벤트 함수에서 습도값을 위해 Read_Humidity.read()를 호출한다. Ubiquitous Computing

37 OscilloscopeC.nc 40: event void Read_Humidity.readDone
(error_t result, uint16_t data) { 41: if (result == SUCCESS) 42: { 43: atomic { 44: T_humi = data; 45: } 46: calc_SHT11(T_humi,T_temp); 47: if(GET_HUMIDITY_DATA){ 48: local.readings[reading++] = myhumi; 49: } 50: else{ 51: local.readings[reading++] = mytemp; 52: } 53: } 54: else{ 55: local.readings[reading++] = 0xffff; 56: report_problem(); 57: } 58: report_received(); 59: } 60: event void Read_Temp.readDone (error_t result, uint16_t data) { 61: if (result == SUCCESS) 62: { 63: atomic T_temp = data; 65: if(call Read_Humidity.read() != SUCCESS) 66: report_problem(); 67: } 68: else{ 69: report_problem(); 70: local.readings[reading++] = 0xffff; 71: } 72: } 73: void calc_SHT11(uint16_t p_humidity , uint16_t p_temperature) { 74: const float C1=-4.0; // for 12 Bit 75: 76: } 77 :} Ubiquitous Computing

38 OscilloscopeSHT11 예제 실습 컴파일 후 AVR Studio를 이용하여 노드에 포팅 자바 애플리케이션으로 확인
$ cd /opt/tinyos-2.x/contrib/zigbex/OscilloscopeSHT11 $ make zigbex $ java net.tinyos.sf.SerialForwarder –comm & $ cd /opt/tinyos-2.x/contrib/zigbex/Oscilloscope/java $ make $ ./run Ubiquitous Computing

39 java Listen 이용 $ export MOTECOM=serial@COMX:57600
$ java net.tinyos.tools.Listen //message_t 내용 출력 Ubiquitous Computing

40 SerialTest 이용 SerialTest 다운로드 (SerialTest.exe)
실행 후 Port Configuration 수행하여 해당 포트번호와 Baud 설정 후 Open Port 수행 Ubiquitous Computing

41 5. Photo 센서 제어(RF 통신) BS520 Photo 센서를 이용하여 빛과 적외선을 측정하고 그 결과를 RF 무선통신을 통해 다른 노드에 전송 Ubiquitous Computing

42 적외선 센서 BS520 적외선 센서 BS520 적외선 센서인 BS520은 ATmega128의 ADC1과 연결되어 있다.
적외선의 강약에 따라 BS520의 출력 AD가 변화하기 때문에, ADC1로 들어오는 전류 변화량에 따라 적외선 값을 측정할 수 있다. Ubiquitous Computing

43 OscilloscopeUltraredRF 예제의 구성도
무선통신 시리얼케이블 ZigbeX 1 ZigbeX 0 OscilloscopeUltraRF BaseStation 1번 노드 – 256ms 마다 측정한 Photo 값을 10번 모아 RF 무선통신을 통해 주위에 broadcast 0번 노드 – RF 데이터를 수신하여 serial 전송 Ubiquitous Computing

44 OscilloscopeUltraredRF 예제의 구성
ActiveMessageC : RF 상태 관련 초기화(SplitControl 사용) AMSender, AMReceiverC : message 전송, 수신 AM_OSILLOSCOPE는 메시지 type 설정됨 message type이 AM_OSCILLOSCOPE일 경우만 receive Ubiquitous Computing

45 OscilloscopeApp.nc configuration OscilloscopeAppC { } implementation {
components OscilloscopeC, MainC, LedsC, new TimerMilliC (), new SensirionSht11C() as Sensor, SerialActiveMessageC , new AMSenderC (AM_OSCILLOSCOPE), new AMReceiverC (AM_OSCILLOSCOPE); OscilloscopeC.Boot -> MainC; OscilloscopeC.RadioControl -> ActiveMessage; Oscilloscope.AMSend ->AMSenderC; Oscilloscope.Receive ->AMReceiverC; Oscilloscope.Timer ->TimerMilliC; Oscilloscope.Read ->Sensor; Oscilloscope.Leds ->LedsC; } Ubiquitous Computing

46 OscilloscopeC.nc OscilloscopeC.nc 파일 경로: 함수 실행순서
/opt/tinyos-2.x/contrib/zigbex/ OscilloscopeUltraredRF/OscilloscopeC.nc 함수 실행순서 Boot.booted() → RadioControl.start () RadioControl.startDone () → startTimer () startTimer () → Timer.startPeriodic () 반복 Timer.fired () → Read.read () → 적외선값 측정 → AMSend.send () Ubiquitous Computing

47 OscilloscopeC.nc 1: #include "Timer.h"
2: #include "Oscilloscope.h" 3: module OscilloscopeC 4: { 5: uses { 6: interface Boot; 7: interface SplitControl as RadioControl; 8: interface AMSend; 9: interface Receive; 10: interface Timer<TMilli>; 11: interface Read<uint16_t>; 12: interface Leds; 13: } 14: } 15: implementation 16: { 17: message_t sendbuf; 18: bool sendbusy; 19: oscilloscope_t local; 20: uint8_t reading; 21: bool suppress_count_change; 1~2: OscilloscopeC.nc 에서는 먼저 include 명령어 를 통해 Timer.h, Oscilloscope.h 에 있는 내용을 참조한다. 3~14: Module파일에 uses에는 사용할 인터페이스 들을 기술하고 있다. Ubiquitous Computing

48 OscilloscopeC.nc 22: void report_problem() { call Leds.led0Toggle(); }
23: void report_sent() { call Leds.led1Toggle(); } 24: void report_received() { call Leds.led2Toggle(); } 25: event void Boot.booted() { 26: local.interval = DEFAULT_INTERVAL; 27: local.id = TOS_NODE_ID; 28: If (call RadioControl.start() != 29: SUCCESS) report_problem(); 30: } 31: void startTimer() { 32: call Timer.startPeriodic(local.interval); 33: reading = 0; 34: } 35: event void RadioControl.startDone (error_t error) { 36: startTimer(); 37: }  38: event void RadioControl.stopDone 39: } 25~30: Boot.booted함수에서는 oscilloscope.h 헤더 파일에 있는 oscilloscope_t 구조체 변수 local의 interval 과 id를 초기화 하고, ActiveMessageC에서 제공하는 RadioControl.start()를 호출하여 RF통신을 위한 초기화를 수행한다. 35~37: 시리얼 컴포넌트의 초기화가 완료되면 RadioControl.startDone 이벤트 함수가 호출되고, 이제 시리얼이 초기화되어 통신이 가능하므로 여기에 센서 데이터를 읽어올 Timer를 시작한다. Ubiquitous Computing

49 OscilloscopeC.nc 40: event message_t* Receive.receive
(message_t* msg, void* payload, uint8_t len) { 41: oscilloscope_t *omsg = payload; 42: report_received(); 43: if (omsg->version > local.version) 44: { 45: local.version = omsg->version; 46: local.interval = omsg->interval; 47: startTimer(); 48: } 49: if (omsg->count > local.count) 50: { 51: local.count = omsg->count; 52: suppress_count_change = TRUE; 53: } 54: return msg; 55: } 56: event void Timer.fired() { 57: if (reading == NREADINGS) 58: { 60: If (!sendbusy && sizeof local <= call AMSend.maxPayloadLength()) 40~55: AM_OSCILLOSCOPE type을 갖는 데이터를 RF로부터 수신했을 경우 Receive.receive이벤트 함 수가 호출되며, 수신한 메시지의 Payload영역에 저 장한 oscilloscope_t 구조체의 데이터에 따라 센싱 타이머 주기와 count필드의 값을 수동으로 변경 하게 된다. 56~75: 타이머 이벤트가 발생할 때 마다 Timer.fired() 이벤트 함수가 호출된다. 이 함수에서는 oscilloscope_t 구조체의 데이터를 저장하는 readings변수에 10개의 데이터가 다 입력됐을 경우, AMSend.send함수를 통해 데이터를 전송한다. 성공 시 bool형 변수인 sendbusy에 TRUE 값을 준다. 성공 하지 못했을 경우에는 report _problem()를 호출하여 적색 LED를 토글시킨다. Ubiquitous Computing

50 OscilloscopeC.nc 61: { 62: memcpy(call AMSend.
61: { 62: memcpy(call AMSend. getPayload(&sendbuf), &local, sizeof local); 63: if (call AMSend.send (AM_BROADCAST_ADDR, &sendbuf, sizeof local) == SUCCESS) 64: sendbusy = TRUE; 65: } 66: if (!sendbusy) 67: report_problem(); 68: reading = 0; 69: if (!suppress_count_change) 70: local.count++; 71: suppress_count_change = FALSE; 72: } 73: if (call Read.read() != SUCCESS) 74: report_problem(); 75: } Ubiquitous Computing

51 OscilloscopeC.nc 76: event void AMSend.sendDone(message_t*
msg, error_t error) { 77: if (error == SUCCESS) 78: report_sent(); 79: else 80: report_problem(); 81: sendbusy = FALSE; 82: } 83: event void Read.readDone(error_t result, uint16_t data) { 84: if (result != SUCCESS) 85: { 86: data = 0xffff; 87: report_problem(); 88: } 89: local.readings[reading++] = data; 90: report_received(); 91: } 92: } 76~82: 메시지 전송이 완료 되었을 경우 성공하면 report_sent() 함수를 호출하여 녹색LED를 토글시 키고, 실패 시에는 report_problem() 함수를 호출하 여 적색LED를 토글시킨다. 83~91: 데이터 전송이 완료되면 Read.readDone 이벤트 함수가 호출되고 ADC값을 local구조체의 readings 필드에 입력한다. 그런 후 report_received() 함수를 호출하여 황색 LED를 토글시킨다. Ubiquitous Computing

52 BaseStation BaseStation 경로 /opt/tinyos-2.x/contrib/zigbex/BaseStation/
무선으로 받은 데이터는 시리얼로 전송 시리얼로 받은 데이터는 무선으로 전송 Ubiquitous Computing

53 CFLAGS += -DDEFINED_TOS_AM_GROUP=0x22
Group Id Broadcast 전송이므로 다른 조의 AM_OSCILLOSCOPE 타입의 패킷이 나의 BaseStation으로 전송 가능 Makefile에 다음 줄을 추가 후 컴파일 CFLAGS += -DDEFINED_TOS_AM_GROUP=0x22 그룹을 나눔으로써 그룹 아이디가 다를 경우 패킷이 CPU 쪽으로 올라오지 않도록 하는 방법이지만 RF채널을 변경한 것은 아니므로 충돌문제나 기타 성능향상은 되지 않음 Ubiquitous Computing

54 OscilloscopeUltraredRF 예제 실습
BaseStation 컴파일 및 포팅 OscilloscopeUltraredRF 컴파일 및 포팅 java program을 이용하여 데이터 확인 $ cd /opt/tinyos-2.x/contrib/zigbex/BaseStation $ make zigbex $ cd /opt/tinyos-2.x/contrib/zigbex/OscilloscopeUltraredRF $ make zigbex $ java net.tinyos.sf.SerialForwarder –comm & $ cd java $ make $ ./run Ubiquitous Computing

55 (참고) 데이터 분석 * Serial_Echo_Test 예제 참고 Ubiquitous Computing

56 TOS_Message(TinyOS→PC)
1 2 3 4 ~ N N+1 N+2 N+3 SYNC_ BYTE Packet Type Dispatch ID Payload Data CRC1 CRC2 0x7E 0x45 0x00 SYNC_BYTE 데이터의 시작과 끝 0x7E Packet Type 0x45 : ack가 필요 없는 사용자 패킷 Payload DispatchID 0x00 (시리얼 메시지임을 의미) CRC (Cycling Redundancy Check) payload에 0x7E가 들어올 경우: 0x7D 0x5E payload에 0x7D가 들어올 경우: 0x7D 0x5D (RFC 1662) Ubiquitous Computing

57 message_t 구조체 /opt/tinyos-2.x/tos/types/message.h
serial 통신 및 RF 통신용 구조체 typedef nx_struct message_t { nx_uint8_t header[sizeof(message_header_t)]; nx_uint8_t data[TOSH_DATA_LENGTH]; //28 nx_uint8_t footer[sizeof(message_footer_t)]; //CRC 2byte nx_uint8_t metadata[sizeof(message_metadata_t)]; } message_t; Ubiquitous Computing

58 serial_header_t 시리얼 통신을 위한 컴포넌트인 SerialActiveMessageC 사용시 header 영역에 들어가는 값 /opt/tinyos-2.x/tos/lib/serial/Serial.h typedef nx_struct serial_header { nx_am_addr_t dest; //메시지 받는 하드웨어 주소(0xFFFF) nx_am_addr_t src; //패킷 보내는 노드의 주소 nx_uint8_t length; //data영역의 길이 nx_am_group_t group; //group id(0x00) nx_am_id_t type; //SerialActiveMessageC 배열에 } serial_header_t; 넣은 숫자 Ubiquitous Computing

59 cc2420_header_t RF 무선통신을 위한 ActiveMessageC, AMSenderC, AMReceiverC 사용시 header 영역에 들어가는 값 /opt/tinyos-2.x/tos/chips/cc2420/CC2420.h typedef nx_struct cc2420_header_t { nxle_uint8_t length; nxle_uint16_t fcf; nxle_uint8_t dsn; nxle_uint16_t destpan; nxle_uint16_t dest; nxle_uint16_t src; nxle_uint8_t type; } cc2420_header_t; Ubiquitous Computing

60 Oscilloscope(조도 센서 예제) data
/opt/tinyos-2.x/contribe/zigbex/Oscilloscope/Oscilloscope.h typedef nx_struct oscilloscope { nx_uint16_t version; /* Version of the interval. */ nx_uint16_t interval; /* Samping period. */ nx_uint16_t id; /* Mote id of sending mote. */ nx_uint16_t count; /* The readings are samples count * NREADINGS onwards */ nx_uint16_t readings[NREADINGS]; } oscilloscope_t; Ubiquitous Computing

61 Oscilloscope(조도 센서 예제) 패킷 분석
SYNC_ BYTE Packet Type Dispat chID Payload Data CRC1 CRC2 2 3 ~ N-3 N-2 N-1 N message_t header data footer metadata serial_ header_t dest src length group type 1 2 3 4 5 6 oscillo scope_t version interval id count readings 1 2 3 4 5 6 7 8 ~ 28 Ubiquitous Computing

62 Oscilloscope(조도 센서 예제) 패킷 분석
7E FF FF C A 05 0D 05 0E C 05 0A A F 45 7E 7E : 시작을 나타냄 45 : ACK가 필요 없는 패킷 타입 00 : DispatchID (시리얼은 0을 갖는다) FF FF : dst 주소 (0xFFFF 는 broadcast를 의미 – default 값) : src 주소 (src 주소 설정 함수를 호출하지 않으면 0x0000) 1C : 데이터 length (28을 의미) 00 : group 93 : type : version : interval (256을 의미) : id count : 00 0A (10번째 패킷을 의미) 05 0D : readings[0] (조도값 1) : readings[9] (조도값 10) 9F 45 : CRC 체크 byte 7E : 끝을 나타냄 Ubiquitous Computing

63 PC → TinyOS SYNC_BYTE Packet Type Sequence Payload 데이터의 시작과 끝 0x7E
1 2 3 4 ~ N-3 N-2 N-1 N SYNC_ BYTE Packet Type Sequ ence Dispat chID Payload Data CRC1 CRC2 0x7E 0x44 0x00 SYNC_BYTE 데이터의 시작과 끝 0x7E Packet Type 0x44 : ack가 필요한 사용자 패킷 Sequence 패킷의 재전송 Sequence를 의미하는 번호 (새 패킷은 0을 가짐) Payload DispatchID 0x00 (시리얼 메시지임을 의미) CRC (Cycling Redundancy Check) payload에 0x7E가 들어올 경우: 0x7D 0x5E payload에 0x7D가 들어올 경우: 0x7D 0x5D (RFC 1662) Ubiquitous Computing


Download ppt "Ubiquitous Computing Practice - Part 2(Sensors, Serial, RF) -"

Similar presentations


Ads by Google