ZigBee開發(15)--組網實驗點播
/***考試周,我抓緊把ZigBee的記錄補一下,其實早就做了,被學院的事情耽擱了,部落格一直沒寫,這兩天給他補上************/
前言: Zigbee 的通訊方式主要有三種點播、組播、廣播。點播,顧名思義就是點對點通訊,也就是 2 個裝置之間的通訊,不容許有第三個裝置收到資訊;組播,就是把網路中的節點分組,每一個組員發出的資訊只有相同組號的組員才能收到。廣播,最廣泛的也就是 1 個裝置上發出的資訊所有裝置都能接收到。這也是 ZigBee 通訊的基本方式。
點播(點對點通訊)
點播描述的就是網路中 2 個節點相互通訊的過程。確定通訊物件的就是節點的 16bit 短地址。
首先,在AF.H檔案中,可以看到這段程式碼
1 typedef enum 2 { 3 afAddrNotPresent = AddrNotPresent, 4 afAddr16Bit = Addr16Bit, 5 afAddr64Bit = Addr64Bit, 6 afAddrGroup = AddrGroup, 7 afAddrBroadcast = AddrBroadcast 8 } afAddrMode_t;
該型別是一個列舉型別:
當 addrMode= Addr16Bit 時,對應點播方式;
當 addrMode= AddrGroup 時,對應組播方式;
當 addrMode= AddrBroadcast 時,對應廣播方式;
開啟SampleApp.c加入點對點通訊定義
afAddrType_t Point_To_Point_DstAddr;//點對點通訊定義 //go to definition of afAddrType_t 可以找到剛才的列舉內容
對 Point_To_Point_DstAddr 一些引數進行配置 加入如下程式碼
// 點對點通訊定義 Point_To_Point_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;//點播 Point_To_Point_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; Point_To_Point_DstAddr.addr.shortAddr= 0x0000; //發給協調器
第三行的意思是點播的傳送物件是 0x0000,也就是協調器的地址。節點和協調器點對點通訊。
新增自己的點對點發送函式,在 SampleAPP.c 最後加入下面程式碼
void SampleApp_SendPointToPointMessage( void ) { uint8 data[]="Hello Tian!"; if ( AF_DataRequest( &Point_To_Point_DstAddr, &SampleApp_epDesc, SAMPLEAPP_POINT_TO_POINT_CLUSTERID, sizeof(data), data, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) { } else { // Error occurred in request to send. } }
/***********************新增完之後記得在SampleApp.c檔案開頭新增函式宣告****************/
加入 SAMPLEAPP_POINT_TO_POINT_CLUSTERID 的定義如所示:
#define SAMPLEAPP_POINT_TO_POINT_CLUSTERID 3//傳輸編號
新增接收函式
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) { uint16 flashTime; switch ( pkt->clusterId ) { case SAMPLEAPP_POINT_TO_POINT_CLUSTERID: HalUARTWrite(0,"I get data\n",11);//用於提示有資料 HalUARTWrite(0, &pkt->cmd.Data[0],10); //列印收到資料 HalUARTWrite(0,"\n",1); //回車換行,便於觀察 break; case SAMPLEAPP_FLASH_CLUSTERID: flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] ); HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) ); break; } }
註冊週期傳送事件
SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status); if ( //(SampleApp_NwkState == DEV_ZB_COORD)|| //協調器不給自己點播 (SampleApp_NwkState == DEV_ROUTER) || (SampleApp_NwkState == DEV_END_DEVICE) ) { // Start sending the periodic message in a regular interval. osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT ); } else { // Device is no longer in the network } /*由於協調器不允許給自己點播,故週期性點播初始化時協調器不能初始化*/
if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) { SampleApp_SendPointToPointMessage();//週期性傳送函式 // Setup to send message again in normal period (+ a little jitter) osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) ); // return unprocessed events return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT); }
將修改後的程式分別以協調器、路由器、終端的方式下載到 3 個節點裝置中,連線串列埠。可以看到只有協調器在一個週期內收到資訊。也就是說路由器和終端均與地址為 0x00(協調器)的裝置通訊,不與其他裝置通訊。實現點對點傳輸。