Zigbee广播通信就是网络内的任何一个节点设备发送出广播数据,网络中的任何设备都可以接收到所发送的数据。
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
附
Zstack协议栈的广播地址 主要有三种类型:
(1)0xFFFF——数据包将被发送到网络内的所有设备,包括睡眠中的设备。对于睡眠中的设备,数据包将被保存在其父亲节点直到被查询到或者信息超时;
(2)0xFFFD——数据包被传送到网络内所有在空闲时打开接收器的设备( RxOnWhenIdle),即除了睡眠中的所有设备;
(3)0xFFFC——数据包发送给所有的路由器,包括协调器。
2.广播发送函数
协议栈已完成广播发送函数的实现,位于SampleApp.c文件中,找到该函数并添加要发送的信息:
void SampleApp_SendPeriodicMessage( void )
{
uint8 data[29]={"This is a broadcast message!"};//待发送的数据
if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
29,
//(uint8*)&SampleAppPeriodicCounter,
data,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
在函数uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
中调用广播发送函数
if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )
{
// Send the periodic message
SampleApp_SendPeriodicMessage();//周期广播发送函数
// 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.数据接收函数
默认接收ID就是SAMPLEAPP_PERIODIC_CLUSTERID,在函数void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
中接收广播信息并打印到串口:
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
//uint16 flashTime;
switch ( pkt->clusterId )
{
case SAMPLEAPP_PERIODIC_CLUSTERID:
HalUARTWrite(0,"Broadcast Message:",18);
HalUARTWrite(0,pkt->cmd.Data,pkt->cmd.DataLength);//打印收到的数据
HalUARTWrite(0,"\n",1);//换行
break;
case SAMPLEAPP_POINTTOPOINT_CLUSTERID:
HalUARTWrite(0,"Point_To_Point Communication:",29);
//此处直接填所发数据的长度,使用sizeof会导致显示串口工具显示的数据正常
HalUARTWrite(0,pkt->cmd.Data,pkt->cmd.DataLength);//打印收到的数据
//HalUARTWrite(0,&pkt->cmd.Data[0],10);//打印收到的数据,两种方式二选一
HalUARTWrite(0,"\n",1);//换行
break;
case SAMPLEAPP_FLASH_CLUSTERID:
HalUARTWrite(0,"Group Message:",14);//提示信息
HalUARTWrite(0,pkt->cmd.Data,pkt->cmd.DataLength);//打印接收到的数组
HalUARTWrite(0,"\n",1);//回车换行
//flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
//HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
break;
}
}
4.下载程序,查看实验结果
将程序分别以协调器、路由器、中断三种方式下载到3个节点设备中,节点设备通过串口与PC相连。
注如果之前的实验注释了协调器的周期性事件,请恢复过来,否则节点设备收不到信息。
在函数uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
中:
case ZDO_STATE_CHANGE:
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 );
}