ZigBee中的技术问题以及解决方案

来源:互联网 发布:浪潮软件二级部门 编辑:程序博客网 时间:2024/06/05 19:52
1.组网后,怎样获取新加入的Endpoint的地址?


答:
    现在有一个最常见的场景,我有一个100个节点的网络同时发送数据给协调器,我很想知道那个地址对应那个节点。其实楼上的就想知道那个,以前老板也经常问我这个问题。即使知道了某个节点的IEEE地址还是不知道是某个节点,除非你事先知道那个节点的地址。你不可能一个一个节点上电在轮询获得地址吧?如果那样的话,我还不如直接加下NV_RESTORE之后断电一个一个标


    终端在给协调器发送的数据包中就包含自己的地址信息就可以了,这样协调器即不用浪费自己的RAM空间来保存所有节点的地址信息,也不用花时间来查询了。


    因为MAC地址是唯一的,所以可以用MAC地址




    还记得毛子在太空用铅笔的典故么?这里有个笨办法,在批量烧写CC2530的时候,就把它的IEEE地址读出来,然后贴在标签上。


A:
请问zigbee 怎么通过mac地址获得网络中挂在路由下的节点的短地址,用APSME_LookupNwkAddr得到短地址时,只能查找协调器儿子节点,对孙子节点不可访问,


afStatus_t ZDP_NwkAddrReq( byte *IEEEAddress, byte ReqType,


                           byte StartIndex, byte SecurityEnable )


根据已知网络地址查询远程设备物理地址,作为一个广播信息发送给网络中的所有设备:这个函数也是知道IEEE地址,对短地址进行寻找,这个不存在上面所说的限制,但是这个短地址放在那里呢,我怎么获得这个短地址呢?



B:
请使用函数:


afStatus_t ZDP_NwkAddrReq( uint8 *IEEEAddress, byte ReqType,byte StartIndex, byte SecurityEnable )


2问题:
请问调用这个函数获得的地址放在那里呢?
答:
会有callback函数上来的,对应的处理事件是


#define NWK_addr_rsp            (NWK_addr_req | ZDO_RESPONSE_BIT)


void ZDApp_ProcessMsgCBs( zdoIncomingMsg_t *inMsg )


的switch case下面做添加就可以,然后去处理获得的地址




3问题:
ZigBee网络中协调器分配网络地址在哪?如何查看设备的网络地址?
答:
协调器的短地址是0x0000,当设备加入成功后,会产生一个ZDO_STATE_CHANGE_EVT事件,这个事件就是设备加入网络成功后,并在网络中的身份确定后产生的一个事件,我们可以在这里处理,一些初始化,比如可以发送终端的短地址,IEEE地址等,这里协调器接收到以后,可以提取出终端的短地址,其实在终端给协调器发送的每个数据包中,都含有其自身的短地址,如结构体当中的afAddrType_t srcAddr;协调器在接收到短地址后,就可以知道自己下面管辖的终端节点,或者路由节点有哪些了?协调器提取到的短地址可以存放到一个非易失性的存储器中。




两种方法,


1)节点在入网的时候都会发送Device Announce,这个Device Announce是广播数据,所以每个设备的Device Announce,Coordinator都能收到,而且在Device Announce 都带有这个设备的短地址,那么你的Coordinator也就可以获得所有终端设备的短地址了。


2)如果错过了Device Announce,那么在协议栈里面有现成的API ZDP_IEEEAddrReq()函数也可以使用获得终端设备的地址,具体参考附件的文档。


问题:
怎样将ZigBee自组织网络的数据传到服务器?
答:
zigbee gprs网关实现ZigBee采集数据上传到服务器。






4问题:
怎样利用移动终端设备(手机)去控制发送数据来操控ZigBee网络中的节点动作?
答:
手机通过GPRS将数据发送到服务器,然后由服务器转化给ZigBee网络的协调器。


5问题:
显示数组时,如果数组的值是程序运行过程中外部赋予的,那么在液晶或者OLED显示时,其尾部会有乱码,怎样处理该问题?
答:
在给数组的最后一个有效数字后面的元素赋值'\0',这样就可以解决,但是在串口显示时'\0'会显示为'*'.


6问题
指针函数的返回值为一指针,调用后获得数据,显示的时候会有乱码?
答: 
返回值为指针的时候,该指针变量必须定义为全局变量。




7问题:
通过串口发送指令时,发送一次后,协调器将自动不停的发送数据,导致终端节点接收到数据后,不停的传送自己的数据导致网络堵塞?
答:
在协调器启动发送广播数据获取终端节点的数据时,先判断通过回调函数获取的串口数据,采用if(osal_memcmp(uart_cmd,"get_data"  && (data_lg >=1 ) 判断后发送获取数据指令。
(uart_cmd 为定义的存放上位机通过串口发送来的数据;data_lg 为定义的上位机通过串口发送来的数据长度)


8问题:
向所有网络节点广播数据发送指令时,协调器无法一个不漏的将终端节点的数据存储下来?


9问题:
组建的网络在协调器断点后,终端节点无法加入协调器新建的网络中?
答:协调器断电,节点成孤点了,一直在搜网,SampleApp_NwkState == DEV_NWK_ORPHAN;不能加入协调器的原因:协调器重新启动后,PANID变了,
节点还在找原来ID的网络,所以不加入新的网络中。可以通过在终端节点的网络状态改变函数中加SampleApp_NwkState == DEV_NWK_ORPHAN,触发终端节点重新复位。复位后就会重新搜索网络,并加入新的网络。


10问题:
最近发生的那个osal_timeout作为休眠时间,怎么样知道osal_timeout的值是多少?
答:
这个timeout主要分为两类,一类是应用层事件的timeout,另外一类是MAC层事件的timeout,


应用层的timeout的时间,是在osal_pwrmgr_powerconserve( void )函数中,通过osal_next_timeout();获得的。


MAC层的timeout时间,是通过halSleep( uint16 osal_timeout )函数里面,通过MAC_PwrNextTimeout();来获得的。


11问题:
如何让End Device进入低功耗状态,休眠时间是如何设定的?
答:
在协议栈宏定义中使能POWER_SAVING后,然后在f8wConfig.cfg文件里面把-DRFD_RCVC_ALWAYS_ON=FALSE,就可以让End Device进入休眠状态。
关于休眠的时间是有OSAL操作系统的调度来决定,每次休眠时间都是按照最新会发生的一个Event Timeout作为休眠时间。具体在协议栈hal_sleep函数中有说明。
这个timeout主要分为两类,一类是应用层事件的timeout,另外一类是MAC层事件的timeout,
1)应用层的timeout的时间,是在osal_pwrmgr_powerconserve( void )函数中,通过osal_next_timeout();获得的。
2)MAC层的timeout时间,是通过halSleep( uint16 osal_timeout )函数里面,通过MAC_PwrNextTimeout();来获得的。


12问题:
TI的ZigBee协议栈不同版本的区别,如何选择合适的协议栈进行产品开发
答:
TI ZigBee 协议栈Z-Stack从最开始的Z-Stack 0.1到大家熟悉的Z-Stack 2.5.1a,以及到现在Z-Stack Home 1.2.1, Z-Stack Lghting 1.0.2, Z-Stack Energy 1.0.1, Z-Stack Mesh 1.0.0. 在协议栈的升级过程TI主要对协议栈做了两方面的工作,1) 根据ZigBee Alliance的ZigBee Specification进行一些新的Feature添加,比方说ZigBee2007是树形的路由,在ZigBee Pro中有了Mesh路由,并且提出了MTO和Source Routing等路由算法,所以TI的把相应新的功能添加到协议栈上去。当然有一部分是Spec中相关bug的修正,比方说有些描述模棱两可的;2) TI ZigBee协议栈本身软件bug的修复。一个版本的协议栈相对于之前一个版本协议栈的区别,都可以在协议栈安装目录下的Release Note中找到。
在Z-Stack 2.5.1a以后,TI的协议栈并没有继续以Z-Stack 2.6.x的形式直接发布,而是按照Application Profile的方式来发布了,原因在于TI希望开发者根据实际的应用选择更有针对的性的协议栈进行开发。像Z-Stack Home 1.2.1之类的协议栈,主要包括两部分,1)核心协议栈Core Stack,这部分起始就是之前的Z-Stack 2.5.1a以后的延续版本,可以在协议栈安装目录下 Z-Stack Core Release Notes.txt文件中找到,Version 2.6.2 。2)应用协议栈 Profile相关,这部分主要跟实际应用相关的,Home Automation 协议栈里都是ZigBee Home Automation Profile相关的实现。同样Z-Stack Lghting 1.0.2和Z-Stack Energy 1.0.1也是一个Core Stack再加上应用上的Profile。
1)Z-Stack Home 1.2.1 针对智能家居相关产品的开发
2)Z-Stack Lighting 1.0.2 针对ZLL相关产品的开发
3)Z-Stack Energy 1.0.1 针对智能能源,Meter, In Home Display, 等相关产品的开发
4)Z-Stack Mesh 1.0.0 针对相关私有应用的产品的开发,只利用标准ZigBee协议相关功能, Mesh路由等,应用层有开发者自己定义。




13问题:
产品如何进行标准ZigBee测试认证,需要了解哪些,需要走什么流程
答:
以开发标准ZigBee Home Automation相关产品为例。首先开发者开发产品时要按照ZigBee Home Automation Profile Specification 中描述的产品进行开发,这个文档可以在www.zigbee.org下载到。在完成产品的开发后,开发着需要了解ZigBee Home Automation Profile Test Specification, 这个文档描述了一个特定产品需要在Test House过的相关测试项,文档也可以在www.zigbee.org下载到,另外除了以上两个文档以外还有一个PICS文档,这个文档专门用于描述需要过认证测试产品所支持的功能,开发者根据开发产品的实际红能,和Specification中所要求的功能,在文档中进行打钩确认。下面是测试的流程,
1) 首先加入ZigBee联盟,一般可以有测试实验室帮助完成。
2) 寄送样品到测试实验室,完成PICS文档的填写。
3) 第一轮预测试,测试实验室对测试结果反馈,开发者修改样品代码。
4) 测试实验室对修改后的样品进行验证,然后开始正式测试。
5) 测试实验室协助开发者完成ZigBee联盟网上认证申请资料的准备和提交。
6) 测试实验室提交正式测试报告给ZigBee联盟。联盟会完成审核并发证
目前国内可以完成标准ZigBee测试的测试实验室有两家
1) CESI 北京 中国标准化电子研究所。
2) TRAC 深圳办事处(总部在英国)
 
 
14问题:
设备的64位 MAC地址是怎么样选取的?
答:
在CC2530中分为两个IEEE地址,一个称为Primary IEEE地址,另外称为Secondary地址。Primary IEEE地址是存放在芯片的Information Page里面,这个地址是TI向IEEE协会购买的,每个芯片的地址都是唯一的。并且用户只能Read这个值,没办法擦除/修改。在协议栈中直接通过读地址可以获得 osal_memcpy(aExtendedAddress, (uint8 *)(P_INFOPAGE+HAL_INFOP_IEEE_OSET), Z_EXTADDR_LEN)。 Secondary地址是存放在CC2530里的Flash最后一个Page里面,用户可以进行Read/Write. 通过函数HalFlashRead(HAL_FLASH_IEEE_PAGE, HAL_FLASH_IEEE_OSET, aExtendedAddress, Z_EXTADDR_LEN);。
协议栈运行是,是如何选择Primary IEEE地址或者Secondary地址作为设备的MAC地址的,具体在函数zmain_ext_addr(void)操作。
1) 从NV中读取 IEEE地址,如果已经存在(都不为0xFF),就使用该地址作为MAC地址了。
2) 如果1)中没有,从Secondary IEEE地址存放位置读取,如果有(都不为0xFF),把该地址写入到NV中,以后就用该地址作为MAC地址了。
3) 如果2)中没有,从Primary IEEE地址存放位置读取,如果有(都不为0xFF),把该地址写入到NV中,以后就用该地址作为MAC地址了
4) 如果3)中没有,就随机产生一个64位的变量,写入到NV中,并作为MAC地址。


15问题:
End Device是低功耗设备, 有电池供电, 节点在断网以后,如何能够禁止节点持续搜索网络,或者把发送Beacon Request间隔增大
答:
1)启动搜索网络 uint8 ZDApp_StartJoiningCycle( void )
停止搜索网络 uint8 ZDApp_StopJoiningCycle( void )


2) 更改发送Beacon Request的周期
修改变量zgDefaultStartingScanDuration
// Beacon Order Values
#define BEACON_ORDER_NO_BEACONS     15
#define BEACON_ORDER_4_MINUTES      14  // 245760 milliseconds
#define BEACON_ORDER_2_MINUTES      13  // 122880 milliseconds
#define BEACON_ORDER_1_MINUTE       12  //  61440 milliseconds
#define BEACON_ORDER_31_SECONDS     11  //  30720 milliseconds
#define BEACON_ORDER_15_SECONDS     10  //  15360 MSecs
#define BEACON_ORDER_7_5_SECONDS     9  //   7680 MSecs
#define BEACON_ORDER_4_SECONDS       8  //   3840 MSecs
#define BEACON_ORDER_2_SECONDS       7  //   1920 MSecs
#define BEACON_ORDER_1_SECOND        6  //    960 MSecs
#define BEACON_ORDER_480_MSEC        5
#define BEACON_ORDER_240_MSEC        4
#define BEACON_ORDER_120_MSEC        3
#define BEACON_ORDER_60_MSEC         2
#define BEACON_ORDER_30_MSEC         1
#define BEACON_ORDER_15_MSEC         0




12问题:
osal_start_timerEx()和函数  halSleep()都是定时让节点进入睡眠模式???




13 问题
传感器模拟电压采集的时候,由于输入AD前,阻抗可能不匹配,导致ADC采样存在误差?
答:
这是可以加入运放电压跟随




14问题:
将终端节点采用halSleep(time)开启PM2休眠模式。如果在休眠只接受协调器的广播命令执行上传数据等操作,但是,在休眠自动唤醒过程中,在示波器上看到了有较高的功率消耗?
答:
原因1:休眠唤醒,是由协议栈根据相关事件操作自动进行,与halSleep(设置时间没有关系);所以节点不断的查询要操作的事件,自然就不会进入真正意义的休眠。 通过对比加入halSleep(time)函数与否,证明了该原因。
解决方案:
在终端节点程序中加入定时设定事件,然后采用周期性启动事件,会发现...


15问题:
加入hal_Sleep()休眠函数后,上位机发送一次get_data命令,结果收到两次数据?
答:
协调器上电,状态改变触发事件,该事件自身设置定时启动,如果该事件自身定时启动的时间小于终端节点的正常工作时间,那么终端节点工作期间(醒来的状态)会再次受到协调器的周期发送事件。终端节点处理了该周期事件对应的指令所指向的事件后,接下来会执行休眠期间存储的事件。这样就会导致节点发送两次数据,自然就会收到两次数据。
解决方案:协调器的周期事件的启动时间大于终端节点的工作时间与休眠时间之和。


16问题:
不带功放修改输出功率增加通讯距离方法如?
答:
要改变输出功率在文件mac_pib.c中


17问题:
对case AF_DATA_CONFIRM_CMD:  
          afDataConfirm = (afDataConfirm_t *)MSGpkt;
          sentEP = afDataConfirm->endpoint;
          sentStatus = afDataConfirm->hdr.status;
          sentTransID = afDataConfirm->transID;
          (void)sentEP;
          (void)sentTransID;


          if ( sentStatus != ZSuccess )
          {
          }
          break;
的理解?


答:
只要调用了AF_DataRequest()函数发送数据,就会有AF_DATA_CONFIRM_CMD事件返回,无论传输成功与否。


sentStatus != ZSuccess的解释与你调用AF_DataRequest()函数的options参数有关:


如果option中使能了AF_ACK_REQUEST,表明需要应用层的ACK,那么此时若sentStatus == ZSuccess则表明数据已经到达了目的地址。


若option中并没有使能AF_ACK_REQUEST,表明只需要MAC层的ACK,那么此时若sentStatus == ZSuccess则表明数据已经到下一跳节点。


18问题:
采用4X1ds18B2阵时,利用CC2530的端口P0_4时,数据无法获取?


答:经过长时间的思考,发现cc2530端口P0_4存在严重问题。之前由于P0_5、P0_6、P0_7端口都用完,且其他端口要么用于下载,要么用于OLED液晶显示,没有多余的端口可用。通过去掉OLED,利用端口P0_0问题解决,数据能够正常采集。


19,为什么P0_4端口不能用呢?


20问题:
matlab拟合的数据采用p=polyfit()输出的系数自保留4位小数,当拟合的精度要就更高时,采用这个自动输出的系数会给植入程序中造成很大的误差,不能满足要求?


答:采用y =poly2sym(p); 输出完整你拟合函数   


20 .zigbee重启路由协调器,有些终端不会联网?


答:代码不用自己写,直接使用zigbee协议栈的例程就可以,如果你想修改局域网络,防止和别的zigbee组网冲突,可以修改协调器的PANID,对应的终端节点和路由器会在这个PANID局域网中组网,可以防止冲突。


21. 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,变化


22.怎样开启宏定义NC_RESTORE?


答:在宏定义中定义NC_RESTORE=1即可。
注意:这个宏定义好处肯定是有的,但是问题也来了,如果终端想加入别的协调器网络,既是PANID和频道都一样,不管重启多少次都不会加入新的协调器中。解决方法参看问题23.


23.清除NV_RESTORE保存的信息?
答:
官方的说明
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的值




24.CC2530的后端射频放大采用cc2590,具体实现效果?
答:
TI公司的CC2590是低功耗低电压高性能2.4GHz RF前端,输出功率高达14dBm(25mW),内部集成了开关,匹配网络,平衡/不平衡(Balun)变压器,LNA,功率放大器和电感.工作电压2.0V到3.6V,可用于所有的2.4GHz ISM频段系统,无线传感器网络和工业系统, ZigBee和IEEE 802.15.4系统,无线消费类电子产品和无线音频系统.


25.Z-stack协议栈中  #define BV(n)      (1 << (n))是什么意思?、


答:
也就是00000001往左移移N位,比如移3位的结果是00001000




26.IAR,“Go?to?Definition?of”是灰色的?
答:


Tools -> Options -> Project:勾选Generate browse information 


27.采用“字模提取V2.2”软件,SSD1306 OLED显示器进行中文字模提取时,提出出来的16X16字模不对?


答:
由于SSD1306的特许性,需要将参数设置中的取模方式设置为“纵向取摸”,同时勾选“字节倒序”选项。


28、关于CC2530核心板有源晶振的接线问题?
答:
不需要复杂的配置电路.有源晶振通常的用法:一脚悬空,二脚接地,三脚接输出,四脚接电压.相对于无源晶体,有源晶振的缺陷是其信号电平是固定的,需要选择好合适输出电平,灵活性较差,而且价格高.
1、首先是TI官网给出的CC2530EM  PCB板,上面的有源晶振是这么接的:1和3分别接CC2530的两端,2和4悬空(没有接地也没有接VCC);
2、其次是飞比的CC2530核心板,接法是这样的:1和3分别接CC2530的两端,2和4直接接地(这个板子我正在用,可以正常工作);






物联网的无线通信技术很多,主要分为两类:一类是Zigbee、WiFi、蓝牙、Z-wave等短距离通信技术;另一类是LPWAN(low-power Wide-Area Network,低功耗广域网),即广域网通信技术。LPWA又可分为两类:一类是工作于未授权频谱的LoRa、SigFox等技术;另一类是工作于授权频谱下,3GPP支持的2/3/4G蜂窝通信技术,比如EC-GSM、LTE Cat-m、NB-IoT等。


29、IAR中make、compile和rebuild all 的区别?
-----------------------------------------------------------------------------------------------------
make (常用)编译,连接当前工程。(编译只编译有改动文件,或者设置变动的文件,工程窗口文件右边会有个*号) 
compile 只编译当前源文件。 (不管文件是否改动,或者设置是否变动) 
rebuild all 编译,连接当前工程。 (不管文件是否改动,或者设置是否变动)


1、Compile:只编译选定的目标,不管之前是否已经编译过。
2、Make:编译选定的目标,但是Make只编译上次编译变化过的文件,减少重复劳动,节省时间。(具体怎么检查未变化,这个就不用考虑了,IDE自己内部会搞定这些的)
3、Build:是对整个工程进行彻底的重新编译,而不管是否已经编译过。Build过程往往会生成发布包,这个具体要看对IDE的配置了,Build在实际中应用很少,因为开发时候基本上不用,发布生产时候一般都用ANT等工具来发布。Build因为要全部编译,还要执行打包等额外工作,因此时间较长。
——-------------------------------------------------------------------------------------------------
30、Z-Stack 协议栈怎样生成hex文件?
答:
第一步:在f8w2530.xcl文件中找到两行被注释掉的语句
-M(CODE)[(_CODEBANK_START+_FIRST_BANK_ADDR)-(_CODEBANK_END+_FIRST_BANK_ADDR)]*\
_NR_OF_BANKS+_FIRST_BANK_ADDR=0x8000
第二步:
1. 正确配置输出文件格式:菜单选择Project-Options-Linker-Output-Format,选择Other。右边的Output下拉框 选intel-extended,Format variant下拉框选None,Module-local下拉框选Include all  2.还是在菜单Project-Options-Linker-Output标签中,勾上Override default选项,把编辑框中的文件名的后缀改为hex


31、绑定表记录的最大个数设置与Cluster ID的最大个数设置?
答:f8wConfig.cfg 中NWK_MAX_BINDING_ENTRIES               MAX_BINDING_CLUSTER_IDS
1 0
原创粉丝点击