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

Slides:



Advertisements
Similar presentations
Wireless & Mobile Communication system LAB TinyOS 의 메시지 형식 및 자바 응용 프로그램들 조선대학교 정보통신공학과 변재영 본 자료는 한백전자 교육자료를 이용하여 제작되었음을 밝힙니다.
Advertisements

컴퓨터와 인터넷.
쉽게 풀어쓴 C언어 Express 제11장 포인터 C Express Slide 1 (of 27)
자바실험실 이동준 우리 곁으로 다가온 사물 컴퓨팅 자바실험실 이동준.
TinyOS Tutorial Lesson 3 : Introducing Tasks for Application Data Processing (Hanback’s zigbeX & TinyOS ver.1.1.7) 3번째 시간입니다. Lesson 2는 생략하고 건너 뛰었습니다.
코크파트너 설치 가이드 Window 7.
인공지능실험실 석사 2학기 이희재 TCP/IP Socket Programming… 제 11장 프로세스간 통신 인공지능실험실 석사 2학기 이희재
Ubiquitous Computing Practice - Part I (Introduction, NesC) -
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
UNIT 15 Timer & Watch Dog 로봇 SW 교육원 조용수.
Report #2 - Solution 문제 #1: 다음과 같이 프로그램을 작성하라.
CUDA Setting : Install & Compile
ZigbeX 소개.
TinyOS 사용법 및 nesC Programming
Ubiquitous Computing Practice - Part I (Installation) -
Ubiquitous Computing Practice - Part 3(RF통신, MAC 프로토콜) -
Ubiquitous Computing Practice - Part I (Introduction, NesC) -
AP 모드 활용하기 WiFi 시리얼 보드 활용가이드 김영준 헬로앱스 (
11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const.
Error Detection and Correction
Root Filesystem Porting
Ubiquitous Computing Practice (RFID)
TCP/IP 응용 프로그램에 적용 가능한 다양한 소켓 옵션을 이해하고 활용한다.
DK-128 ADC 실습 아이티즌 기술연구소
부트로더와 Self Programming
메시지 큐[5] – test1.c 메시지 제어: msgctl(2) #include <sys/msg.h>
DK-128 실습 EEPROM 제어 아이티즌 기술연구소
타이머카운터 사용법 휴먼네트웍스 기술연구소
4. LAN의 배선체계 (3장. LAN: Local Area Network)
14장. 포인터와 함수에 대한 이해.
Ubiquitous Computing Practice (RFID)
10장. 예외처리.
C#.
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
어서와 C언어는 처음이지 제14장.
인터넷응용프로그래밍 JavaScript(Intro).
㈜시스원이 제공하는 시스템 관리 통합 솔루션 SysmanagerOne Agent설치 안내서
27장. 모듈화 프로그래밍.
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
SMART-W50의 사용 방법 ▪ 1. 서버에서의 CDMA 설정
HTTP 프로토콜의 요청과 응답 동작을 이해한다. 서블릿 및 JSP 를 알아보고 역할을 이해한다.
24장. 파일 입출력.
임베디드 시스템 개론 임베디드 타겟 보드 포팅 및 H/W 제어 3일차 강의 자료 Embedded System Lab.
Ubiquitous Computing Practice - Part 2(LED 제어) -
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
USN(Ubiquitous Sensor Network)
DK-128 실습 내부 EEPROM 제어 아이티즌 기술연구소 김태성 연구원
DK-128 실습 타이머카운터 사용법 아이티즌 기술연구소
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
클라우드 서버로 부터 값 읽어오기 WiFi 시리얼 보드 활용가이드 김영준 헬로앱스 (
컴퓨터 프로그래밍 기초 - 8th : 함수와 변수 / 배열 -
웹서버 기능으로 데이터 읽기 및 제어하기 WiFi 시리얼 보드 활용가이드 김영준
Fucntion 요약.
CHAP 21. 전화, SMS, 주소록.
STS 에서 웹 서버 설치 방법.
DK-128 개발환경 설정 아이티즌 기술연구소
DK-128 직렬통신 실습 아이티즌 기술연구소
AT MEGA 128 기초와 응용 I 기본적인 구조.
Homework #12 (1/2) 프로그램을 작성하고, 프로그램과 실행 결과를 프린트하여 제출한다.
7주차: Functions and Arrays
생체 신호의 실시간 디지털 처리 7조 홍윤호( )-1등
셀프 프로그래밍으로 쓰기 셀프 프로그래밍이란? 프린트포트의 ISP 모듈을 사용하지 않음 부트로더에 의한 펌웨어 다운로드
AdcRead API 함수 분석 마이크로프로세서.
IPC 펌웨어 업그레이드 방법 안내 ** 반드시 IPC를 NVR POE 포트 연결 전에 작업 하시기 바랍니다. IPC를 NVR POE 포트에 연결 하실 경우 IP 대역폭을 마추셔야 하는 작업이 필요합니다. **
동적메모리와 연결 리스트 컴퓨터시뮬레이션학과 2016년 봄학기 담당교수 : 이형원 E304호,
Tiny OS & NesC , NesC Part2..
제 29 강 스트링(string) 다루기 s a i s . s T i h t g r i n.
아두이노 프로그래밍 2일차 – Part4 아날로그 키패드 활용하기 강사: 김영준 목원대학교 겸임교수
ARP.
Progress Seminar 양승만.
Presentation transcript:

Ubiquitous Computing Practice - Part 2(Sensors, Serial, RF) - Spring Semester, 2010 Ubiquitous Computing Practice - Part 2(Sensors, Serial, RF) - Laboratory of Intelligent Networks @ KUT (http://link.kut.ac.kr) Created by: Heon-Jong Lee Presenter: Yong-hwan Kim

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

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

(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

기본 지식(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

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

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

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

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

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

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

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

기본 지식 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

기본 지식 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

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

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

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

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

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

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

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

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

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

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

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

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

Ubiquitous Computing

(참고) 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 serial@COMX:57600 & $ cd java $ make $ ./run Ubiquitous Computing

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

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

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

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

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

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

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

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

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