一、zigbee四种通讯
1、单播(略)
2、广播(略)
3、组播:在zigbee网络中,模块可以用分组来标记,发送的模块如果发送的组号和网络里面标记接收模块的组号相对应,那么这些模块就可以拿到这些无线数据包(组播通信与广播通信相似,单个发送设备可以同时向多个接收设备发送数据)。
4、绑定(略)
二、组播相关概念
1、分组中的组编号占用2个字节。例如:0x0001。
2、组编号是和模块里已经定义了的端点相关联,即如果一个模块被标记为组1,那么这个模块里至少有1个定义了的可用端点和组0x0001相关联。
3、发送模块按照组的方式发送数据时,需要指定的内容包含 目标模块的组标号、端点和簇,原则上只有当接收模块的这3个参数匹配上了,才能拿到和处理这样一个无线数据包。
例如:发送模块A发送了一个无线数据包,无线数据包中指定了接收者要满足:组号为0x0001、端点号为10、簇为0x0001,因此通过判断只有模块B的10号端点最终成功接收到了数据包。
4、组标记中,同一个模块定义的一个组编号可以关联多个可用的端点(一个组标记可以使使用多个端点),同一个端点也可以关联多个组编号(即一个模块可以同时是组1和组2的模块,同属于2个组)。
三、组播实验
1、发送端数据发送设置
(1)例如发送数据:组编号号为0x0001,端点号10,簇为0x0001,内容是“Hello world”
char theMessageData[] = "Hello World"; //定义发送内容
smartHomeApp_DstAddr.addrMode = (afAddrMode_t)AddrGroup; //指定发送模式,组播模式
/*
enum
{
AddrNotPresent = 0,
AddrGroup = 1,
Addr16Bit = 2,
Addr64Bit = 3,
AddrBroadcast = 15
};
*/
smartHomeApp_DstAddr.addr.shortAddr = 0x000; //组播模式下,该参数表示为组编号
smartHomeApp_DstAddr.endPoint = 10; //指定接收模块端点号
//smartHomeApp_DstAddr结构体无论是在单播、广播还是组播中都是用来指定描述接收模块的一些信息
AF_DataRequest( &smartHomeApp_DstAddr, &smartHomeApp_epDesc,
smartHomeApp_CLUSTERID, //指定接收模块的簇
(byte)osal_strlen( theMessageData ) + 1, //表示发送字节个数
// 1,
(byte *)&theMessageData,//发送的数组的首地址
&smartHomeApp_TransID,
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );
2、接收模块设置
在应用层初始化函数中默认挂钩了端点号10,同样簇的编号也被默认定义了0x0001,我们也不需要动。
(1) 组播通信中接收模块需要关联组
标记组的话,首先要定义一个组的结构体变量aps_Group_t smartHomeApp_Group;组的结构体和相关函数可以在aps_groups.h中找到。因此我们需要在应用处理函数所在源文件中引入aps_groups.h头文件,如下图。
(2)关联端点与组编号
首先定义组结构体,给组结构体的第一个成员变量ID赋值为组编号0x0001(第二个参数name可以不用,name的作用就相当于一个注释,给组起个别名,最多不能超过16个字节)。
然后我们调用函数ZStatus_t aps_AddGroup( uint8 endpoint, aps_Group_t *group );(也在组头文件中有声明),它的作用是将我们的端点与组关联起来。(第一个参数为关联的端点号,第二个参数是组结构体的地址)。
在关联之前我们还需要调用函数extern uint8 aps_RemoveGroup( uint8 endpoint, uint16 groupID );,它的作用时去除当前端点所关联的组编号。来确保只有一个组与我们的10号端点关联。(第一个参数是我们要取消关联的端点,第二个参数是取消关联的组号)。
//...
aps_Group_t smartHomeApp_Group;//定义一个组相关结构体
smartHomeApp_Group.ID=0x0001;//组相关结构体的ID值赋0x0001
aps_RemoveGroup(10,0x0002);//如果10号端点关联了0x0002,那么就取消组2的关联;如果没有关联,就不做处理。
//aps_RemoveGroup(uint8 endpoint, uint16 groupID )函数用来解端点与组的关联
StarryApp_Group.ID=0x0001;
aps_AddGroup(10,&smartHomeApp_Group);//将端点与组关联起来。(第一个参数为关联的端点号,第二个参数是组结构体的地址)
//...
/*
其他组相关函数
// Remove all groups for endpoint
extern void aps_RemoveAllGroup( uint8 endpoint );
更多组相关函数参考头文件aps_groups.h
*/
(3)数据接收
消息处理函数要修改成适合组播的接收处理程序,其中pkt结构体变量的groupId成员,如果为0,表示收到的数据包不是通过组播发送的,而是通过单播或者广播等。
static void smartHomeApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
if(pkt->groupId==0x0001)
{
if(pkt->endPoint==10)
{
switch(pkt->clusterId)
{
case 0x0001:
//... 处理内容代码
break;
}
}
}
if(pkt->groupId==0x0002)
{
if(pkt->endPoint==10)
{
switch(pkt->clusterId)
{
case 0x0001:
//... 处理内容代码
break;
}
}
}
}
参考链接
(1)lesson10组播通信原理_哔哩哔哩_bilibili
(2)lesson10 Zigbee组播通信原理-CSDN博客