概述
在一般的ZigBee
教程中,子节点如何向协调器发送消息已经被描述得非常清楚了,即子节点直接使用API
向地址为0x0000
的协调器发送消息即可。用到的函数如下:
afStatus_t AF_DataRequest (
afAddrType_t *dstAddr,
endPointDesc_t *srcEP,
uint16 cID,
uint16 len,
uint8 *buf,
uint8 *transID,
uint8 options,
uint8 radius
);
参数dstAddr
即为目标节点的地址。例如做一个点对点的通信实验,向协调器发数据,则dstAddr
应该这样实例化:
afAddrType_t Point_To_Point_DstAddr; /* 点对点通信 */
Point_To_Point_DstAddr.addrMode = ( afAddrMode_t ) afAddr16Bit; /* 点播 */
Point_To_Point_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
Point_To_Point_DstAddr.addr.shortAddr = 0x0000; /* 发送给协调器,0x0000是协调器的地址 */
要使协调器向子节点发送数据,只需要知道子节点的地址即可。在许多深入讲解ZigBee
通信协议的书中,对ZigBee
网络节点的地址分配机制都做了详细的介绍,依据一些公式和描述该网络拓扑结构的参数可以计算出每个节点的地址。这也就似乎意味着如果一个网络拓扑结构固定的ZigBee
网络,则其节点的地址也是固定的,可以通过事先计算将节点地址算出来,再进行通信。但是在项目开发阶段,我们很难做到固定拓扑结构,而且这需要修改ZigBee
协议栈中关于网络拓扑结构类型的预先定义。所以比较可靠的方法是:当ZigBee
子节点加入网络后的第一时间,立即向协调器发送一条消息,告诉协调器它的地址及认为给它加上的编号。这样协调器端则会形成一个编号和短地址的对应表,协调器根据这张表向相应的子节点发送数据。
具体实现过程可以是这样的:在子节点端的SampleApp_ProcessEvent
函数中,在处理节点网络状态改变的分支位置开启一个定时器,在处理定时器计时完成的代码中向协调器发送该节点的短地址:
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, SEND_ADDR_MSG_EVT, SEND_ADDR_STEP_TIMEOUT );
} else {
/* Device is no longer in the network */
}
break;
在处理SEND_ADDR_MSG_EVT
事件中,可以这样做:
if ( events &SEND_ADDR_MSG_EVT ) {
HalUARTWrite ( 0, "开始发送", 4 );
if ( AF_DataRequest (
&Point_To_Point_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_POINT_TO_POINT_CLUSTERID,
4,
sendAddr,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) {
HalUARTWrite ( 0, "成功发送", 4 );
} else {
HalUARTWrite ( 0, "发送失败", 4 );
}
}
sendAddr
为一个uint8
类型的数组,存储了该节点的编号(人为编号)。这样当协调器收到这个数据包时,即可以知道这个节点的短地址(数据包中自带)和编号(来自数据包中的数据体)。协调器端知道了这个节点的短地址,接下来利用该地址就可以向这个节点发送数据了。
最后
以上就是傻傻紫菜为你收集整理的ZigBee协调器向子节点发消息的全部内容,希望文章能够帮你解决ZigBee协调器向子节点发消息所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复