通过串口来修改协调器的信道,从而去修改网络中所有设备的信道,包括路由和终端。
现在问题是:协调器修改信道成功后,所有终端都能随之切换信道并加入网络。
1。但网络中有路由时候,协调器切换信道后,路由和终端就不能随其切换信道,还在原来的信道中。是不是路由器维持了原来的网络导致终端不能切换信道了?
2。没有路由时候,协调器切换信道后,终端能随之切换并加入网络,是不是终端重新寻找网络的结果,而不是协调器吧修改的信道值通知了终端?
若要是想通过协调器修改信道后,其网络中的所有设备都随之修改信道并加入网络,该怎么弄呢?
修改信道是下面代码吗?好像没有通知其他设备啊
// Components\stack\zdo\ZDNwkMgr.c
if ( events & ZDNWKMGR_CHANNEL_CHANGE_EVT )
{
// Switch channel
_NIB.nwkLogicalChannel = ZDNwkMgr_NewChannel;
ZMacSetReq( ZMacChannel, &ZDNwkMgr_NewChannel );
// Our Channel has been changed — notify to save info into NV
ZDApp_NwkStateUpdateCB();
// Reset the total transmit count and the transmit failure counters
_NIB.nwkTotalTransmissions = 0;
nwkTransmissionFailures( TRUE );
return ( events ^ ZDNWKMGR_CHANNEL_CHANGE_EVT );
}
VV:
首先你要知道路由和终端设备在ZigBee网络里面的通信方式是不同的。
1)路由一旦入网以后,可以不依赖于父设备,自己完全可以维持正常的工作,即便协调器切换信道,还是父设备掉电
2)终端设备在入网以后,所有的通信都是依赖于父设备的。终端设备以一定的周期Poll Rate向父设备询问是否有数据需要接收
第一种场景,网络里面只有协调器和终端设备
协调在切换信道以后,终端还是以一定的周期Poll Rate去询问父设备,但是这个时候父设备(协调器)已经在其他信道了,当然收不到数据,所以终端设备会认为自己失去了父设备,而去找新的父设备,在找了若干次以后,会去其他信道找,这个时候就会找到,对应协议栈里面的代码实现如下,这个也是为什么你会看到终端设备也到新的信道上去了。
#if defined ( ZIGBEE_COMMISSIONING ) if (startMode == MODE_REJOIN && scanCnt++ >= 5 ) { // When ApsUseExtendedPanID is commissioned to a non zero value via // application specific means, the device shall conduct an active scan // on the Default Channel list and join the PAN with the same // ExtendedPanID. If the PAN is not found, an scan should be completed // on all channels. // When devices rejoin the network and the PAN is not found from zgDefaultChannelList = MAX_CHANNELS_24GHZ; } #endif // ZIGBEE_COMMISSIONING
第二种场景,网络里面有协调器,路由器,终端设备
按照第一种场景的解释,终端设备在失去父设备以后,会去找新的父设备,那么协调器在切换信道的情况下,但是路由器并没有切过去,因为路由器不知道,他完全可以自己维持工作,那么终端设备如果原先是协调器的子设备,这个时候就可以重新到网络里面的路由作为父设备,这个也是为什么你会看到第二种情况下,终端设备切换信道也不成功了。
所以最后的办法是,你需要通过发命令的方式让路由和终端切换到新的信道上去。
ZDP_MgmtNwkUpdateReq( zAddrType_t *dstAddr, uint32 ChannelMask, uint8 ScanDuration, uint8 ScanCount, uint8 NwkUpdateId, uint16 NwkManagerAddr )
user4381970:
回复 VV:
非常感激VV的解释,
我现在是应用层给路由节点发送一个事件来实现的。这样是否没有底层的可靠呢?
我听明白了你的解释,我之前也跟踪到这里过。
1。
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT ) ZDNwkMgr_event_loop,#endif
2。
case ZDO_CB_MSG: // ZDO sends the message that we registered for ZDNwkMgr_ProcessMsgCBs( (zdoIncomingMsg_t *)msgPtr ); break;
3。
#if defined ( NWK_MANAGER ) case Mgmt_NWK_Update_notify: ZDNwkMgr_ProcessMgmtNwkUpdateNotify( inMsg ); break;#endif // NWK_MANAGER
4。
ZDNwkMgr_CheckForChannelChange( pNotify );
5。
ZDP_MgmtNwkUpdateReq( &dstAddr, channelMask, 0xfe, 0, _NIB.nwkUpdateId, 0 );
最后一步就是你提的那里了。
我想问的是
1。第一步1要#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT ),是不是只有路由节点才有效呀?
2。第三步3要#if defined ( NWK_MANAGER ) 。然而我的工程里没有用过NWK_MANAGER ,网络里好像只能有一个,那就对应协调器了?还会影响其他功能吗?