🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
>[success] 导师视频讲解:[去听课](https://www.bilibili.com/video/BV1k34y1D7Vz/) >[success] **技术支持说明:** >**1**.一般以自主学习为主 > **2**.可到官方问答社区中提问:[**去提问**](https://bbs.csdn.net/forums/zigbee) > **3**.工程师**会尽快**解答社区问题,但他们是一线开发,【**难以保证**】解答时效,解答辛苦,感谢理解! <br/> 本节课将以实验的方式讲解如何使用ZCL通信API发送On/Off命令,实验设备包含一个网关(协调器)和一个智能插座(终端或路由器),内容是当智能插座加入到网络后,网关自动定期地向这个智能插座发送On和Off指令来控制智能插座的开关。 <br/> ## **智能插座开发** 打开zcl\_samplesw.c文件在应用初始化函数zdSampleSw\_Init中可以找到如下代码: ![](https://img.kancloud.cn/3d/e9/3de92a4a7324ed5a0faf38d4e7c46264_832x454.png =600x) ### \#else与#endif中的代码是当设备处于终端(或路由器)角色时执行,其中的bdb\_StartCommissioning函数是用于组建网络的的,在BDB章节中已经讲解过。 ### zclSampleSw\_DeviceAnnce函数是由笔者自定义的,用于向整个网络广播一个数据包,该数据包中包含本设备的地址。当协调器收到这个数据包时,就知道这个设备的地址信息了。其定义代码如下: ### ``` static void zclSampleSw_DeviceAnnce( void ) {     ZDP_DeviceAnnce( NLME_GetShortAddr(),//获取本设备的网络地址(短地址) NLME_GetExtAddr(),//获取本设备的物理地址(通常就是MAC地址)         ZDO_Config_Node_Descriptor.CapabilityFlags,//暂不展开简介,可忽略 0//暂不展开讲解,可忽略 );     } ``` ### 该函数调用了ZDP\_DeviceAnnce函数,这是一个协议栈的API。可以套用上述代码来实现向网络中广播本设备的地址信息。 <br/> #### **处理指令** 在处理On/Off命令前,需要先在ZCL命令回调函数列表中注册一个回调函数,即在zcl\_samplesw.c文件中添加zclSampleSw\_OnOffCB函数,如下图所示。 ![](https://img.kancloud.cn/81/54/81541c0f618c103351b285e912ceee37_810x416.png =600x) ### zclSampleSw\_OnOffCB函数的定义代码如下: ``` 1.static void zclSampleSw_OnOffCB( uint8 cmd )     2.{     3.    if(cmd == COMMAND_ON) // 命令为ON时   4.    {     5.      HalLcdWriteString("Set ON", 4);  // 打印信息到屏幕   6.           7.      HalLedSet(HAL_LED_ALL, HAL_LED_MODE_ON);  // 开启所有LED   8.    }     9.    else if(cmd == COMMAND_OFF) // 命令为OFF时   10.    {     11.      HalLcdWriteString("Set OFF", 4);  // 打印信息到屏幕   12.           13.      HalLedSet(HAL_LED_ALL, HAL_LED_MODE_OFF);  // 关闭所有LED   14.    }     15.} ``` <br/> ## **网关开发** 网关主要完成这两件事情: * 接收并处理智能插座广播的地址信息 * 启动一个周期性事件来周期地向智能插座发送On/Off指令 #### **接收地址信息** 当协调器接收到由智能插座广播(Annce)的地址消息时,会产生系统事件ZDO\_CB\_MSG,可以在应用层事件处理函数中处理事件,代码如下图所示。 ![](https://img.kancloud.cn/36/c5/36c56f632fd8a5fd0d8a69bcde4519c1_832x202.png =600x) ### 事件处理函数zclSampleSw\_ProcessZDOMgs的代码定义如下: ### ``` 1.static void zclSampleSw_processZDOMgs(zdoIncomingMsg_t *pMsg)   2.{   3. switch ( pMsg->clusterID )//判断消息中的Cluster ID 4. {   5. case Device_annce://如果是Device_annce 6. {   7. // 把目标设备的网络地址保存到全局变量中 8. zclSampleSw_OnOffTestAddr = pMsg->srcAddr.addr.shortAddr; 9. // 在屏幕上显示目标设备网络地址和提示信息 10. HalLcdWriteStringValue("Node:", pMsg->srcAddr.addr.shortAddr, 16, 3);   11. HalLcdWriteString("On/Off Test...", 4);   12.         13. //周期地产生SAMPLEAPP_ONOFF_TEST_EVT事件,即发送On/Off指令 14. osal_start_timerEx(zclSampleSw_TaskID,    15.                         SAMPLEAPP_ONOFF_TEST_EVT,//事件类型,在zcl\_samplesw.h文件中定义 16.                         SAMPLEAPP_ONOFF_TEST_PERIOD);//时间间隔,在zcl\_samplesw.h文件中定义  17. }   18.     break;   19.     default:   20.     break;   21. }   22.} ``` <br/> #### **处理SAMPLEAPP_ONOFF_TEST_EVT事件** 在zcl\_samplesw.c文件中找到zclSampelSw\_eventloop函数,添加事件处理代码,如下图所示。 ![](https://img.kancloud.cn/4a/e9/4ae9b73c64d1ffcc4e127e720e8beaf9_752x392.png =600x) <br/> #### **发送On/Off指令** 在SAMPLEAPP\_ONOFF\_TEST\_EVT事件处理代码中调用了zclSampleSw\_OnOffTest来发送指令,该函数定义如下: ### ``` static void zclSampleSw_OnOffTest(void)  {   afAddrType_t destAddr;//用于保存目标设备的地址信息 static uint8 txID = 0;   static bool  on   = true;//静态变量,指示智能插座的开关状态 destAddr.endPoint = SAMPLESW_ENDPOINT;//端点号 destAddr.addrMode = Addr16Bit;//地址模式(类型)为16为的地址,使用P2P的通信方式 destAddr.addr.shortAddr = zclSampleSw_OnOffTestAddr;//网络地址  if(on)  {//如果智能插座正在开启 HalLcdWriteString("Command: ON", 4);  // 屏幕打印提示信息 zclGeneral_SendOnOff_CmdOn(//发送打开命令 SAMPLESW_ENDPOINT,//端点号 &destAddr,//地址信息 TRUE,//TRUE表示属性关联命令 txID++); }   else//如果智能插座已关闭 {   HalLcdWriteString("Command: OFF", 4);  // 屏幕打印提示信息 zclGeneral_SendOnOff_CmdOff(//发送关闭命令 SAMPLESW_ENDPOINT,//端点号 &destAddr,//地址信息 TRUE,//TRUE表示属性关联命令 txID++); }   on = !on;//反转开关状态 } ``` <br/> ## **仿真调试** * 编译协调器工程,然后把固件烧录到其中一块开发板中,该开发板充当网关; * 编译终端(或路由器)工程,然后烧录到另外一块开发板中,该开发板充当智能插座; * 先后分别给网关和智能插座供电; * 智能插座会自动加入到网关创建的网络中,接着可以在智能插座的显示器中看到有网关发送过来的命令,如图所示。 ![](https://img.kancloud.cn/51/16/511634fc10916994e2c39996d081610a_276x244.png =150x) ![](https://img.kancloud.cn/cb/2b/cb2b554f3e7b6bc0ebdb3d509cdce53f_288x240.png =150x) <br/> <br/> ## **项目定制** * 如需项目定制开发,可扫码添加项目经理好友(注明“**项目定制**”) * 定制范围:**NB-IoT**、**CATn(4G)**、**WiFi**、**ZigBee**、**BLE Mesh**以及**STM32**、**嵌入式Linux**等IoT技术方案 * 善学坊官网:[www.sxf-iot.com](https://www.sxf-iot.com/) ![](https://img.kancloud.cn/ca/73/ca739f92cab220a3059378642e3bd502_430x430.png =200x) * 非项目定制**勿扰**,此处**非**技术支持