从零开始学习Zigbee开发 - 图文(10)

2019-08-03 13:05

从零开始学习Z-Stack之9(2009-03-23 20:41:14) 标签:it

接到昨天的继续忽悠,话说: 2、SimpleApp

分类:WSN学习

“这个例子我基本跑通了,可是鉴于时间的关系,没有来得及打字了,所以就留到下一次了,时间真是如流水啊-------------------快!?.”

这个例子里面有两个演示:一个是灯与开关的控制实验,一个温度传感器实验。咱一个个来,不忙。 灯与开关实验

在这个例子中灯对应的工程名字为:SimpleControllerDB;开关对应:SimpleSwitchDB。严重需要注意的地方,这里选用的是DB。因为从从零开始学习Z-Stack之1上可以看到DB与EB的区别,而这里用DB的硬件就足以应付。 编译下载我就不继续罗嗦了。

咱关心的几个问题不外乎就是表演过程和表演结果,以及初步看看为什么会有这样的结果产生,当然就得从程序上简单了解下。

首先打开Controller(也就是灯设备)的电源,那么LED2就会不停的闪烁,这个时候是设备正在初始化,让您选择设备以哪种类型启动,从程序可以看出: if ( keys & HAL_KEY_SW_1 ) {

if ( myAppState == APP_INIT ) {

// In the init state, keys are used to indicate the logical mode. // Key 1 starts device as a coordinator

zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );

if ( logicalType != ZG_DEVICETYPE_ENDDEVICE ) {

logicalType = ZG_DEVICETYPE_COORDINATOR;

zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType); }

// Do more configuration if necessary and then restart device with auto-start bit set

// write endpoint to simple desc...dont pass it in start req..then reset zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );

startOptions = ZCD_STARTOPT_AUTO_START;

zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );

zb_SystemReset(); }

如果按下S1(UP),那么作为协调器启动。 if ( keys & HAL_KEY_SW_2 ) {

if ( myAppState == APP_INIT ) {

// In the init state, keys are used to indicate the logical mode. // Key 2 starts device as a router

zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType ); if ( logicalType != ZG_DEVICETYPE_ENDDEVICE ) {

logicalType = ZG_DEVICETYPE_ROUTER;

zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType); }

zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );

startOptions = ZCD_STARTOPT_AUTO_START;

zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );

zb_SystemReset(); }

如果按下S2(RIGHT),设备作为路由器启动。

这里由于是第一个启动的设备,所以作为协调器启动,就按下UP,此时灯会有状态变化,最终结果是:LED2常亮,标示建立网络成功。如果您还有另外的灯设备就可以按下RIGHT让他们都作为路由器启动,由于本人这里只有两个节点,所以就只能有个协调器。 现在就来启动开关设备的电源,同样LED2会闪烁让您选择设备,但是在ZIGBEE中除了协调器和路由器就剩下终端设备了,所以开关就只能作为终端被启动,但是也需要通过按键来控制,从程序中可以看出: if ( keys & HAL_KEY_SW_1 ) {

if ( myAppState == APP_INIT ) {

// In the init state, keys are used to indicate the logical mode. // The Switch device is always an end-device

logicalType = ZG_DEVICETYPE_ENDDEVICE;

zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType); // Do more configuration if necessary and then restart device with auto-start bit set

zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );

startOptions = ZCD_STARTOPT_AUTO_START;

zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );

zb_SystemReset(); } else {

// Initiate a binding with null destination zb_BindDevice(TRUE, TOGGLE_LIGHT_CMD_ID, NULL); } }

if ( keys & HAL_KEY_SW_2 ) {

if ( myAppState == APP_INIT ) {

// In the init state, keys are used to indicate the logical mode. // The Switch device is always an end-device logicalType = ZG_DEVICETYPE_ENDDEVICE;

zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType); zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );

startOptions = ZCD_STARTOPT_AUTO_START;

zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );

zb_SystemReset(); } else {

// Send the command to toggle light

zb_SendDataRequest( 0xFFFE, TOGGLE_LIGHT_CMD_ID, 0, (uint8 *)NULL, myAppSeqNumber, 0, 0 ); }

}

无论是按下S1还是S2(UP或者RIGHT),开关设备均作为终端设备启动。

启动之后呢,灯的状态同样会发生一些变化,最终结果是:LED2快速闪烁,表明此时开关已经成功加入刚才灯设备建立的那个网络了。

那么接下来就要看这个例子的核心部分----------绑定!

首先按下灯设备(这里为协调器,如果有路由器也可以)的UP,那么程序中调用了: zb_AllowBind( myAllowBindTimeout );

函数,允许绑定,这个允许的时间据说只有10S,当然这个时间是可以调整的,因为这里的参数为:static uint8 myAllowBindTimeout = 10;至于这个时间怎么计算的就需要到某个函数zb_AllowBind里去分析了。zb_AllowBind规定这个参数为1~64,如果为0,表示为假,就是不允许绑定的意思。如果大于64的话,就一直为真,就是一直都允许绑定。好像似乎是这个意思。至于这个10S是怎么制定的呢,在这个函数内部调用了: osal_start_timerEx(sapi_TaskID, ZB_ALLOW_BIND_TIMER, timeout*1000); 因为osal_start_timerEx定时函数最小单位为mS,所以*1000就表示S了。 而在SAPI_ProcessEvent事件处理函数中ZB_ALLOW_BIND_TIMER事件处理如下: if ( events & ZB_ALLOW_BIND_TIMER ) {

afSetMatch(sapi_epDesc.simpleDesc->EndPoint, FALSE); return (events ^ ZB_ALLOW_BIND_TIMER); }

也就是定时取消绑定状态!!!

如果有人看着这些看不明白,那就把这个例子多看几遍,多跑几遍。一般如果您每天花费4个小时看这个例子,那么只需要一周事件,我想到时比我还精通明白的!

所以在10S之内,开关必须发起绑定,此时同样按下开关设备的UP,那么开关设备就调用了函数:zb_BindDevice(TRUE, TOGGLE_LIGHT_CMD_ID, NULL);发送一个绑定请求去寻求绑定设备。

一个设备允许绑定,一个设备发起绑定请求,两个是您情我愿的,所以就一拍即合,相当的登对!当然没有这么简单的哈,就如同两个人谈恋爱,至少也需要是一男一女啊,两个都是男或女那就太不正常了,ZIGBEE是个国际化的标准,当然不能有这种变态行为,所以也需要两个命令的属性是相反的,就例如这里的控制灯开关的命令,对于灯来说这个命令为输入,而对于开关来说这个命令是输出。所以一入一出刚好就登对。呵呵!! 绑定成功的表象是:开关设备的LED1快速闪烁。 void zb_AllowBindConfirm( uint16 source ) {

// Flash LED

HalLedSet( HAL_LED_1, HAL_LED_MODE_BLINK ); }

绑定成功了就可以发送灯控制命令了。按下RIGHT,调用了函数:

zb_SendDataRequest( 0xFFFE, TOGGLE_LIGHT_CMD_ID, 0,

(uint8 *)NULL, myAppSeqNumber, 0, 0 ); 可以看出发送了一个数据请求,显然是广播发送的,而命令为切换灯状态的TOGGLE_LIGHT_CMD_ID。当灯收到这命令,就有处理函数了:

void zb_ReceiveDataIndication( uint16 source, uint16 command, uint16 len, uint8 *pData ) {

if (command == TOGGLE_LIGHT_CMD_ID) {

// Received application command to toggle the LED HalLedSet(HAL_LED_1, HAL_LED_MODE_TOGGLE); } }

所以LED1显示状态发生改变。

此时这个例子已经接近尾声了,因为绑定成功开关能够控制灯了,但是既然可以绑定那么也可以接触绑定的,如果按下开关的DOWN,那么同样调用了发送绑定请求函数: zb_BindDevice(FALSE, TOGGLE_LIGHT_CMD_ID, NULL);

只是这里第一个参数为FALSE,所以就能解除绑定。如果某个开关被解除了绑定,那么此时就不能控制灯了。

在这个例子最后做个小结------绑定的好处。

绑定了之后,发送数据或者命令,就不需要设备的地址,因为这个命令只能在建立绑定间的设备中传输。------------绝对是我的理解!

还有,一个开关可以绑定多个灯,同样,一个灯可以同时与多个开关发生绑定。这个不代表本人观点,本人强力反对脚踏N只船!!!!!!

现在来简单分析下传感器的例子,由于前面灯的例子说的比较多,这里我就说少点。 中心节点对应SimpleCollectorEB ,传感器节点对应SimpleSensorEB。这里用到了EB,主要是因为DB没有串口硬件,而EB有,这个例子需要用到串口。

传感器的例子效果是:协调器可以收集传感器节点的温度信息并通过串口传输到PC机,如下图所示:


从零开始学习Zigbee开发 - 图文(10).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:2014高考物理大一轮复习讲义第十三章第3课时原子与原子核解读

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: