ZigBee协调器向子节点发消息

本文介绍了在ZigBee网络中,子节点如何向协调器发送消息以及协调器如何回应。在固定拓扑结构的网络中,节点地址通常是预计算的,但实际项目开发中拓扑可能变化,因此更可靠的方法是子节点加入网络后立即通知协调器其地址。子节点通过定时发送包含自身地址和编号的消息给协调器,协调器据此建立地址对应表,以便后续通信。这种方法确保了网络动态性并简化了地址管理。
摘要由CSDN通过智能技术生成

  在一般的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类型的数组,存储了该节点的编号(人为编号)。这样当协调器收到这个数据包时,即可以知道这个节点的短地址(数据包中自带)和编号(来自数据包中的数据体)。协调器端知道了这个节点的短地址,接下来利用该地址就可以向这个节点发送数据了。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值