从零开始学习Z-Stack之9
接到昨天的继续忽悠,话说: 2、SimpleApp “这个例子我基本跑通了,可是鉴于时间的关系,没有来得及打字了,所以就留到下一次了,时间真是如流水啊-------------------快!….” 这个例子里面有两个演示:一个是灯与开关的控制实验,一个温度传感器实验。咱一个个来,不忙。 灯与开关实验 在这个例子中灯对应的工程名字为: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机,如下图所示: 可以看到能够看到节点的温度和电源电压。 具体实现与灯的例子稍区别,但是本质的原理是一样的,先选择设备类型,然后建立绑定,最后收集信息。这里建立绑定的区别在于,只要中心节点允许绑定(与前面操作一样),然后传感器节点是自动发送绑定请求的: osal_start_timerEx( sapi_TaskID, MY_FIND_COLLECTOR_EVT, myBindRetryDelay ); 定时去产生发MY_FIND_COLLECTOR_EVT事件: if ( event & MY_FIND_COLLECTOR_EVT ) { // Find and bind to a collector device zb_BindDevice( TRUE, SENSOR_REPORT_CMD_ID, (uint8 *)NULL ); } 这个事件就是发送绑定请求的。 至于绑定后的现象与前面一样了。 最后通过串口调试工具就能看到前面那个图的效果了!!!!!!!!!!!!! 这里的温度为42,这个肯定不可能的,不然我就被蒸发掉了哈!因为采用的是芯片内部集成的温度传感器,这个传感器做实验还可以,因为可以看见温度的变化,但是其准确性是在不敢恭维。TI也是的,做了温度传感器,还超级不准确,还不如不做,只有还可以降低硬件成本,几乎没有任何使用价值!!! 不知道各位看官看到这里有何感想,我想都会觉得我写的乱七八糟,因为我也是兴之所至,毫无章法的。有任何疑问欢迎来函交流:peterpanjy@163.com。建议有以书面的形式集中提出交流意见、问题等。本人晚上回家与大家一起学习进步!!!
今天完成的比较早,这个要归功于昨天晚上的功劳。不过还是到此结束,我也需要一点私人空间,看会电影!!!!!!!!!!!!!!
YYYtech于成都 2008-8-6 21:27
|
文章评论(0条评论)
登录后参与讨论