ZigBee学习——基于AF的数据通信

2024-02-19 18:52
文章标签 学习 zigbee 数据通信 af

本文主要是介绍ZigBee学习——基于AF的数据通信,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、简单描述符
    • 1.1 简单介绍
    • 1.2 简单描述结构体介绍
    • 1.3 结构体中的簇
    • 1.4 应用场景
  • 二、AF通信原理
    • 2.1 通信过程
    • 2.2 端点号分类
    • 2.3 通信方式
    • 2.4 注册简单描述符
  • 三、数据发送API简介
    • 3.1 AF层数据发送API
    • 3.2 基于AF层封装的通信API
      • 3.2.1 点对点通信API
      • 3.2.2 广播通信API
      • 3.2.3 组播通信API
  • 四、实战

一、简单描述符

1.1 简单介绍

  在ZigBee中,简单描述符(Simple Descriptor)是一种数据结构,它提供了关于某个设备的端点(EndPoint)的基本信息。简单描述符包括端点的ID,设备的类型,以及设备支持的簇(Cluster)。
  如果设备是一个智能灯泡,那么它可能有一个简单描述符,其中的设备类型就是"智能灯泡",支持的簇可能包括"开关控制",“亮度控制"等等。这样,当其他设备(比如一个开关或者调光器)想与这个智能灯泡交互时,就可以通过查看这个简单描述符来了解该设备的功能以及如何与其交互。
  比如说,一个智能开关在连接一个智能灯泡时,它可以查看灯泡的简单描述符,发现这个灯泡支持"开关控制"和"亮度控制”,那么,这个开关就知道它可以通过发送特定的信号来控制灯泡的开关和亮度。
  所以,可以说简单描述符在ZigBee网络中起到了"设备说明书"的作用,它描述了设备的功能以及设备之间如何交互,帮助设备之间的正常通信。

1.2 简单描述结构体介绍

  简单描述符结构体

typedef struct{
uint8    EndPoint;//端点号
uint16   AppProfId;//描述所在应用场景,例如家居自动化
uint16   AppDeviceId;//设备ID
uint8    AppDevVer:4;//由开发者自定义,表示版本号
uint8    Reserved:4;//保留字段
uint8    AppNumInClusters;//端点支持的输入簇个数
cId_t    *pAppInClusterList;//指向输入簇列表的指针
uint8    AppNumOutClusters;//端点支持的输出簇个数
cId_t    *pAppOutClusterList;//指向输出簇列表的指针
}SimpleDescriptionFormat_t;
  • 端点号:EndPoint,可以理解为简单描述符的编号,取值范围是0~255。在同一个ZigBee设备中,每一个简单描述符都有一个不同的端点号,可以利用端点号来找到对应的简单描述符。
  • AppProfId:Profile ID,表示这个简单描述符所属的应用场景。这个应用场景可以是家居自动化、智能照明和智慧零售等。ZigBee联盟为不同的场景定义了对应的ID值,称为Profile ID。
  • AppDeviceId:Device ID,表示这个简单描述符所属的设备类型。这个设备类型可以是插座、灯或者传感器等。类似地,ZigBee联盟为不同类型的设备定义了对应的ID值,称为Device ID。
  • AppDevVer:这个值可以由开发者自定义,用来表示版本号。
    Reserved:保留字段,暂时可以忽略。
  • Cluster:簇,或者集群,可以划分为输入簇(In Cluseter)和输出簇(Out Cluster),用来描述这个服务的具体内容。一个简单描述符中可以包含多个Cluster,这些Cluster共同描述了这个服务的具体内容,后续章节将会详细讲解。

1.3 结构体中的簇

  在ZigBee中,"簇"或"集群"是指一组基于某种特定功能组合在一起的设备。这些设备能够按照固定规则进行交互或执行特定任务。
  比如,我们可以把灯泡、开关和调光器看作一个“簇”。开关负责控制灯泡的开启或关闭,调光器则可以调节灯泡的亮度。它们三个围绕着"控制照明"这个功能组成了一个簇。
  在这个簇中,当你使用开关,开关会发送一个信号给灯泡,告诉它要开或者关。如果你用调光器,调光器会发送一个信号给灯泡,告诉它调到什么样的亮度。这就是开关、调光器和灯泡在这个“簇”中的交互方式。
所以,通过设置簇,我们可以更好地将相关设备组织在一起,更有效地实现环境控制、智能家居等复杂应用。不同的簇可以包含不同类型的设备,以满足不同场景的需求。

1.4 应用场景

简单描述符一般定义在App层,如下图所示:
在这里插入图片描述

SimpleDescriptionFormat_t zclSampleSw_SimpleDesc =
{SAMPLESW_ENDPOINT,                  //  端点号ZCL_HA_PROFILE_ID,                  //  设备应用领域IDZCL_HA_DEVICEID_ON_OFF_LIGHT_SWITCH,//  设备类型IDSAMPLESW_DEVICE_VERSION,            //  版本号SAMPLESW_FLAGS,                     //  保留字段ZCLSAMPLESW_MAX_INCLUSTERS,         //  最大输入簇数量(cId_t *)zclSampleSw_InClusterList, //  表示输入簇列表ZCLSAMPLESW_MAX_OUTCLUSTERS,        //  最大输出簇数量(cId_t *)zclSampleSw_OutClusterList //  表示输出簇列表
};

二、AF通信原理

2.1 通信过程

AF的全称是Application Framework,中文意思是应用框架,AF层也就是应用框架层,它在ZigBee协议层次中位置如图所示。开发者可以基于这个层次编写代码,实现ZigBee设备之间的数据通信。
在这里插入图片描述
图片来源于:善学坊

需要知道的是ZigBee在很多情况下是基于服务的,也就是单单依靠网络地址是不够的,还需要端点号来确认通信的最终目的。

处于网络中的ZigBee设备都会被分配一个网络地址,用于标识设备所处的位置。通过这个网络地址就可以找到对应的设备了。我们知道ZigBee 3.0是利用简单描述符来描述特定的服务的,并且设备上的每个简单描述符都配有一个唯一的端点号
在这里插入图片描述
图片来源于:善学坊

  假设现在ZigBee网络中有一个协调器和一个智能插座终端,这个智能插座的网络地址为0x0EF1,并且配有一个简单描述符描述这个插座具备的一些功能,这个简单描述符的端点号是8。

  如果协调器要向这个插座发送一个打开指令,不能简单地使用网络地址0x0EF1来说明把命令发送给这个插座,还需要利用端点号8来说明把命令发送给端点号8对应的服务。

2.2 端点号分类

端点号的分类
端点号的取值范围是0~255,其中:

  • 端点号0被分配给了ZDO(ZigBee Device Object)。
  • 端点号255是广播,也就是向这个端点号发送数据时,设备的所有服务(简单描述符)都会收到这个数据。
  • 端点号241~254是暂时保留起来的端点号,暂时不能使用。
  • 剩下的端点号1~240可以供开发者自由地使用,例如读者一直学习的SampleSwitch这个工程所使用的端点号可以在工程中找到,如图所示。

在这里插入图片描述

2.3 通信方式

ZigBee支持3种通信方式,分别是点对点、广播和组播。

  • 点对点通信(P2P,Peer to Peer):顾名思义,就是两个设备之间一对一通信。
  • 广播:给其他的所有设备发送数据。
  • 组播:给一部分的设备发送数据,这里的“一部分”说的就是一个特定的组。

2.4 注册简单描述符

在使用AF通信前,需要先注册简单描述符并且让对应的端点号生效,或者说让这个简单描述符对应的服务生效。这个流程是:

(1)创建一个简单描述符。在讲解简单描述符的章节中,我们已经看到相关的定义了。

(2)注册这个简单描述符。打开配套的工程,在zcl_samplesw.c文件中的zclSampleSw_Init()这个函数中可以找到以下代码,如图所示。
在这里插入图片描述

在应用层初始化函数zclSampleSw_Init()中,有两种注册简单描述符的方法:
(1)可以调用bdb_RegisterSimpleDescriptor()来在BDB中注册简单描述符。
(2)也可以直接调用afRegister()直接在AF中注册简单描述符。

在注册完简单描述符之后,就可以使用AF层的通信API来收发数据了。

三、数据发送API简介

3.1 AF层数据发送API

  数据发送API
在AF.c这个文件中可以找到一个名为AF_DataRequest()的数据发送API,如图所示。
在这里插入图片描述
  参数说明

/*
* @param dstAddr 目标设备地址,包含网络地址和端点号
* @param srcEP 发送设备的简单描述符
* @param cID Cluster ID,后续章节将会详细讲解
* @param len 待发送数据的长度
* @param buf 待发送的数据
* @param transID 传输ID,可以用来给每一次发送的数据包编一个号
* @param options 附加选项,可以用来给这次数据发送添加一些说明                      
* @param radius 最大的路由跳转级数
*/
afStatus_t AF_DataRequest(afAddrType_t *dstAddr, endPointDesc_t *srcEP,uint16 cID,uint16 len, uint8 *buf,uint8 *transID,uint8 options,uint8 radius );

协议栈里面的SampleSwitch这个例程基于这个API封装出了点对点通信API、广播通信API和组播通信API。

3.2 基于AF层封装的通信API

3.2.1 点对点通信API

/*
* @param destNwkAddr 目标设备的网络地址
* @param cid Cluster ID,后续课程将会详细讲解
* @param len 数据长度
* @param data 数据内容
*/
static void zclSampleSw_AF_P2P(uint16 destNwkAddr, uint16 cid, uint8 len, uint8 *data)
{    afAddrType_t dstAddr; //寻址信息配置 static uint8 transferId = 0;//传输ID,是数据包的标识符/* Destination */    dstAddr.addrMode = afAddr16Bit;// 设置目标地址模式为16位网络地址,表示使用P2P的通信方式dstAddr.addr.shortAddr = destNwkAddr;//目标设备的网络地址  dstAddr.endPoint = SAMPLESW_ENDPOINT;//目标设备的端点号transferId++;    AF_DataRequest(&dstAddr, &sampleSw_TestEp,//已经创建好的简单描述符cid,    len, data,    &transferId,AF_DISCV_ROUTE,//进行路由扫描操作,用于建立发送数据报文的通信路径。关于这个参数,暂时保持例程默认的代码就可以了AF_DEFAULT_RADIUS);//指定最大的路由跳转级数
}

这个API中使用了一个afAddrType_t类型变量,该变量类型被定义在AF.h中,用于配置寻址信息。这个变量定义如下:

typedef struct
{union{uint16      shortAddr;ZLongAddr_t extAddr;} addr;afAddrMode_t addrMode;uint8 endPoint;uint16 panId;  // used for the INTER_PAN feature
}  afAddrType_t;

这个API中也使用了一个afAddrMode_t变量,表示地址模式(类型),用于说明使用的是点对点、广播还是组播的通信方式。同样地,可以查看其定义,代码如下:
在这里插入图片描述

可以看到,afAddrMode_t是一个枚举类型变量。

在zclSampleSw_AF_P2P()函数的的最后,可以看到最终就是调用AF_DataRequest()来发送数据的。开发者也可以基于AF_DataRequest()来编写自己的点对点通信API,而不使用这个工程中的默认的这个zclSampleSw_AF_P2P()。

3.2.2 广播通信API

在zcl_samplesw.c文件中可以找到广播通信API,代码如下:

/*
* @param cid Cluster ID
* @param len 待发送数据的长度
* @param *data 待发送数据的内容
*/
static void zclSampleSw_AF_Broadcast(uint16 cid,uint8 len,uint8 *data)
{afAddrType_t dstAddr;  static uint8 transferId = 0;  /* Destination */  dstAddr.addrMode = afAddrBroadcast;   // 使用广播模式dstAddr.addr.shortAddr = 0xFFFF; // 广播地址dstAddr.endPoint = SAMPLESW_ENDPOINT; // 目标设备的端点号/* Transfer id */  transferId++;  /* Send */  AF_DataRequest(&dstAddr, &sampleSw_TestEp,//已经创建好的简单描述符cid,  len, data,  &transferId,AF_TX_OPTIONS_NONE,AF_DEFAULT_RADIUS );//指定了最大的路由跳转级数
}

从广播通信API的定义可以发现,它和点对点通信API是相似的。广播通信API中使用了网络地址0xFFFF,这表示把数据发送到该网络上的所有设备中。但其实ZigBee的广播地址一共有3个,如下所示:

0xFFFF:广播给该网络中的所有设备
0xFFFD:只广播给该网络中打开收听功能的设备
0xFFFC:只广播给该网络中的协调器和路由设备

同样地,开发者也可以基于AF_DataRequest()来编写自己的广播通信API,而不使用这个工程中的默认的这个zclSampleSw_AF_Broadcast()

3.2.3 组播通信API

使用组播通信API,可以只给指定的一组设备发送数据。在zcl_samplesw.c文件中可以找到组播通信API,代码如下:

/*
* @param groupId 组ID
* @param cid ClusterID,后续章节将会详细讲解
* @param len 待发送数据的长度
* @param data 待发送数据的内容
*/
static void zclSampleSw_AF_Groupcast(uint16 groupId,uint16 cid,uint8 len,uint8 *data)
{    afAddrType_t dstAddr;    static uint8 transferId = 0;    /* Destination */    dstAddr.addrMode = afAddrGroup;//使用组播通信模式dstAddr.addr.shortAddr = groupId;dstAddr.endPoint = SAMPLESW_ENDPOINT;//组中的设备的端点号/* Transfer id */    transferId++;   /* Send */    AF_DataRequest(&dstAddr, &sampleSw_TestEp,//已经创建好的简单描述符cid, len, data,    &transferId, AF_TX_OPTIONS_NONE,AF_DEFAULT_RADIUS );//指定最大的路由跳转级数,暂时可忽略
}

四、实战

在学习完AF层通信API后,本章将以实验的方式讲解如何使用这些API,实验设备包含一个协调器和一个路由器(或终端),内容是:

  • 路由器(或终端)定时地通过点对点的方式向协调器发送数据。
  • 让路由器(或终端)加入到一个组中。
  • 协调器定时地发送广播数据和组播数据。

这部分根据善学坊教程:3.4 ZigBee 3.0 通信实验

这篇关于ZigBee学习——基于AF的数据通信的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/725621

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件