zoukankan      html  css  js  c++  java
  • 「ZigBee模块」网络通讯实验-点播、组播、广播


    点播、组播、广播

    一、基础知识补充

      Zigbee的通信方式主要有三种:点播、组播、广播。

      点播就是点对点通信,也就是两个设备之间的通信,不允许第三个设备收到信息。

      组播就是把网络中的节点分组,每一个组员发出的信息只有相同组号的组员才能收到。

      广播,最广泛的就是1个设备上发出的信息所以设备都能接收到。 

    二、点播实验步骤

      因为要将收到的数据通过串口显示在屏幕上,所以在程序开始之前先把串口初始化吧~设置波特率和关闭流控不要忘记!完成后就开始点播实验吧~

    1. 打开AF.h,找到图1所示代码段。该类型是枚举类型。

     

    图1

      我们需要知道的是Addr16Bit表示点播,AddrGroup表示组播,AddrBroadcast表示广播。

      打开SampleApp.c声明一个结构体变量(如图2

    afAddrType_t Point_To_Point_DstAddr;

     

    图2

      这个是点对点通信的定义。查看afAddrType_t的定义就可以知道其中包含哪些内容。这个结构体是用于选择你将要进行哪种方式的通信。在后面发送数据的函数中会用到。

      2. 声明了结构体变量就要对其进行初始化对吧?初始化的代码一般都写在初始化函数SampleApp_Init()中。我们现在来对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 = 0x00; //发送给协调器

     

    图3

      注意最后一个值是0x0000,这个是协调器的地址,这样配置我们就可以确保只发送给协调器啦。如图3我们还可以看到另外两个同结构体类型的初始化配置。它们的通信方式分别是广播和组播。广播的发送地址是0xFFFF,这个是指发送给全部的设备。组播的发送地址从变量名就可以看出是发送给同一组内成员哒。 

      3. 在SampleApp.c下添加自己的点对点发送函数。

     1 void SampleApp_SendPointToPointMessage(void)
     2 
     3 {
     4 
     5   uint8 data[10] = {‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’};
     6 
     7   if ( AF_DataRequest( &Point_To_Point_DstAddr, &SampleApp_epDesc,
     8 
     9                        SAMPLEAPP_POINT_TO_POINT_CLUSTERID,
    10 
    11                        10,
    12 
    13                        &data[0],
    14 
    15                        &SampleApp_TransID,
    16 
    17                        AF_DISCV_ROUTE,
    18 
    19                        AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
    20 
    21   {
    22 
    23   }
    24 
    25   else
    26 
    27   {
    28 
    29     // Error occurred in request to send.
    30 
    31   }
    32 
    33 }
    SampleApp_SendPointToPointMessage

      这个格式应该看着挺熟悉了吧,之前好几次有涉及过,这里就不解释啦。就注意一点,函数的传递参数没有的话要加void,不然可能会报错哦。

      函数写好了不要忘记在文件开头加上函数声明呢,不然程序会找不到...... 

      4. 刚才写的函数不知道你们有没有仔细看,其实里面有一个参数是还没有定义过的哦。就是SAMPLEAPP_POINT_TO_POINT_CLUSTERID啦。这个类型的参数应该也挺眼熟的吧......打开SampleApp.h,找到它们的同类,在后面加上一句:

    #define SAMPLEAPP_FLASH_CLUSTERID    3

      同时不要忘了把SAMPLEAPP_MAX_CLUSTERS的值改3

     

    图4

      5. 写完发送函数就要把它用上!找到事件处理函数SampleApp_ProcessEvent();找到里面的if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )语句(因为我们要周期性发送数据,所以就选它啦),发现里面已经有一个广播的发送函数啦。我们要做的就是用点播的函数把它替换掉!(如图5

     

    图5

      这样我们就可以实现周期性点播发送函数啦。

      6. 发送处理完就要考虑接收啦。在SampleApp.c下找到发送函数SampleApp_MessageMSGCB();我们在其中把发送的代码写上,同时把广播发送的代码删除。(如图6

     

    图6

      7. 由于协调器不能给自己点播,我们需要在周期性点播初始化的地方把它注释掉。(如图7

     

    图7 

    三、点播实验结果

      将编译好的程序分别以协调器、路由器、终端的方式下载到3个节点设备中。连接串口后可以看到只有协调器收到了信息。

     

    图8 

    四、点播实验流程总结

     

    9 

    五、组播实验步骤

      一开始先串口初始化!

    1. 来看下SampleApp.c关于组播的定义。之前我们就知道组播afAddrType_t的类型变量已经定义好的了,变量名是SampleApp_Flash_DstAddr

      然后,注意看,该定义下面还有一行关于组播的代码

    aps_Group_t SampleApp_Group;

      这行代码是关于分组内容的。

     

    图10 

      2. 再看组播参数的配置。其实已经给我们配置好了。在同一个函数里面再往下看,可以看到有关于分组的配置。为了以后操作方便(其实我没觉得方便...),可以稍微修改一下。我们可以看到现在配置的分组ID0x0001,我们把这个改成SAMPLEAPP_FLASH_GROUP,这样以后该分组只要在SAMPLEAPP_FLASH_GROUP定义里面修改就可以了。看吧,其实没有方便......

     

    图11

      3. 然后我们就可以开始添加自己的组播发送函数啦。代码如下:

     1 void SampleApp_SendGroupMessage(void)
     2 
     3 {
     4 
     5   uint8 data[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
     6 
     7     if ( AF_DataRequest( &SampleApp_Flash_DstAddr, &SampleApp_epDesc,
     8 
     9                        SAMPLEAPP_FLASH_CLUSTERID,
    10 
    11                        10,
    12 
    13                        data,
    14 
    15                        &SampleApp_TransID,
    16 
    17                        AF_DISCV_ROUTE,
    18 
    19                        AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
    20 
    21   {
    22 
    23   }
    24 
    25   else
    26 
    27   {
    28 
    29     // Error occurred in request to send.
    30 
    31   }
    32 
    33 }
    SampleApp_SendGroupMessage

      这里对代码不再做解释啦(我懒...),也不需要再加定义什么的,就是不要忘了在文件开头加上函数声明。

      4. 把事件处理函数里面原有的组播函数换成我们自己写的。(如图12

     

    图12

      5. 然后就到接收部分啦。在接收到组播信息部分,修改代码如下:

     1     case SAMPLEAPP_FLASH_CLUSTERID:
     2 
     3       HalUARTWrite(0, "I get data:", 11);
     4 
     5       HalUARTWrite(0, &pkt->cmd.Data[0], pkt->cmd.DataLength);
     6 
     7       HalUARTWrite(0, "
    ", 1);
     8 
     9       //flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
    10 
    11       //HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
    12 
    13       break;

    图13

    六、组播实验结果

      程序分别下载到一个协调器,两个路由器。其中协调器和路由器1组号为0x0001,路由器2组号为0x0002。(如图14

     

    图14

      连接串口,可以看到只有协调器和路由器1相互发送信息。

     七、广播实验步骤

      广播实验就更方便了......不过还是要初始化串口!

    1. 看到广播参数的配置
      // Setup for the periodic message's destination address
    
      // Broadcast to everyone
    
      SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;
    
      SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
    
      SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;

      0xFFFF是广播地址

      广播地址有3种类型:

      0xFFFF——数据包将被传送到网络上的所以设备

      0xFFFD——数据包将被传送到网络上的所有在空闲时打开接收的设备,即除睡眠中的所以设备

      0xFFFC——数据包发送给所有的路由器,包括协调器 

      2. 找到自带广播发送函数,修改代码如下:

    void SampleApp_SendPeriodicMessage( void )
    
    {
    
      uint8 data[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
    
      if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
    
                           SAMPLEAPP_PERIODIC_CLUSTERID,
    
                           10,
    
                           data,
    
                           &SampleApp_TransID,
    
                           AF_DISCV_ROUTE,
    
                           AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
    
      {
    
      }
    
      else
    
      {
    
        // Error occurred in request to send.
    
      }
    
    }
    SampleApp_SendPeriodicMessage

      3. 修改接收的代码:

    1     case SAMPLEAPP_PERIODIC_CLUSTERID:
    2 
    3       HalUARTWrite(0, "I get data:", 11);
    4 
    5       HalUARTWrite(0, &pkt->cmd.Data[0], pkt->cmd.DataLength);
    6 
    7       HalUARTWrite(0, "
    ", 1);
    8 
    9       break;

    八、广播实验结果

      把程序分别下载到协调器、路由器、终端。可以看到各个设备都在广播发送信息,同时接收广播信息。

  • 相关阅读:
    WPF Caliburn 学习笔记(五)HelloCaliburn
    MSDN 教程短片 WPF 20(绑定3ObjectDataProvider)
    MSDN 教程短片 WPF 23(3D动画)
    比赛总结一
    HDU3686 Traffic Real Time Query System
    HDU3954 Level up
    EOJ382 Match Maker
    UESTC1565 Smart Typist
    HDU3578 Greedy Tino
    ZOJ1975 The Sierpinski Fractal
  • 原文地址:https://www.cnblogs.com/Donut/p/4145382.html
Copyright © 2011-2022 走看看