Ubiquitous Computing Practice Part 1

Download Report

Transcript Ubiquitous Computing Practice Part 1

Spring Semester, 2011
Ubiquitous Computing Practice
- Part 3(RF통신, MAC 프로토콜) Laboratory of Intelligent Networks @ KUT
(http://link.kut.ac.kr)
Yong-hwan Kim
5. Photo 센서 제어(RF 통신)
BS520 Photo 센서를 이용하여 빛과 적외선을 측정하고
그 결과를 RF 무선통신을 통해 다른 노드에 전송
2
Ubiquitous Computing
적외선 센서 BS520
적외선 센서 BS520


3
적 외 선 센 서 인 BS520 은 ATmega128 의 ADC1 과
연결되어 있다.
적외선의 강약에 따라 BS520의 출력 AD가 변화하기
때문에, ADC1로 들어오는 전류 변화량에 따라 적외선
값을 측정할 수 있다.
Ubiquitous Computing
OscilloscopeUltraredRF 예제의 구성도
무선통신


4
ZigbeX 1
ZigbeX 0
OscilloscopeUltraRF
BaseStation
시리얼케이블
1번 노드 – 256ms 마다 측정한 Photo 값을 10번 모아
RF 무선통신을 통해 주위에 broadcast
0번 노드 – RF 데이터를 수신하여 serial 전송
Ubiquitous Computing
OscilloscopeUltraredRF 예제의 구성

RF 로 전송하기 위해 필요한 컴포넌트
 ActiveMessageC : RF 상태 관련 초기화(SplitControl 사용)
 AMSender, AMReceiverC : message 전송, 수신

AM_OSILLOSCOPE는 메시지 type 설정됨
 message type이 AM_OSCILLOSCOPE일 경우만 receive
5
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);
}
6
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 ()
7
Ubiquitous Computing
OscilloscopeC.nc
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
8
#include "Timer.h"
#include "Oscilloscope.h"
module OscilloscopeC
{
uses {
interface Boot;
interface SplitControl as RadioControl;
interface AMSend;
interface Receive;
interface Timer<TMilli>;
interface Read<uint16_t>;
interface Leds;
}
}
implementation
{
message_t sendbuf;
bool sendbusy;
oscilloscope_t local;
uint8_t reading;
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(); }
void report_sent() {
call Leds.led1Toggle(); }
void report_received() {
call Leds.led2Toggle(); }
event void Boot.booted() {
local.interval = DEFAULT_INTERVAL;
local.id = TOS_NODE_ID;
If (call RadioControl.start() !=
SUCCESS) report_problem();
}
void startTimer() {
call Timer.startPeriodic(local.interval);
reading = 0;
}
event void RadioControl.startDone
(error_t error) {
startTimer();
}
event void RadioControl.stopDone
(error_t error) {
}
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
9
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) {
oscilloscope_t *omsg = payload;
report_received();
if (omsg->version > local.version)
{
local.version = omsg->version;
local.interval = omsg->interval;
startTimer();
}
if (omsg->count > local.count)
{
local.count = omsg->count;
suppress_count_change = TRUE;
}
return msg;
}
event void Timer.fired() {
if (reading == NREADINGS)
{
If (!sendbusy && sizeof local <= call
AMSend.maxPayloadLength())
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
60:
10
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:
{
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
memcpy(call AMSend.
getPayload(&sendbuf), &local,
sizeof local);
if (call AMSend.send
(AM_BROADCAST_ADDR,
&sendbuf, sizeof local) ==
SUCCESS)
sendbusy = TRUE;
}
if (!sendbusy)
report_problem();
reading = 0;
if (!suppress_count_change)
local.count++;
suppress_count_change = FALSE;
}
if (call Read.read() != SUCCESS)
report_problem();
}
11
Ubiquitous Computing
OscilloscopeC.nc
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92: }
12
event void AMSend.sendDone(message_t*
msg, error_t error) {
if (error == SUCCESS)
report_sent();
else
report_problem();
sendbusy = FALSE;
}
event void Read.readDone(error_t
result, uint16_t data) {
if (result != SUCCESS)
{
data = 0xffff;
report_problem();
}
local.readings[reading++] = data;
report_received();
}
76~82: 메시지 전송이 완료 되었을 경우 성공하면
report_sent() 함수를 호출하여 녹색LED를 토글시
키고, 실패 시에는 report_problem() 함수를 호출하
여 적색LED를 토글시킨다.
83~91: 데이터 전송이 완료되면 Read.readDone
이벤트 함수가 호출되고 ADC값을 local구조체의
readings 필드에 입력한다. 그런 후 report_received()
함수를 호출하여 황색 LED를 토글시킨다.
Ubiquitous Computing
BaseStation
BaseStation



13
경로 /opt/tinyos-2.x/contrib/zigbex/BaseStation/
무선으로 받은 데이터는 시리얼로 전송
시리얼로 받은 데이터는 무선으로 전송
Ubiquitous Computing
Group Id


Broadcast 전송이므로 다른 조의 AM_OSCILLOSCOPE
타입의 패킷이 나의 BaseStation으로 전송 가능
Makefile에 다음 줄을 추가 후 컴파일
CFLAGS += -DDEFINED_TOS_AM_GROUP=0x22
그룹을 나눔으로써 그룹 아이디가 다를 경우 패킷이 CPU
쪽으로 올라오지 않도록 하는 방법이지만 RF채널을 변경한
것은 아니므로 충돌문제나 기타 성능향상은 되지 않음
14
Ubiquitous Computing
OscilloscopeUltraredRF 예제 실습
BaseStation 컴파일 및 포팅
$ cd /opt/tinyos-2.x/contrib/zigbex/BaseStation
$ make zigbex
OscilloscopeUltraredRF 컴파일 및 포팅
$ cd /opt/tinyos-2.x/contrib/zigbex/OscilloscopeUltraredRF
$ make zigbex
java program을 이용하여 데이터 확인
$ java net.tinyos.sf.SerialForwarder –comm serial@COMX:57600 &
$ cd java
$ make
$ ./run
15
Ubiquitous Computing
6. 기본 무선통신 프로토콜
MAC 프로토콜의 특징과 사용법을
실제 무선 송수신 예제를 통해 연습
Ubiquitous Computing
OSI 7계층





실제 서비스 구현
HTTP, SMTP, 채팅 프로그램
상호간의 접속이 이루어지도록 함
TCP, UDP
네트워크 라우팅, 흐름 제어
IP
신뢰성 있는 정보 수단 제공(에러 검출,
재전송, 충돌 회피)
연속적 비트 스트림 전송
Ubiquitous Computing
기본 지식
TinyOS의 기본 MAC 프로토콜


TinyOS에서는 무선 RF 칩 CC2420의 제어를 위해 CC2420Radio
컴포넌트를 제공하고 있으며, CC2420Radio 컴포넌트에는 TinyOS에서
사용되는 간단한 MAC 프로토콜도 함께 구현됨
앞에서 사용한 ActiveMessageC, AMSenderC, AMReceiverC 중
AMSenderC는 Queue를 가지고 CC2420ActiveMessageC 컴포넌트에게
전송할 데이터를 하나씩 처리하는 스케줄링 기능 지원
무선 MAC 형태
CSMA/CA 방식
반송파 감지
RSSI 기반의 CCA(Clear Channel Assessment :
RSSI 값이 일정 threshold 값 이상이면 전송안함)
랜덤 Backoff
MacBackoff 및 Random 컴포넌트 제공(데이터
전송 전에 [0,N] 숫자 중 하나를 랜덤 선택하여
그 시간만큼 기다린 후 전송)
재전송 기법
DATA/ACK 형태의 패킷 전송(DATA에 대한 ACK
가 오지 않으면 충돌으로 간주하고 재전송)
Ubiquitous Computing
BasicMAC.nc


1초마다 조도 센서로부터 측정값을 받은 후 그
내용을 RF 무선 통신을 위해 주변 노드에게 전달
내용 전달시 MAC 프로토콜에 근거하여 순서 정함
Ubiquitous Computing
BasicMAC.nc
configuration BasicMAC { }
implementation
{
components MainC, BasicMACM, new TimerMilliC(), LedsC
, new PhotoSensorC() as Photo, ActiveMessageC
, new AMSenderC(AM_BMACMSG), new AMReceiverC(AM_BMACMSG);
}
BasicMACM.Boot -> MainC;
BasicMACM.Packet ->ActiveMessageC;
BasicMACM.Timer -> TimerMilliC;
BasicMACM.Leds -> LedsC;
BasicMACM.Photo -> Photo;
BasicMACM.CommControl -> ActiveMessageC;
BasicMACM.RecvMsg -> AMReceiverC;
BasicMACM.DataMsg -> AMSenderC;
Ubiquitous Computing
BasicMACM.nc
BasicMACM.nc 파일

경로:
 /opt/tinyos-2.x/contrib/zigbex/BasicMAC/BasicMACM.nc

함수 실행순서
 Boot.booted() → SerialControl.start ()
 SerialControl.startDone () → startTimer ()
 startTimer () → Timer.startPeriodic ()
 반복
Timer.fired () → Read.read () → 조도값 측정 → Read.read
Done() → AMSend.send ()
Ubiquitous Computing
BasicMACM.nc
1: module BasicMACM
2: {
3: uses {
4:
interface Timer<TMilli>;
5:
interface Leds;
6:
interface Read<uint16_t> as Photo;
7:
interface SplitControl as CommControl;
8:
interface AMSend as DataMsg;
9:
interface Receive as RecvMsg;
10: interface Packet;
11: interface Boot;
12: }
13: }implementation{
14: struct BasicMAC_Msg *pack;
15: message_t sendmsg;
16: uint8_t recvNumber;
17: uint16_t seq_;
18: event void Boot.booted() {
19: call CommControl.start();
20: recvNumber = 0;
21: seq_ = 0;
22: }
18: Main 컴포넌트에 의해 먼저 시작되는
Boot.booted() 함수에서는 CommControl 인터페이
스를 start하고 이 예제에서 사용할 여러 변수들을
초기화한다.
Ubiquitous Computing
BasicMACM.nc
23: event void CommControl.startDone
(error_t error) {
24: call Timer.startPeriodic(1000);
25: }
26: event void CommControl.stopDone
(error_t error) {
27: }
23: RF의 초기화가 완료되면
CommControl.startDone( ) 이벤트 함수가 호출되면
1초마다 주기적인 동작을 수행하도록
Timer.startPeriodic(1000) 함수를 호출한다.
28: event void Photo.readDone
(error_t result,uint16_t data) {
29: if(result == SUCCESS){
30:
struct BasicMAC_Msg BasicMAC_M;
31:
BasicMAC_M.seq = seq_++;
32:
BasicMAC_M.TTL = Default_TTL;
33:
BasicMAC_M.SenderID = TOS_NODE_ID;
34:
BasicMAC_M.data[0] = data ;
35:
memcpy(call DataMsg.getPayload(
&sendmsg), (uint8_t *)&BasicMAC_M,
sizeof(struct BasicMAC_Msg));
36:
call Packet.setPayloadLength(&sendmsg,
sizeof(struct BasicMAC_Msg));
28: 조도 센서값의 측정이 끝나면 Photo.readDone( )
함수호출되고, 이 함수 내에서는 받은 조도 데이터를
BasicMAC_M 구조체 변수에 저장한다. 그리고
DataMsg.send(...) 함수를 통해 무선으로 해당 데이
터를 브로드 캐스팅(AM_BROADCAST_ADDR)한다.
하지만 AM_BROADCAST_ADDR 대신 특정 번호를
주소 필드에 기입하게 되면, 해당 번호를 아이디로
갖는 노드만 데이터를 받게 되는 유니캐스팅이 일어
난다.
Ubiquitous Computing
BasicMACM.nc
37:
if (call DataMsg.send(AM_BROADCAST_ADDR,
&sendmsg, call Packet.payloadLength
(&sendmsg)) == SUCCESS){
call Leds.led2On();
//Yellow On
}
38:
39:
40: }
41: }
42: event void DataMsg.sendDone(message_t*
msg, error_t error) {
43: if (error == SUCCESS){
44:
call Leds.led2Off();
//Yellow Off
45: }
46: }
47: event void Timer.fired() {
48: call Leds.led1Toggle();
//Green Toggle
49: call Photo.read();
50: }
51: event message_t* RecvMsg.receive
(message_t* msg, void* payload,
uint8_t len) {
52: call Leds.led0Toggle();
//Red Toggle
53: return msg;
54: }
55: }
47: Timer에 의해 1초마다 Timer.fired()가 호출되면,
Photo.read() 함수를 호출하여 ADC[0]에 있는 조도
센서값을 Photo 컴포넌트에게 요청한다.
51: 다른 노드로부터 무선 데이터를 받게 될 경우,
RecvMsg.receive (...) 함수가 호출된다. 프로그래머
는 받은 데이터의 처리를 위해, RecvMsg.receive (...)
함수 내에 기술하여 수신 프로그램을 작성할 수 있다.
Ubiquitous Computing
BMAC.h
BMAC.h 에 정의된 데이터 포멧
#define DATA_MAX 10
struct BasicMAC_Msg
{
uint16_t seq;
uint16_t TTL;
};
uint16_t SenderID;
uint16_t data[DATA_MAX];
//패킷 번호
//무한 루프를 방지하기 위한 값
(현재 예제에서는 사용 안됨)
//소스 노드의 address
//측정된 조도값
enum {
AM_BMACMSG = 10
};
Ubiquitous Computing
BasicMAC 예제 실습
BasicMAC 컴파일 및 포팅
$
$
$
$



cd /opt/tinyos-2.x/contrib/zigbex/BasicMAC
make zigbex
make zigbex reinstall.0
//0번 아이디
make zigbex reinstall.1
//1번 아이디
AVR Studio를 이용하여 두 개의 센서 노드에 각각
reinstall된 hex파일을 program 함.
두 개의 센서 노드의 전원을 on하게 되면 1초마다 Green
LED와 Yellow LED의 빛이 깜박 거리는 것을 확인
한쪽 Yellow LED가 순간 깜박 거릴 때 (데이터를 송신한
후), 다른 쪽 노드의 Red LED (송신된 데이터를 모두
수신한 후)가 on/off를 반복함을 확인
Ubiquitous Computing