背景
最近在尝试使用CC2530芯片作为Zigbee终端,ESP32-C6芯片作为Zigbee协调器。Zigbee终端的PCB板上搭载了一个AHT20温湿度采集模块以及一个LED,ESP32-C6仅搭载了一个WS2812B的RGB灯模块。
在编写通信代码的过程中遇到非常多的问题:通信流程是怎样的?终端和协调器分别如何编写代码?终端如何发送数据?协调器如何接收数据?等等,本篇Blog将完整且细致地分析整个通信过程,将终端采集到的温度发送给协调器。【本篇blog仍需要一些zigbee基础】
版本
Zigbee终端:IAR10.10.1 + z-stack3.0.2;
Zigbee协调器:Arduino2.3.6 + ESP-IDF zigbee;
抓包工具:TiwsPC + Wireshark + CC2531 Dongle(硬件)。
这些工具中,每个软件都能轻易搜索并下载,仅提供TiwsPC的下载地址。CC2531 Dongle需要在某宝进行购买,我找到一个比较便宜的,花了13元。
正文
一、Zigbee终端
在上篇blog中,我尝试构建一个最小化的zigbee IAR项目,并且在项目末尾有提供一个空白的项目,如有需要可以下载(不需要积分)。
(一)项目架构

图1.1
- AHT20.c/h 温湿度采集模块驱动,主要提供了接口AHT20_get_humiture(float *temperature, float *humidity);供外部访问;
- humiture.c/h Zigbee终端的温湿度传输模块,主要作用是获取温湿度、zigbee初始化配置等等;
- light.c/h Zigbee终端的灯模块,主要作用是控制板载LED灯亮灭、zigbee初始化配置等,暂且不用。本文只传输温度。
- OSAL_GenericApp.c Zigbee OSAL初始化配置文档,用于Zigbee协议各个层次的初始化配置;
- sensor_cfg.c/h Zigbee一些公共属性、函数接口文件。
(二)必要参数设置
【注】:每段演示代码都会用~/filename.c/h的方式标注属于哪个文件。
0、通信机制初涉

图 1.1

图 1.2

图 1.3
图1.1和图1.2来自ESP-IDF zigbee官方文档,Zigbee设备(Device)支持多应用并行(Multiple Applications),每个应用作为独立功能模块,包含若干集群(Cluster),集群核心要素:
- 属性(Attributes):定义设备状态(如温度值、开关状态);
- 命令(Commands):实现操作指令(如读取属性、触发报警)。
Zigbee协议通过端点(Endpoint)实现通信隔离与路由,每个应用绑定唯一端点号(1-240),数据交换规则是设备间通信基于端点间的集群交互。
1、端点
~/sensor_cfg.h
#define endpoint_coordinator 0x01
#define endpoint_humiture 0x06
上述代码分别定义了协调器及温湿度采集模块的端点(EndPoint),端点值采用无符号8位整型类型进行表示,取值范围是0~255,每个ZigBee设备最多支持240个应用端点(1~240),其中的端点0为特殊端点,端点255用于向其他端点的广播,端点241~254是保留端点。
2、输入集群和输出集群
~/sensor_cfg.h
#define inclusters_humiture_length 3
#define outclusters_humiture_length 1
extern const cId_t inclusters_humiture[];
extern const cId_t outclusters_humiture[];
~/sensor_cfg.c
const cId_t inclusters_humiture[inclusters_humiture_length] = {
ZCL_CLUSTER_ID_GEN_BASIC,
ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT,
ZCL_CLUSTER_ID_MS_RELATIVE_HUMIDITY
};
const cId_t outclusters_humiture[outclusters_humiture_length] = {
ZCL_CLUSTER_ID_GEN_BASIC
};
上述代码用于配置一个Zigbee温湿度传感器的集群(Cluster)信息,定义了设备支持的输入和输出集群。
其中,输入集群表示设备作为服务器端支持的集群,能够响应这些集群的请求或上报属性:
-
ZCL_CLUSTER_ID_GEN_BASIC:所有Zigbee设备必须支持的基本集群,包含设备厂商、型号等基本信息;
-
温度与湿度测量集群:传感器作为服务器,提供温湿度数据(通过属性或报告)。
输出集群表示设备作为客户端可能使用的集群,用于向其他设备发起请求,如控制其他设备。GEN_BASIC 在此处示例配置,可以删除。
3、简单描述符
~/sensor_cfg.h
#define device_version 1
#define device_flags 0
extern SimpleDescriptionFormat_t simple_desc_humiture;
~/sensor_cfg.c
SimpleDescriptionFormat_t simple_desc_humiture = {
endpoint_humiture,
ZCL_HA_PROFILE_ID,
ZCL_HA_DEVICEID_TEMPERATURE_SENSOR,
device_version,
device_flags,
inclusters_humiture_length,
(cId_t *)inclusters_humiture,
outclusters_humiture_length,
(cId_t *)outclusters_humiture
};
上述代码定义了Zigbee温湿度传感器的 简单描述符(Simple Descriptor),用于描述设备在Zigbee网络中的功能特性。
endpoint_humiture:设备的端点号,用于在同一设备中区分不同功能模块(如一个设备同时支持温湿度传感器和开关)。ZCL_HA_PROFILE_ID:表示使用 Zigbee家庭自动化(HA)配置文件,这是Zigbee联盟为智能家居设备定义的标准配置文件。通信时,同一链路需要保持终端和协调器使用同样的规范(PROFILE)。ZCL_HA_DEVICEID_TEMPERATURE_SENSOR:设备类型标识为温湿度传感器(设备ID为0x0302),也有温度传感器和湿度传感器。device_version:描述符版本,用于兼容性管理(例如固件升级时版本号变化)。device_flags:通常用于标识安全权限或设备能力(此处为0表示无特殊标志)。输入集群和输出集群:引用了之前定义的输入集群(inclusters_humiture)和输出集群(outclusters_humiture)数组,声明设备支持的集群列表。
简单描述符的作用:
-
设备发现与通信:当设备加入Zigbee网络时,协调器通过简单描述符了解其支持的集群、设备类型和端点信息。
-
端点功能绑定:其他设备(如协调器或网关)根据端点号和集群信息与传感器建立绑定关系。
4、属性定义
~/sensor_cfg.h
#define attrs_humiture_length 16
extern CONST zclAttrRec_t attrs_humiture[];
#define DEFAULT_TEMPERATURE_VALUE 2000 // 20.00
#define DEFAULT_HUMIDITY_VALUE 5000 // 50.00
static uint16 temperature_value = DEFAULT_TEMPERATURE_VALUE;
static uint16 humidity_value = DEFAULT_HUMIDITY_VALUE;
static const uint16 min_temperature_value = 0;
static const uint16 max_temperature_value = 10000; // 100.00
static const uint16 min_humidity_value = 0;
static const uint16 max_humidity_value = 10000; // 100.00
上述代码定义了 Zigbee 温湿度传感器的属性,主要包含温湿度传感器的属性列表,温湿度的采集数值(含最大最小数值)。
在Zigbee通信的过程中是不允许传输浮点类型的数值,所以需要将采集到的数值乘以100,随后在协调器端除以100即可得到准确的数值。
~/sensor_cfg.c
/*********************************************
* ATTRIBUTE DEFINITIONS
*********************************************/
/* BASIC CLUSTER */
const uint8 hw_revision = 1;
const uint8 zcl_version = 1;
const uint8 manufacturer_name[] = { 16, 'T','e','x','a','s','I','n','s','t','r','u','m','e','n','t','s' };
const uint8 model_id[] = { 16, 'T','I','0','0','0','1',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };
const uint8 date_code[] = { 16, '2','0','0','6','0','8','3','1',' ',' ',' ',' ',' ',' ',' ',' ' };
const uint8 power_source = POWER_SOURCE_MAINS_1_PHASE;
uint8 location_description[17] = { 16, ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };
uint8 physical_environment = PHY_UNSPECIFIED_ENV;
uint8 device_enable = DEVICE_ENABLED;
const uint16 cluster_revision = 0x0001;
CONST zclAttrRec_t attrs_humiture[attrs_humiture_length] = {
/* [IN] ZCL_CLUSTER_ID_GEN_BASIC */
{
ZCL_CLUSTER_ID_GEN_BASIC,
{
ATTRID_BASIC_HW_VERSION,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ,
(void *)&hw_revision
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{
ATTRID_BASIC_ZCL_VERSION,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ,
(void *)&zcl_version
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{
ATTRID_BASIC_MANUFACTURER_NAME,
ZCL_DATATYPE_CHAR_STR,
ACCESS_CONTROL_READ,
(void *)&manufacturer_name
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{
ATTRID_BASIC_MODEL_ID,
ZCL_DATATYPE_CHAR_STR,
ACCESS_CONTROL_READ,
(void *)&model_id
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{
ATTRID_BASIC_DATE_CODE,
ZCL_DATATYPE_CHAR_STR,
ACCESS_CONTROL_READ,
(void *)&date_code
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{
ATTRID_BASIC_POWER_SOURCE,
ZCL_DATATYPE_UINT8,
ACCESS_CONTROL_READ,
(void *)&power_source
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{
ATTRID_BASIC_LOCATION_DESC,
ZCL_DATATYPE_CHAR_STR,
(ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
(void *)&location_description
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{
ATTRID_BASIC_PHYSICAL_ENV,
ZCL_DATATYPE_CHAR_STR,
(ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
(void *)&physical_environment
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{
ATTRID_BASIC_DEVICE_ENABLED,
ZCL_DATATYPE_BOOLEAN,
(ACCESS_CONTROL_READ | ACCESS_CONTROL_WRITE),
(void *)&device_enable
}
},
{
ZCL_CLUSTER_ID_GEN_BASIC,
{
ATTRID_CLUSTER_REVISION,
ZCL_DATATYPE_UINT16,
ACCESS_CONTROL_READ,
(void *)&cluster_revision
}
},
/* [IN] ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT */
{
ZCL_CLUSTER_ID_MS_TEM

&spm=1001.2101.3001.5002&articleId=147545150&d=1&t=3&u=62c66932bca04235955abe4775dd58fa)
2219

被折叠的 条评论
为什么被折叠?



