基本定义及特点
- 组播通信:在ZigBee网络中,模块可以分组来标记,发送的模块如果发送的组号和网络里标记模块的组号相对应,那么这些模块就可以拿到这些数据包。
- 分组中组的编号为2个字节。
- 特点:
a. 组都是和已经定义的端点相关联,如果说我们定义一个模块标记为组1,那么这个模块里至少有1个定义了的可用的端点和组0x0001相关联。( 定义了组号,在模块应用层中至少要有一个端点相关联。)
b. (接收模块):需要组号,端点号,接收簇编号;(组号和端点号 相互还要一定关联)
c. (发送模块)按照组的方式发送,需要指定内容:需要目标模块组编号,端点号,目标簇编号;(组号和端点号 相互还要一定关联),原则上只有当接收模块的这三个参数匹配上,才能拿到和处理这个的一个无线数据包。
d. 同一个组可以关联多个断点号,同一个端点号可以关联多个组编号。
实现功能
发送模块:(终端)
- 按键1 —>发送(组编号 0x0001 端点号 10 簇0x0001 数据内容是8)
- 按键2 —>发送(组编号 0x0002 端点号 10 簇0x0001 数据内容是8)
接收模块: (协调器、路由器) - 挂钩定义10号端点,簇0x0001
- 按键1 在端点10号 只关联组0x0001
- 按键2 在端点10号 只关联组0x0002
- 按键3 同时端点10号同时关联组0x0001、0x0002到端点10
具体效果
- 当接收模块没有按键按下,发送模块按键按下,接收模块都接收不到信息。
- 当接收模块按下按键1后,发送模块按下按键1后 接收端 会收到信息(通过串口打印),按下按键2时接收不会收到信息。
- 当接收模块按下按键2后,发送模块按下按键2后 接收端 会收到信息(通过串口打印),按下按键1时接收不会收到信息。
- 当接收模块按下按键3后,发送模块按下按键1、2后 接收端都会收到信息。
ZStack协议代码移植、修改
注:LEDApp_DstAddr
结构体,无论是单播 广播 组播都用来描述接收模块的一些信息。
- 发送模块 (终端)
if ( events & LEDApp_MY_EVT )
{
if(P0_4 == 0)//S5
{
char theMessageData[] = "KEY1按下\n";
LED02 =~LED02;//
LEDApp_DstAddr.addrMode = (afAddrMode_t)AddrGroup;//发送模式是组播的方式
LEDApp_DstAddr.addr.shortAddr = 0x0001;//目标接收模块组编号
// Take the first endpoint, Can be changed to search through endpoints
LEDApp_DstAddr.endPoint = 10;//接收模块的端点号
//LEDApp_epDesc结构体 端点描述符有源端点的信息,延时10
//发送 (byte)osal_strlen( theMessageData ) + 1表示发送的字节
AF_DataRequest( &LEDApp_DstAddr, &LEDApp_epDesc,
0x0001,//目标端点簇编号,房间的连接端点数据宏是1,2个字节,所以在射频是0x0001
(byte)osal_strlen( theMessageData ) + 1,//发送字符串的长度
(byte *)&theMessageData,//字符串内容数组的首地址
&LEDApp_TransID,//记录我们应用层任务发送的数据包个数
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );
}
if(P0_5 == 0)//S5
{
char theMessageData[] = "KEY1按下\n";
LED02 =~LED02;//
LEDApp_DstAddr.addrMode = (afAddrMode_t)AddrGroup;//发送模式是组播的方式
LEDApp_DstAddr.addr.shortAddr = 0x0002;//目标接收模块组编号
// Take the first endpoint, Can be changed to search through endpoints
LEDApp_DstAddr.endPoint = 10;//接收模块的端点号
//LEDApp_epDesc结构体 端点描述符有源端点的信息,延时10
//发送 (byte)osal_strlen( theMessageData ) + 1表示发送的字节
AF_DataRequest( &LEDApp_DstAddr, &LEDApp_epDesc,
0x0001,//目标端点簇编号,房间的连接端点数据宏是1,2个字节,所以在射频是0x0001
(byte)osal_strlen( theMessageData ) + 1,//发送字符串的长度
(byte *)&theMessageData,//字符串内容数组的首地址
&LEDApp_TransID,//记录我们应用层任务发送的数据包个数
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );
}
// P0_1 =~P0_1;//led2
P0IFG = 0;
P0IF = 0;
return (events ^ LEDApp_MY_EVT);
}
- 接收模块
a.协调器
按键处理函数
声明#include "aps_groups.h"
,用到了aps_Group_t结构体。
定义全局变量:aps_Group_t SampieApp_Group1;aps_Group_t SampieApp_Group2;
if ( events & LEDApp_MY_EVT )
{
if(P0_4 == 0)//S1
{
LED01 =~LED01;
aps_RemoveGroup(10,0x0002);//取消10号端口与0x0002组的关联
SampieApp_Group1.ID = 0X0001;
aps_AddGroup(10,&SampieApp_Group1);//完成10号端口与0x0001组的关联
}
if(P0_5 == 0)//S2
{
LED02 =~LED02;
aps_RemoveGroup(10,0x0001);//取消10号端口与0x0001组的关联
SampieApp_Group2.ID = 0X0002;
aps_AddGroup(10,&SampieApp_Group2);//完成10号端口与0x0002组的关联
}
if(P0_6 == 0)//S3
{
LED03 =~LED03;
aps_RemoveAllGroup(10);//取消10号端口所有组的关联
SampieApp_Group1.ID = 0X0001;
aps_AddGroup(10,&SampieApp_Group1);//完成10号端口与0x0001组的关联
SampieApp_Group2.ID = 0X0002;
aps_AddGroup(10,&SampieApp_Group2);//完成10号端口与0x0002组的关联
}
P0IFG = 0;
P0IF = 0;
return (events ^ LEDApp_MY_EVT);
}
接收处理函数
static void LEDApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
if((pkt->groupId)==0x0001)//组
{
if((pkt->endPoint)== 10)//端口号
{
switch(pkt->clusterId)//簇
{
case 0x0001: UartTX_Send_String( pkt->cmd.Data,pkt->cmd.DataLength);
LED01 =~LED01;
break;
}
}
}
if((pkt->groupId)==0x0002)//组
{
if((pkt->endPoint)== 10)//端口号
{
switch(pkt->clusterId)//簇
{
case 0x0001: UartTX_Send_String( pkt->cmd.Data,pkt->cmd.DataLength);
LED02 =~LED02;
break;
}
}
}
}
b.路由器(同样作为接收就和协调器代码一样)