ZigBee中PANID的修改

做了一个ZigBee农业沙盘的烂尾项目,当在一个区域有多个协调器存在的时候,终端组网就乱了,可能这个实验箱的终端连到那个实验箱的协调器上去啦。

项目用的是Z-stack协议栈,2007版的,这个蹿网的问题是一个问题。

最后我们是这样解决的:用TI的烧录hex文件的工具——SmartRF Flash Programmer烧录的时候,可以设置IEEE地址,烧到Flash中去,从而读取这个值再作为PANID,这样每套实验箱的PANID就不一样啦。甚至还可以写值到Flash,让程序来自动判断是CO2传感器终端还是光照传感器终端等。


之前网上搜了一下,要修改PANID啥的,这里找到一篇文章,感觉还不错,但不一定行,先放到这里供参考。

转载自:http://bbs.feibit.com/thread-8632-1-1.html


首先感谢一下这个论坛,让我学到了很多东西,我也把一些心得分享给大家,共同进步!
想要实现的功能:
1.串口修改PAN ID;
2.串口修改CHANNEL;
3.广播发送给网内节点,重启建立新的网络。

实现例程:sampleapp例程修改
IAR预编译:
ZTOOL_P2
MT_TASK
MT_AF_FUNC
MT_AF_CB_FUNC
MT_APP_FUNC
MT_DEBUG_FUNC
MT_NWK_FUNC
MT_NWK_CB_FUNC
MT_SYS_FUNC
MT_SYS_OSAL_NV_READ_CERTIFICATE_DATA
MT_UTIL_FUNC
MT_ZDO_CB_FUNC
MT_ZDO_FUNC
MT_ZDO_MGMT
NV_RESTORE

在看帖子之前建议大家先看3篇其他前辈的,我借鉴了他们的经验:
http://www.feibit.com/forum.php?mod=viewthread&tid=3627
http://www.cnblogs.com/qmlm8844/archive/2012/03/13/2393366.html
http://hi.baidu.com/njordnb/item/2ad8c4125f8dcc16e3f986f2
相信看完以上3篇以后,大家已经对PAN ID 和CHANNEL有了大概了解? 什么,还没看?  赶紧先去看

一、串口修改PAN ID
 
在之前的实验中,我一直纠结于pan id的设置,有2种方法:
方法1.
pan_id=0x1122;//你想要的ID
zb_WriteConfiguration(ZCD_NV_PANID, sizeof(uint16),  &pan_id) ;
zb_SystemReset();


方法2:
pan_id = 0x1122;     
_NIB.nwkPanId = pan_id;
NLME_UpdateNV(0x01);
zb_SystemReset();
我自己的实验结果显示,方法2是可行的,于是,我对MT_UTIL.C函数中的MT_UtilSetPanID做了修改
(我用ztool中util修改PAN ID不成功,不知道为什么,有人遇到过吗?)
以下是修改后的代码
 
串口发送fe 02 27 02 00 05 22,PAN ID改为0x0500,自动重启,路由器不在网内
我用串口调试助手,IAR仿真结果显示PAN ID修改成功,剩下的我们就需要考虑如何广播出去了(这个简单)

二、修改CHANNEL
这里有个概念问题:
_NIB.channelList表示可以扫描的信道;
_NIB.nwkLogicalChannel表示正在使用的逻辑信道,从11~26,即0x0B~0x1A
所以我们要修改的目标是_NIB.nwkLogicalChannel
代码奉上:
 
记得改一下:-DDEFAULT_CHANLIST=0x00003800   //使能0B 0C 0D信道
串口发送数据:
_NIB.nwkLogicalChannel                                   帧结构
0x0b                                             fe 05 27 03 00 08 00 00 0b 22
0x0c                                             fe 05 27 03 00 10 00 00 0c 3d

三、广播发送
直接贴上代码,有不懂的同学想一想,实在想不通再问。
协调器广播部分:
其中KEY1    KEY2是例程自带的,KEY5是我自己定义的广播发送按键。
之前的帖子中说道协调器广播完后重启的问题,所以我在这里新建了一个任务,让协调器5秒后自动重启:
osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SYS_RESET_SOFT, 5000);//新建一个任务,5S后重启

  1. void SampleApp_HandleKeys( uint8 shift, uint8 keys )
  2. {
  3.   (void)shift;  // Intentionally unreferenced parameter
  4.   
  5.   if ( keys & HAL_KEY_SW_1 )  //FLASH读写实验
  6.   {
  7.     /* This key sends the Flash Command is sent to Group 1.
  8.      * This device will not receive the Flash Command from this
  9.      * device (even if it belongs to group 1).
  10.      */
  11.     SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION );
  12.   }
  13.   
  14.    if ( keys & HAL_KEY_SW_2 )
  15.   {
  16.     /* The Flashr Command is sent to Group 1.
  17.      * This key toggles this device in and out of group 1.
  18.      * If this device doesn't belong to group 1, this application
  19.      * will not receive the Flash command sent to group 1.
  20.      */
  21.     aps_Group_t *grp;
  22.     grp = aps_FindGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP );
  23.     if ( grp )
  24.     {
  25.       // Remove from the group
  26.       aps_RemoveGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP );
  27.     }
  28.     else
  29.     {
  30.       // Add to the flash group
  31.       aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group );
  32.     }
  33.   }
  34.    
  35.   if ( keys & HAL_KEY_SW_5 )
  36.   {            
  37.         //广播至所有节点
  38.         if(UpdateAllNetwork(_NIB.nwkPanId, _NIB.nwkLogicalChannel) == afStatus_SUCCESS)
  39.         {
  40.                  osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SYS_RESET_SOFT, 5000);//新建一个任务,5S后重启
  41.         }
  42.   }
  43. }
复制代码
  1. static afStatus_t UpdateAllNetwork(uint16 panId, uint8 channelId)
  2. {

  3.   afAddrType_t dstAddr;
  4.   uint8 dataLength = 3;   //PAN ID+CHANNEL
  5.   uint8 *msg = osal_mem_alloc(dataLength);

  6.   dstAddr.addrMode = (afAddrMode_t)afAddrBroadcast;
  7.   dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVALL;
  8.   dstAddr.endPoint = AF_BROADCAST_ENDPOINT;

  9.   msg[0] = LO_UINT16(panId);
  10.   msg[1] = HI_UINT16(panId);
  11.   msg[2] = channelId;

  12.   return AF_DataRequest(&dstAddr, 
  13.                        &SampleApp_epDesc, 
  14.                        YOURNAME_NETCONF_CLUSTERID,
  15.                        dataLength, 
  16.                        msg,
  17.                        &SampleApp_TransID, 
  18.                        0, 
  19.                        AF_DEFAULT_RADIUS);
  20. }
复制代码
节点接收部分:
  1. void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
  2. {
  3.   uint16 flashTime;

  4.   switch ( pkt->clusterId )
  5.   {
  6.     case SAMPLEAPP_PERIODIC_CLUSTERID:
  7.       break;

  8.     case SAMPLEAPP_FLASH_CLUSTERID:
  9.       flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
  10.         HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
  11.       break;
  12.         //配置网络信息
  13.     case ELINKCS_NETCONF_CLUSTERID:
  14.         _NIB.nwkPanId=BUILD_UINT16(pkt->cmd.Data[0], pkt->cmd.Data[1] );
  15.         _NIB.nwkLogicalChannel=pkt->cmd.Data[2];
  16.         NLME_UpdateNV(0x01);
  17.         HalLedBlink( HAL_LED_4, 6, 50, (flashTime / 4) );
  18.         osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SYS_RESET_SOFT, 5000);//创建一个任务,5S后重启
  19.         break;
  20.   }
  21. }
复制代码
先写这么多,以后想到再完善!



  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值