ZigBee中PANID的修改
信道配置:
Zigbee在3个频段定义了27个物理信道:868MHz频段中定义了1个20Kb/s信道,915MHz频段中定义了10个40Kb/s信道,信道间隔为2MHz,2.4GHz频段上定义了16个250Kb/s信道,信道间隔为5MHz.
信道编号 |
中心频率/MHz |
信道间隔/MHz |
频率上限/MHz |
频率下限/MHz |
k=0 |
868.3 |
-- |
868.6 |
868.0 |
k=1,2,…,10 |
906+2(k-1) |
2 |
928.0 |
902.0 |
k=11,12,…,26 |
2401+5(k-11) |
5 |
2483.5 |
2400.0 |
Z-stack中可以在f8wConfig.cfg里设置信道,相关部分如下:
/* Default channel isChannel 11 - 0x0B */
// Channels are definedin the following:
// 0 : 868 MHz 0x00000001
// 1 - 10 : 915 MHz 0x000007FE
// 11 - 26 : 2.4 GHz 0x07FFF800
//-DMAX_CHANNELS_868MHZ 0x00000001
//-DMAX_CHANNELS_915MHZ 0x000007FE
//-DMAX_CHANNELS_24GHZ 0x07FFF800
//-DDEFAULT_CHANLIST=0x04000000// 26 - 0x1A
//-DDEFAULT_CHANLIST=0x02000000// 25 - 0x19
//-DDEFAULT_CHANLIST=0x01000000// 24 - 0x18
//-DDEFAULT_CHANLIST=0x00800000// 23 - 0x17
//-DDEFAULT_CHANLIST=0x00400000// 22 - 0x16
//-DDEFAULT_CHANLIST=0x00200000// 21 - 0x15
//-DDEFAULT_CHANLIST=0x00100000// 20 - 0x14
//-DDEFAULT_CHANLIST=0x00080000// 19 - 0x13
//-DDEFAULT_CHANLIST=0x00040000// 18 - 0x12
//-DDEFAULT_CHANLIST=0x00020000// 17 - 0x11
//-DDEFAULT_CHANLIST=0x00010000// 16 - 0x10
//-DDEFAULT_CHANLIST=0x00008000// 15 - 0x0F
//-DDEFAULT_CHANLIST=0x00004000// 14 - 0x0E
//-DDEFAULT_CHANLIST=0x00002000// 13 - 0x0D
//-DDEFAULT_CHANLIST=0x00001000// 12 - 0x0C
-DDEFAULT_CHANLIST=0x00000800 // 11 - 0x0B 这里默认使用的是编号为11的信道
当建网过程开始后,网络层将请求MAC层对规定的信道或由物理层默认的有效信道进行能量检测扫描,以检测可能的干扰。网络层管理实体对能量扫描的结果以递增的方式排序,丢弃那些能量值超出可允许能量水平的信道,然后再由网络层管理实体执行一次主动扫描,结合检查PAN描述符,对剩下的信道选择一个合适的建立网络。
若要在应用中查看信道,可以这样获得,_NIB.nwkLogicalChannel,读取这个就OK了。
PANID:
在确定信道以后,下一步将是确定PANID,如果ZDAPP_CONFIG_PAN_ID被定义为0xFFFF,那么协调器将根据自身的IEEE地址建立一个随机的PANID(0~0x3FFF),如ZDAPP_CONFIG_PAN_ID没有被定义为0xFFFF,那么网络的PANID将由ZDAPP_CONFIG_PAN_ID确定。
“如果ZDAPP_CONFIG_PAN_ID被定义为0xFFFF,那么协调器将根据自身的IEEE地址建立一个随机的PANID(0~0x3FFF)”这句话怎么理解呢,我经过试验发现,这个随机的PANID并非完全随机,它有规律,与IEEE地址有一定的关系:要么就是IEEE地址的低16位,要么就是一个与IEEE地址低16位非常相似的值。如IEEE地址为0x8877665544332211,PANID很有可能就是2211,或相似的值;IEEE地址为0x8877665544337777,PANID很有可能就是3777,或其它相似的值;
Z-stack中相关部分代码如下:
/* Define the default PANID.
*
* Setting this to a valueother than 0xFFFF causes
* ZDO_COORD to use thisvalue as its PAN ID and
* Routers and end devicesto join PAN with this ID
*/
-DZDAPP_CONFIG_PAN_ID=0xFFFF
若要在应用中查看PANID可以这样获得,_NIB.nwkPanId,读取这个就OK了。
发射功率:
传送范围的大小是和发射功率还有信道环境有关, 传送速率和传送范围之间没有直接联系。所以呢,适当的增大发射功率可增大传送范围。但也是有一定的限制的。具体详见datasheet。
在mac_radio_def.h里有可以设置:
#defineMAC_RADIO_CHANNEL_DEFAULT 11
#defineMAC_RADIO_TX_POWER_DEFAULT 0x1F
#defineMAC_RADIO_TX_POWER_MAX_MINUS_DBM 25
这些只是举例说明一下,这些参数的意义,以及在z-stack里的什么地方修改。还有很多其它的参数,可以查看相关的源文件。
[mac_radio_def.h]
#defineMAC_RADIO_SET_CHANNEL(x) st(FSCTRLL = FREQ_2405MHZ + 5 * ((x) - 11); )
#defineMAC_RADIO_SET_TX_POWER(x) st(TXCTRLL = x; )
#define MAC_RADIO_SET_PAN_ID(x) st( PANIDL = (x) & 0xFF;PANIDH = (x) >> 8; )
[mac_radio.c]
void macRadioInit(void)
{
/* variableinitialization for this module */
reqChannel = MAC_RADIO_CHANNEL_DEFAULT;
macPhyChannel =MAC_RADIO_CHANNEL_DEFAULT;
reqTxPower = MAC_RADIO_TX_POWER_DEFAULT;
macPhyTxPower =MAC_RADIO_TX_POWER_DEFAULT;
}
[mac_low_level.h]
uint8macRadioRandomByte(void);
voidmacRadioSetPanCoordinator(uint8 panCoordinator);
voidmacRadioSetPanID(uint16 panID);
voidmacRadioSetShortAddr(uint16 shortAddr);
voidmacRadioSetIEEEAddr(uint8 * pIEEEAddr);
voidmacRadioSetTxPower(uint8 txPower);
voidmacRadioSetChannel(uint8 channel);
voidmacRadioStartScan(uint8 scanType);
voidmacRadioStopScan(void);
voidmacRadioEnergyDetectStart(void);
uint8 macRadioEnergyDetectStop(void);
想要实现的功能:
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后重启
- void SampleApp_HandleKeys( uint8 shift, uint8 keys )
- {
- (void)shift; // Intentionally unreferenced parameter
- if ( keys & HAL_KEY_SW_1 ) //FLASH读写实验
- {
- /* This key sends the Flash Command is sent to Group 1.
- * This device will not receive the Flash Command from this
- * device (even if it belongs to group 1).
- */
- SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION );
- }
- if ( keys & HAL_KEY_SW_2 )
- {
- /* The Flashr Command is sent to Group 1.
- * This key toggles this device in and out of group 1.
- * If this device doesn't belong to group 1, this application
- * will not receive the Flash command sent to group 1.
- */
- aps_Group_t *grp;
- grp = aps_FindGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP );
- if ( grp )
- {
- // Remove from the group
- aps_RemoveGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP );
- }
- else
- {
- // Add to the flash group
- aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group );
- }
- }
- if ( keys & HAL_KEY_SW_5 )
- {
- //广播至所有节点
- if(UpdateAllNetwork(_NIB.nwkPanId, _NIB.nwkLogicalChannel) == afStatus_SUCCESS)
- {
- osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SYS_RESET_SOFT, 5000);//新建一个任务,5S后重启
- }
- }
- }
复制代码
- static afStatus_t UpdateAllNetwork(uint16 panId, uint8 channelId)
- {
- afAddrType_t dstAddr;
- uint8 dataLength = 3; //PAN ID+CHANNEL
- uint8 *msg = osal_mem_alloc(dataLength);
- dstAddr.addrMode = (afAddrMode_t)afAddrBroadcast;
- dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVALL;
- dstAddr.endPoint = AF_BROADCAST_ENDPOINT;
- msg[0] = LO_UINT16(panId);
- msg[1] = HI_UINT16(panId);
- msg[2] = channelId;
- return AF_DataRequest(&dstAddr,
- &SampleApp_epDesc,
- YOURNAME_NETCONF_CLUSTERID,
- dataLength,
- msg,
- &SampleApp_TransID,
- 0,
- AF_DEFAULT_RADIUS);
- }
复制代码
节点接收部分:
- void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
- {
- uint16 flashTime;
- switch ( pkt->clusterId )
- {
- case SAMPLEAPP_PERIODIC_CLUSTERID:
- break;
- case SAMPLEAPP_FLASH_CLUSTERID:
- flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
- HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
- break;
- //配置网络信息
- case ELINKCS_NETCONF_CLUSTERID:
- _NIB.nwkPanId=BUILD_UINT16(pkt->cmd.Data[0], pkt->cmd.Data[1] );
- _NIB.nwkLogicalChannel=pkt->cmd.Data[2];
- NLME_UpdateNV(0x01);
- HalLedBlink( HAL_LED_4, 6, 50, (flashTime / 4) );
- osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SYS_RESET_SOFT, 5000);//创建一个任务,5S后重启
- break;
- }
- }
【zigbee】开启及清除NV_RESTORE信息的方法
2014-07-21 16:57 7235人阅读 评论(1) 收藏 举报
分类:
zigbee(11)
版权声明:本文为博主原创文章,未经博主允许不得转载。
目录(?)[+]
1、NV_RESTORE宏的作用
· 问:coo和终端都已经组网成功
1、这时将coo断电,重新上电,组网后终端的短地址是否不变?
2、这时终端断电,重新上电,组网后终端的短地址是否不变?
3、这时COO和终端都断电,重新上电,组网后终端的短地址是否不变?
· 答:分两种情况来看 开启NV_RESTORE和不开启NV_RESTORE
1) 开启NV_RESTORE
1, 不变
2,不变
3,不变
2)不开启NV_RESTORE
1, 变化
2,不变
3,变化
2、加入NV_RESTORE编译选项
这个选项可以帮助终端在重启后也还会连上一次连接的协调器,获取到的短地址仍然不变化。开启的方法也很简单
在宏定义中定义NC_RESTORE=1即可
3、清除NV_RESTORE保存的信息
加入这个宏定义好处肯定是有的,但是问题也来了,如果终端想加入别的协调器网络,既是PANID和频道都一样,
不管重启多少次都不会加入新的协调器中,那该怎么办呢?
其实TI考虑到这个问题了,下面是官方的说明
application wants to delete the stored NV information It just needs to set the ZCD_NV_STARTUP_OPTION as explained below and do a reset.
"If the application would like to force a "new" join, the application should set the ZCD_STARTOPT_DEFAULT_NETWORK_STATE bit in the ZCD_NV_STARTUP_OPTION NV item before calling this function. "New" join means to not restore the network state of the device. Use zgWriteStartupOptions() to set these options
[zgWriteStartupOptions(ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE);]
zGlobals.c中有这两个函数,第二个就是上面所用的函数
uint8 zgReadStartupOptions( void ) //启动时读取ZCD_NV_STARTUP_OPTION的值
uint8 zgWriteStartupOptions( uint8 action, uint8 bitOptions ) //修改ZCD_NV_STARTUP_OPTION的值
ZigBee动态修改PanID
标签: zigbee学习笔记
2017-04-19 16:14 116人阅读 评论(0) 收藏 举报
分类:
ZigBee(7)
版权声明:本文为博主原创文章,未经博主允许不得转载。
修改方法:
1、设置预编译选项
ZTOOL_P1
NV_INIT
NV_RESTORE
2、在工程应用层目录中添加 sapi.c 文件
3、添加头文件 sapi.h OSAL_Nv.h
4、将sapi.c 中的 #define OSAL_SAPI TRUE 改为 #define OSAL_SAPI FALSE
5、在需要更改PanID处添加以下代码:
uint16 mypanid = 0x1122;
_NIB.nwkPanId = mypanid;
NLME_UpdateNV(0x01);
zgConfigPANID = mypanid;
osal_nv_write(ZCD_NV_PANID, 0, osal_nv_item_len( ZCD_NV_PANID ), &zgConfigPANID);
//要用定时器延时一段时间后再重启,否则 osal_nv_write 会来不及执行
osal_start_timerEx( SampleApp_TaskID,SAMPLEAPP_RESET_EVT,SAMPLEAPP_RESET_TIMEOUT );
5、SAMPLEAPP_RESET_EVT 时间中 调用 zb_SystemReset();
SAMPLEAPP_RESET_TIMEOUT 设置为2000 时 ,运行正常。
其他说明:
1、终端无法随意切换PanID的问题:
若终端在修改PanID语句中没有添加
zgConfigPANID = mypanid;
osal_nv_write(ZCD_NV_PANID, 0, osal_nv_item_len( ZCD_NV_PANID ), &zgConfigPANID);
这两句,则只能修改至f8wConfig.cfg 中设置的 PANID,其他PANID需要在联网的情况下才能切换。
加上上面两句后不会出现以上问题。
2、发信息给对方,让其改PanID,随后自己也改:
发送方的Reset Timeout 要比接收方稍微大一些。
在实验中,终端5s ,协调器3s ,运行正常。
3、其他修改PanID和Channe的方法(未验证,单独使用未成功)
zb_WriteConfiguration(ZCD_NV_CHANLIST,4,&channelList);
zb_WriteConfiguration(ZCD_NV_PANID, sizeof(uint16), &pan_id) ;
zb_SystemReset();//重启后才会启用新的PAN_ID,不然只是修改了NV里面的数据。
4、其他修改PanID和Channe的方法(未验证,单独使用未成功)
添加NV_INIT编译选项后,data request间隔只能为3S。
ZigBee中PANID的修改相关推荐
- tensorflow中keep_prob的修改方法
tensorflow中keep_prob的修改方法 warning: WARNING:tensorflow:From D:\software\pycharm_location\venv\Dehaze- ...
- Ueditor编辑旧文章,从数据库中取出要修改的内容
Ueditor编辑旧文章,从数据库中取出要修改的内容然后放置到编辑器中: <script type="text/plain" id="editor"> ...
- linux查找最近访问的文件,教您在Linux系统中查找最近修改的文件/文件夹
如果您使用Linux系统进行日常操作,则主目录文件将随时间急剧增加.如果您有成千上万个文件,很可能不记得最近更改的文件名,本文将教您在Linux系统中查找最近修改的文件/文件夹.另外,如果要检查出于任 ...
- 【Android 逆向】修改 Android 系统文件 ( Android 逆向中需要经常修改的文件和目录 | 在 root 后的设备中获取 / 目录的 rw 权限后注意事项 )
文章目录 一.Android 逆向中需要经常修改的文件和目录 二.在 root 后的设备中获取 / 目录的 rw 权限后注意事项 1.不要随意执行 wipe 命令 2.不要随意执行 rm 命令 一.A ...
- MySQL中如何通过修改表实现约束的添加与删除
修改表实现约束的添加与删除 一.主键约束 添加主键约束 Alter table 表名 add primary key(列名) 例 将 emp 表中的 employee_id 修改为主键且自动增长: ...
- python pandas 读取excel 去重某一列_Python中Pandas读取修改excel操作攻略(代码示例)...
本篇文章给大家带来的内容是关于Python中Pandas读取修改excel操作攻略(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 环境:python 3.6.8 以某米赛 ...
- git 撤销对工作区中文件的修改
对工作区中文件的修改分为三种情况: (1)修改,但没有用git add将修改添加到暂存区: (2)修改,已经使用git add将修改添加到暂存区: (3)修改,已经使用git add将修改添加到暂存区 ...
- mysql在计算机管理中的路径怎么修改_称重软件中的数据修改怎么知晓?
称重软件 称重软件应客户需求,数据允许修改,但不允许删除只能作废.如果数据已修改,该如何知晓该数据是修改过的呢,这就用到了标记.用户修改数据时为保证数据的可追溯性,同样在数据安全方面也有相应的要求,要 ...
- 如何理解在数据类型中元素不能修改?
如何理解在数据类型中元素不能修改? 我所理解的元素修改是: 不能对已经赋值或者初始化的数据类型进行元素的修改,这里的修改不是指片面意思上的输错了数值,将光标移到对应位置,按下删除键,再进行数据的修改等 ...
最新文章
- wordpress 拾遗
- android中互斥的控件,Android控件之Radiobutton与RadioGroup
- 前端学习(2948):webpack创建简单项目
- 查找树的指定层级_阿里面试,问了B+树,这个回答让我通过了
- Win8Metro(C#)数字图像处理--2.31灰度拉伸算法
- 小米平板5系列共三款机型:全系搭载2K/120Hz屏幕
- web系统权限之数据权限
- paramiko模块_玩转网络自动化之Netmiko模块
- ORA-28000 the account is locked的解决办法
- 基于Mysql+Java的超市管理系统(附源码)
- 四轮差分驱动平台gazebo插件
- SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图
- 实例演示如何在公共互联网构建overlay实现SDWAN
- ACL-BioNLP 2020 | 耶鲁大学实践成果:生物医药知识图谱嵌入模型基准测试
- 何海涛100题(1)自己心得
- 一图看懂TensorFlow2.0系列(十一)如何用TensorFlow2.0实现seq2seq的机器翻译?
- Java常用类(六):FilenameUtils类
- 微信昵称保存不了mysql_微信昵称存储mysql失败解决办法
- Android ABC 取其精华去其糟粕、JetPack好用的组件推荐
- 北斗三号频点_【导航论坛】北斗三号卫星导航信号及接收策略