Zigbee 控制节点数据收发流程|学习笔记

简介: 快速学习Zigbee 控制节点数据收发流程

开发者学堂课程【嵌入式之RFID开发与应用2020版:Zigbee 控制节点数据收发流程】学习笔记与课程紧密联系,让用户快速学习知识

课程地址https://developer.aliyun.com/learning/course/665/detail/11140


Zigbee 控制节点数据收发流程

 

Zigbee 控制节点数据收发流程

刚刚提到了本地的数据,包括串口还有按键的数据处理,接下来是网络数据的处理,网络数据包括数据的发送和接收的基本流程。首先第一,假如需要发送数据应该如何操作?刚才当按下按键 KEYBOARD,那么下面四句话都是在进行发数据的流程。

debug("key1

down\n");my_SendPointToPointMessage(SAMPLEAPP_SENSOR_CLUSTERID,SET_TEMP_ADJUST_OPEN);

my _SendPointToPointMessage(SAMPLEAPP_SENSO_CLUSTERID,SET _HUMI _ADJUST_OPEN);

my _SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_TEMP_ADJUST_OPEN);

my _SendPointToPointMessage(SAMPLEAPP_CTRL_CLUSTERID,SET_HUMI_ADJUST_OPEN);

只有以下三行代码是在完成本地点灯的操作。

LOCAL_LED1 = SWITCH_LED_OPEN;

LOCAL_LED2 = SWITCH_LED_OPEN;

SWITCH_LED = SWITCH_LED_OPEN;

并且操作完之后会进行返回 return(events ^ DEMO_KEYBOARD_)。从这个结果可以看出轮循事件,这里已经处理完此事件,剩下的事件交由下一次处理。

到底应该怎样完成数据的发送?这里书写了发送点到点的函数接口,其需要两个参数。第一是发送的对象是什么类型,这里简单做了约定:传感器规定为1,控制器规定为2,以及发送的内容,将所有的内容全部设定为字符串,其实字符串的处理,更能提高其通用性。

整个的内容,分为温度与湿度。temp 是对温度的调节,例如打开加热器(open)或者关闭了加热器(close),humi 是对湿度的调节,例如打开加湿器(open)或者关闭加湿器(close),那么当然还可以分为自动控制(auto)和手动控制(manual),大概就是这几种控制方法。

接下来看第一个发送的是将温度调节开关打开,查看发送的目标,点击进去之后,第一件事情需要明确,程序比较乱,主要原因是其把协调器的代码,终端的代码,甚至是路由器的代码,包括控制器的代码,传感器的代码,全部融入到这一个程序里面,这样看起来就比较费劲。这里是可以分开的,分开的操作就是将其分成多个文件,比如其中一个文件,表示的是传感器。另一个表示的是控制器,再另一个则是表示协调器,这样的话就可以将其分开。

先按照这样来看,这里有一个函数,有一个全局变量,这是为了给自己提供当前身份的辨识,比如在程序运行的过程中,会混淆自己当前的身份,那么这个全局变量,能够告诉当前身份手机是设备、协调器、还是路由器。所以在发送此接口的此函数时,此函数有可能被协调器调用,有可能被传感器调用,也有可能被控制器调用,那么不管怎么样,如果现在调用此函数的调用者是 DEV_END_DEVICE 就表示是设备在调用,那么其会将 cid 设成传感器(sensor),控制器与传感器都为终端,然而不是控制器的原因是:控制器一般不往外发送数据,就是控制器是执行机构,没有必要对外发送数据。但传感器不行,其需要对外发送数据,也需要接受数据,需要去采集。

将地址设成零的原因是:如果数据需要发送给协调器,协调器的短地址默认都是零,只有加入网络的其他普通设备的地址才是非零,并且由协调器分配,所以其永远为零。只要为零,就表示数据肯定已经发送给协调器,这就是 CLUSTERID。

接下来看协调器,协调器具体如下代码。

if(obj== SAMPLEAPP_SENSOR_CLUSTERID{

my_DstAddr.addr.shortAddr =join_addr[SAMPLEAPP SENSOR CLUSTERID-1].addr;

cid=SAMPLEAPP SENSORCLUSTERID;

}else if(obj== SAMPLEAPP CTRL CLUSTERID)!

my_DstAddr.addr.shortAddr=join_addr[SAMPLEAPP CTRLCLUSTERID-1].addr;

cid=SAMPIFAPP_CTRL_CLUSTERID:

先不考虑协调器的问题,先看终端。终端如果需要发送数据,(例子这里路由器没有实现,如果实现可以在方面直接加上,此次演示先不进行演示。)发送需要了解地址,地址决定发送的目标,cid 就是命令。因为存在很多功能,这里功能分成两种功能:第一个是 SENSOR,另一个是 CTRL,也就是控制和采集折两种功能。

#define SAMPLEAPP_SENSOR_CLUSTERID  1

#define SAMPLEAPP_CTRL _CLUSTERID  2

#define SAMPLEAPP_MAX_CLUSTERS  2

最后需要调用函数,调用 AF_DataRequest 函数,在课件里面有详细介绍,例如源端点,簇命令(cid),就是刚才提到的 SENSOR,然后长度等等一些参数,基本都很容易能明确这些参数。

注册函数:

afRegister(endPointDesc_t*epDesc)

注册过程就是向端点应用链表 epList 增加一个节点

发数据函数:

AF DataRequest(

afAddrTypet*dstAddr//目标地址

endPointDesct*srcEP//源端点

uint16clD//族命令 ID,对于接收方可以通过该命令来区分数据包 uint16len,//发送数据的长度

uint8*buf//发送数据的起始地址

uint8*transID.//事务 ID,可以是包计数器,用于信息确认

uint8options,//告知 AF 层做的一此预处理,一般为 AF DISCV ROUTE uint8radius)//转发数据最多经过的路由深度(AF DEFAULT RADIUS)

填好之后,函数会发送到协调器,而协调器就会收到数据,协调器收到数据的现象是什么?回到 My_process event 页面,协调器收到数据,首先收到了 SYS_EVENT_MSG,有事件。然后在下面看到Incomeing_msg,这表示协调器已经收到数据,然后再从 MSGpkt 里提取数据,可以从这里看到数据的长度,数据的内容。内容拿出来之后,首先将内容进行打印,就是收到是数据是什么类型,然后判断 clusterID,clusterID 就是控制的方式:控制器以及传感器。因为这里仅仅制作了这两种控制器,先不看控制器,因为刚是传感器传输的,传感器如下代码所示。

debug("采集终端入网地址:0x%x\n",pkt->srcAddr.addr.shortAddr);

join addrSAMPLEAPP SENSOR CLUSTERID-11.type =SAMPLEAPP SENSOR CLUSTERID;

Join_addr[SAMPLEAPP_SENSOR_CLUSTERID-11.addr=pkt->srcAddr.addr.shortAddr;

break;//收集完地址退出

其实这里的控制器有点多余,如果为协调器发出控制,是有益的,但是对控制节点,其实没必要发控制信号。

如果是传感器应该怎么做:首先判断当前接收数据的节点是不是协调器,如果是协调器,判断是不是确认信号,如果是确认信号,会做确认信号的事情,如果不是确认信号,那么会判断收到的数据是温度湿度调节打开还是关闭,是否为周期性的采集数据,也或者要获取传感器的温湿度。所以这里做了些分解,刚才发的是温度调节开关的打开,那时候其会将 switch_led 打开。发送和接受都看完了,现在要进行捎代码了,将程序捎进去。但这里出现了问题。如果此数据发给协调器,让协调器去开关灯的意义不是很大,所以这里让协调器将数据发给控制器,因为控制器本来就是专门负责控制设备。流程其实一样,就是发送方,比如当前协调器,(这里全部发送)如果发给控制器,其调用的接口,不是 END_DEVICE,而是协调器。那么协调器在发数据时,这里要提前说一个问题,当不管是传感器还是控制器,加入网络之后,首先设备的地址其实是动态分配的,所以协调器最好是能够建立数组(join_addr)。数组应该可以维护加入到网络的每一个设备,这样便于后期管理。

这里包含了两个信息:第一个,设备的类型,是传感器 SENSOR,还是控制器 CTRL,以及其地址是多少,记录到数组里。

先看数据的收发。其得到的 cid,如果是控制类的就是 CTRL,然后 cid,此过程就不进行重复了,与刚才过程一样,此数据会发给控制器。

接下来重新编译,首先是协调器的代码,此代码刚才已经编译并下载。所以没有必要再重新下载协调器的内容。

image.png

现在应该下载控制器,但控制器存在问题:因为代码是控制器和传感器共用的,所以在头文件里有个说明,例如将宏定义成1表示控制节点,如果为0是温湿度采集节点。

#define CTRL_OR_GATHER  1//0表示温湿度采集节点。1表示控制节点

#define CLIENT_AFFIRM  “affirm”

#define SAMPLEAPP_PROFID 0x0F08

#define SAMPLEAPP_DEVICEID 0x0001

#define SAMPLEAPP_DEVICE_VERSION  0

#define SAMPLEAPP_FLAGS 0

这决定协调器在确认加入者身份时,也就是通过 send_coord_affirm(发送身份确认),确认其身份是控制器还是传感器,这与协调器发的内容不同,所以这里需要稍微更改,就是不同的设备可能不一样。接下来将其改成 END_DEVICE,重新编译。编译完成后,先把下载的拔下来,插到继电器上,然后就给其下载程序,下载完成后把串口打开,然后复位,可以看到协调器建立网络成功。

image.png

成功之后,把另外控制器打开,马上就会检测到控制终端入网。而且入网地址是动态分配,接下来按键,观察到继电器的灯亮了,继电器也发出了声音,表示信号已经传输成功,试验其关闭、打开功能可以正常使用。

 image.png

整个过程其实就是协调器给控制器发数据,控制器收数据的过程。所以说整个过程也是控制器的数据收发过程,那么后面再去看数据采集的过程。

相关文章
|
运维 网络协议 安全
长连接网关技术专题(十):百度基于Go的千万级统一长连接服务架构实践
本文将介绍百度基于golang实现的统一长连接服务,从统一长连接功能实现和性能优化等角度,描述了其在设计、开发和维护过程中面临的问题和挑战,并重点介绍了解决相关问题和挑战的方案和实践经验。
467 1
|
C语言
C语言循环结构
C语言循环结构
133 0
|
Java 中间件 数据库连接
分库分表的4种方案
分库分表的4种方案
1978 0
|
3月前
|
存储 人工智能 资源调度
MCP协议深度集成:生产级研究助手架构蓝图
本文详解基于LangGraph与MCP协议构建研究助手的技术方案,涵盖双服务器集成、状态化智能体设计与用户元命令控制,助你掌握生产级代理系统开发要点。
337 1
|
IDE 测试技术 编译器
linux安装Pycharm
linux安装Pycharm
411 0
|
4月前
|
人工智能 自然语言处理 前端开发
牛x,这也许是Coze(字节)平替,AIFlowy:企业级AI应用开发平台
AIFlowy 是一个基于 Java 的企业级开源 AI 应用开发平台,专为中国 toB 场景打造。它提供可视化 AI 工作流编排、大模型配置与市场、RAG 知识库、Bot 应用、素材中心及系统管理模块,帮助企业快速构建和部署 AI 应用。平台支持多样模型接入、复杂流程组装、素材生成及系统治理,适用于智能客服、知识运营、营销素材生产等场景。技术栈成熟,本土化支持良好,具备完整的开发、部署和管理能力,是企业级 AI 落地的理想选择。
421 0
|
安全 编译器 C++
constexpr、const和 #define 的比较
本文比较了 `constexpr`、`const` 和 `#define` 在 C++ 中定义常量和函数的优缺点。`constexpr` 用于编译期求值,提供更高的性能和类型安全性;`const` 保证变量在运行期间不可修改,增强代码可靠性;`#define` 用于宏定义,适用于简单的常量和跨平台兼容性。选择时应根据具体需求和代码上下文决定。
|
并行计算 Ubuntu PyTorch
Ubuntu 18.04 + CUDA 11.3.0 + CUDNN 8.2.1 + Anaconda + Pytorch 1.10(上)
Ubuntu 18.04 + CUDA 11.3.0 + CUDNN 8.2.1 + Anaconda + Pytorch 1.10
684 0
|
算法
基于DSP的音频信号降噪技术
基于DSP的音频信号降噪技术
665 4
|
开发工具 git
git设置默认编辑为vim
f you want to set the editor only for Git, do either (you don’t need both): Set core.editor in your Git config: git config --global core.
3401 0