270 likes | 503 Views
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 무선통신을 통해 다른 노드에 전송. 적외선 센서 BS520. 적외선 센서 BS520
E N D
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 무선통신을 통해 다른 노드에 전송 Ubiquitous Computing
적외선 센서 BS520 • 적외선 센서 BS520 • 적외선 센서인 BS520은 ATmega128의 ADC1과 연결되어 있다. • 적외선의 강약에 따라 BS520의 출력 AD가 변화하기 때문에, ADC1로 들어오는 전류 변화량에 따라 적외선 값을 측정할 수 있다. Ubiquitous Computing
OscilloscopeUltraredRF 예제의 구성도 무선통신 • 1번 노드 – 256ms 마다 측정한 Photo 값을 10번 모아 RF 무선통신을 통해 주위에 broadcast • 0번 노드 – RF 데이터를 수신하여 serial 전송 시리얼케이블 ZigbeX 1 ZigbeX 0 OscilloscopeUltraRF BaseStation Ubiquitous Computing
OscilloscopeUltraredRF 예제의 구성 • RF 로 전송하기 위해 필요한 컴포넌트 • 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 (error_t error) { 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. 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
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
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 컴포넌트에게 전송할 데이터를 하나씩 처리하는 스케줄링 기능 지원 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: } 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)); 23: RF의 초기화가 완료되면 CommControl.startDone( ) 이벤트 함수가 호출되면 1초마다 주기적인 동작을 수행하도록 Timer.startPeriodic(1000) 함수를 호출한다. 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){ 38: call Leds.led2On(); //Yellow On 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; //소스 노드의 address uint16_t data[DATA_MAX]; //측정된 조도값 }; enum { AM_BMACMSG = 10 }; Ubiquitous Computing
BasicMAC 예제 실습 • BasicMAC 컴파일 및 포팅 • AVR Studio를 이용하여 두 개의 센서 노드에 각각 reinstall된 hex파일을 program 함. • 두 개의 센서 노드의 전원을 on하게 되면 1초마다 Green LED와 Yellow LED의 빛이 깜박 거리는 것을 확인 • 한쪽 Yellow LED가 순간 깜박 거릴 때 (데이터를 송신한 후), 다른 쪽 노드의 Red LED (송신된 데이터를 모두 수신한 후)가 on/off를 반복함을 확인 $ cd /opt/tinyos-2.x/contrib/zigbex/BasicMAC $ make zigbex $ make zigbex reinstall.0 //0번 아이디 $ make zigbex reinstall.1 //1번 아이디 Ubiquitous Computing