1. 程式人生 > >ZigBee開發(15)--組網實驗點播

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(協調器)的裝置通訊,不與其他裝置通訊。實現點對點傳輸。