ZigBee协调器部分
协调器作为本项目的一个中转站,不需要像终端样采集数据,控制设备,只需将终端发送过来的数据转播给8266,同样将8266发过来的命令转播给终端即可。
我们还是先进入SampleApp_Init
// 网蜂点对点通讯定义
Point_To_Point_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;//点播
Point_To_Point_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
//Point_To_Point_DstAddr.addr.shortAddr = 0x0000; //发给协调器
由于要发给终端,所以短地址就不一样了,我们这里先注释,之后来获取终端的短地址。
接下来看到case ZDO_STATE_CHANGE:
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) )
去掉第三行的注释,打开点播功能。
然后我们跳到void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )这个函数中
这个函数在收到终端发过来的点播数据时会进入,在这里我们需要获取发过来终端的短地址
case SAMPLEAPP_POINT_TO_POINT_CLUSTERID:
if ((pkt->cmd.Data[0] == '@') && (pkt->cmd.Data[1] == 'A'))
{
shortAddr_A = pkt->srcAddr.addr.shortAddr;
HalUARTWrite(0,&pkt->cmd.Data[0],strlen(pkt->cmd.Data)-1); //温度
}
else if ((pkt->cmd.Data[0] == '@') && (pkt->cmd.Data[1] == 'B'))
{
shortAddr_B = pkt->srcAddr.addr.shortAddr;
HalUARTWrite(0,&pkt->cmd.Data[0],strlen(pkt->cmd.Data)-1); //温度
}
break;
在开头时定义了一个全局变量shortAddr_A,shortAddr_B,用来存放终端的短地址的。收到点播数据时,对方的短地址会存在pkt->srcAddr.addr.shortAddr,所以从中读出来可以了,要注意的是,短地址不是固定不变的,每次重新连接都会变化。收到后就将终端发送过来的数据通过串口转播给8266,因为点播过来的值最后总有一个!所以我最后一位没有发送。
将终端发送过来的数据转发出去已经完成了,接下里只要将esp8266发送过来得命令点播至终端就可以了。
此时我们需要添加串口,大家可以直接参考网蜂的例程串口透传,移植过来就可以了,不然串口是无法用的。然后再在事件中添加以下内容。
case CMD_SERIAL_MSG:
SampleApp_SerialCMD((mtOSALSerialData_t *)MSGpkt);
break;
当串口收到数据时,就会跳入到 SampleApp_SerialCMD((mtOSALSerialData_t *)MSGpkt)中。
void SampleApp_SerialCMD(mtOSALSerialData_t *cmdMsg)
{
uint8 i,len,*str=NULL; //len 有用数据长度
str=cmdMsg->msg; //指向数据开头
len=*str; //msg 里的第 1 个字节代表后面的数据长度
/********打印出串口接收到的数据,用于提示*********/
/* HalUARTWrite(0,str,1);
HalUARTWrite(0,"\n",1);
HalUARTWrite(0,str+1,strlen(str+1));
HalUARTWrite(0,"\n",1);*/
Point_To_Point_DstAddr.addr.shortAddr = shortAddr_A;
if ( AF_DataRequest( &Point_To_Point_DstAddr,
&SampleApp_epDesc,
SAMPLEAPP_POINT_TO_POINT_CLUSTERID,
len,
str+1,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
Point_To_Point_DstAddr.addr.shortAddr = shortAddr_B;
if ( AF_DataRequest( &Point_To_Point_DstAddr,
&SampleApp_epDesc,
SAMPLEAPP_POINT_TO_POINT_CLUSTERID,
len,
str+1,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
收到串口数据再利用点播转发给终端就行了,这里我只用了两个终端,所以就直接依次转发了,各位小伙伴们也可以判断一下再转发。
然后这里补充一个重点,博主在调试时,因为8266那边的波特率是9600,所以将协调器也设置成了9600,没想到就一直有个BUG,后来调试才发现,9600的波特率发给协调器时,数据过长的话协调器一次接受不完,所以这里要设成115200才可以。
大家可以直接不连8266试一下,将协调器和终端上电,协调器就会收到以下数据了。