Zigbee高频问题集合

Zigbee 子设备开发


huanghuan
Posts: 202

持续补充中 。。。 欢迎各位开发者留言支持

huanghuan
Posts: 202

Re: Zigbee高频问题集合

1. 编译相关

1. 开发者确认各平台编译器软件版本:

PHY622X 平台需安装 keil v5.26 版本
MG21平台需安装IAR for ARM8.4版本
MG24平台需安装IAR for ARM9.3版本
TLSR8258 平台开发框架自带编译链不依赖外部编译器

2. 开发者遇到编译器打开时同时使用ide进行编译报错

PHY622X 平台遇到permission error
这是 keil打开时使用ide进行编译,请关闭keil后继续操作

Image

MG2x平台:FileExistsError: 当文件已存在时,无法创建该文件。
问题原因: IDE build 工程时,编译脚本会从\TuyaOS\tools\templates中拷贝模板并扫描应用文件夹下的源文件重新构建IAR工程,如果此时IAR工程已经打开,则会报错。
解决方案: 关闭对应的IAR工程,重新build。

3.开发者遇到python脚本执行失败的log

PHY622X平台:No python at ...

Image

TLSR825X平台:prebuild.py execution failed!!!

Image

这是由于依赖的python3.exe 无法正确调用导致的问题,需要注意的是:
1.安装了python3.8并且配置了环境变量。
2.在python3.8安装路径下复制python.exe重命名为python3.exe
3.python3.8环境变量优先级高于其他python版本。

若无法确认是否安装了python3.8,打开cmd,输入where python可看到当前安装的所有python版本

Image

Image

4. MG2X应用开发时是否可以用IAR进行debug?

可以的,使用MG21平台调试时,编译脚本已经完成IAR工程配置,一般不用修改,进入调试界面需选择Cortex-M33内核;

Image

5. 使用开发包里的demo进行IAR 调试时,进入调试状态PC指针地址一直停留在0xFFFFFFFF

问题原因:基于tuyaSDK开发zigbee设备必须支持OTA升级,这种情况大概率是没有烧录bootloader。
解决方案:IDE build之后会在目录TuyaOS\apps\tuyaos_demo_xx\output生成目标文件:

Code: Select all

•	  tuyaos_demo_xx_DIFF_[version].bin 用于差分ota的升级文件
•	  tuyaos_demo_xx_QIO_[version].bin 包含bootloader的完整目标文件
•	  tuyaos_demo_xx_UG_[version].bin OTA升级固件包文件

烧录QIO文件或者单独烧录bootloader文件之后即可正常调试。
bootloader文件在目录TuyaOS\tools\bootloader中,需区分目标平台。
烧录软件在目录TuyaOS\tools\commander中,烧录方式请参考TuyaOS\docs\0_快速入门.md文档的6.6章节。

huanghuan
Posts: 202

Re: Zigbee高频问题集合

2. 工具相关

2.1 Ubiqua 抓包器使用

无线设备的开发和调试,必定需要搭建一个抓包环境,有了这个抓包,可以直观的看到空气中的数据交互,对分析和定位问题有很大的帮助。正所谓磨刀不误砍柴工,zigbee抓包,可以达到事半功倍的效果。那么按照如下步骤,搭建我们自己的抓包环境吧。

1. 准备工作

硬件: CC2531 USB Dongle

Image

软件:Ubiqua 抓包工具。该工具为付费软件,可以有两个月的免费试用,试用期过了之后,需要购买,65美元每个月。官方下载网址:https://www.ubilogix.com/ubiqua/,我们要多多支持正版哦。

2. 抓包器介绍

Ubiqua 抓包器,主页面如下:

Image

常用工具介绍:

Image

3. 抓包器添加

首先我们要插上我们的抓包器 CC2531 USB Dongle。(若显示设备添加失败,那就下载一个驱动精灵装一下驱动吧)点击菜单栏:Device-->Add Device--,弹出设备添加框:选择“Texas Instruments”,然后选中“Texas Instruments CC2531”,再点“Add Device”

Image

4. 信道查看

首先我就必须要知道网关的所在信道啦,接下来教大家一个找信道的方法,如果接入的是涂鸦的zigbee网关和涂鸦的app,非常方便哦

Image

涂鸦的app配上我们的涂鸦zigbee网关之后,通过查看,网关的设备信息,可以方便的获取信道。如上图,当前信道在24信道。

5. 抓包器信道选择

Image

然后点击设备上的开关按钮即可开始

Image

添加 Trust Center Link Key 输入5A:69:67:42:65:65:41:6C:6C:69:61:6E:63:65:30:39

点击“Add”添加 Key

Image
Image

到此抓包环境全部搭建好。

6. 抓包数据查看

抓包器,需要抓到设备和网关完整的整个组网流程,才能将加密的数据的解密出来。我们现在要做的就是组网了。app打开网关组网通道,设备本地触发组网。开启你的无线世界吧。

下图是收到了一部分数据
Image

huanghuan
Posts: 202

Re: Zigbee高频问题集合

3. 配网相关

3.1 配网成功,app上显示了子设备面板,一分钟左右提示设备离线

TUYA网关配网时会读取入网设备basic cluster下6个属性来识别设备,子设备回复数据后,app上就会跳出子设备面板

Image

Zigbee 3.0规定入网流程中需要获取tc link key 如果获取tc link key失败则会离网

Image

Image

Code: Select all

综上:出现配网成功后就离线的问题可能是设备获取tc link key失败,导致该问题的原因可能是:

1.网关读取basic cluster下属性注册到云端,app上刚刚跳出子设备界面后,用户就退出了配网界面,这时候由于退出了配网模式导致设备获取tc link key失败

2.大规模设备配网 并发入网较多,网关进行处理忙碌导致设备获取tc link key没有被响应

3.由于干扰等因素,导致子设备request key,网关transport ,后续的 verify 和confirm 及其 APS ACK没有被响应导致tc link key交互失败

建议使用者采取以下措施规避:

1.使用网关本地按键(短按一下)开启长配网,长配网模式网关会在设备tc link key交互后才会向云端注册,解决了设备还会由于tc link key没有获取到而离线的问题

2.app配网时出现子设备面板界面后不要直接退出界面,在该界面等待 30s ,可以使得网关处于配网状态,便于子设备获取tc link key

3.参考 4.1章节排查wifi干扰对于交互的影响

3.2 配网成功但是一直没有显示子设备面板

1.2023年5月9日起,由涂鸦平台Zigbee方案创建pid的新设备,如未购买涂鸦授权码,将默认限制接入。设备需要经过烧录授权才能接入并识别面板

2.网关识别设备并向云端注册需要时间,子设备入网成功提示后需要等待 30s 左右确认是否可以正常跳出面板。

3.3 配网成功但是显示面板不对,出现如一路开关之类的默认面板

可以查看 3.1 章节 子设备入网时网关会读取子设备 basic cluster下6个属性,其中会通过 manufacturer name 和 mode id

其中涂鸦公版设备 manufacturer name 是由能力值字段+pid字段组成

Image

mode id可以通过该链接确认 Zigbee 对接规范

huanghuan
Posts: 202

Re: Zigbee高频问题集合

4. 离线相关

4.1 wifi干扰排查

Zigbee在有干扰的情况下,会经常造成ota失败,如何确认是否存在干扰,请照以下步骤:

1. APP软件安装

点击此处下载WiFi魔盒

或者app市场下载:WiFi魔盒

2. APP查看干扰数

Image

Image

1.分别在Zigbee设备和网关所处的地方(贴近设备和网关才能真实反映设备状态):打开WiFi魔盒 app--看干扰

2.底部的干扰数,越多表示这里wifi越密集


3.通过tuya app网关界面查看网关信道,然后通过对比wifi密集的wifi信道,和所处zigbee信道如果有重合就说明有干扰

3. 查看网关信道

Image

右上角铅笔-设备信息-信道

4. 数据对比

Image

Image

Code: Select all

•   如上图网关信道20,对应wifi 8和9 信道 
•   我们就查看8和9信道下的干扰数.上图所示确实有干扰 

有WiFi干扰的情况下,可以通过以下措施改善:

Code: Select all

•   将网关远离WiFi路由器
•   或者是切换并固定wifi信道,是的wifi信道与zigbee信道错开
huanghuan
Posts: 202

Re: Zigbee高频问题集合

5. 应用功能相关

5.1 自定义DP接入规范

5.1.1 DP基本概念

Code: Select all

DP(Data Point)是描述一个设备对象功能点的抽象方式。DP 操作代表通过预定的功能特性来改变设备的状态,例如使用 开关 DP 来改变一个设备的开启和关闭。涂鸦定义了100以内为涂鸦公版DP,101-255为开发者自定义DP。

5.1.2 DP基本类型

Code: Select all

DP常见类型有布尔型、数值型、枚举型、字符型、bitmap、透传(RAW)型。

5.1.3 自定义DP目的

Code: Select all

自定义DP为终端设备在接入涂鸦云端时,可以通过创建自定义DP进行个性化功能开发。

5.1.4 接入标准化流程

1. 添加私有透传cluster 0xEF00

Code: Select all

#define PRIVATE_ATTR_LIST \
    {0x0000, ATTR_INT8U_ATTRIBUTE_TYPE, 1, (ATTR_MASK_TOKEN_FAST|ATTR_MASK_SINGLETON), 0, (UINT8_T*)0x00 }, /* current positiong lift percentage*/\
    {0xFFFD, ATTR_INT16U_ATTRIBUTE_TYPE, 2, (ATTR_MASK_READABLE), 0, (UINT8_T *)0x0002},

const TAL_ATTR_T g_private_attr_list[] = {
    PRIVATE_ATTR_LIST};

#define DEF_CLUSTER_PRIVATE_CLUSTER_ID(a) \
    { CLUSTER_PRIVATE_TUYA_CLUSTER_ID, (TAL_ATTR_T *)&((a)[0]), GET_ARRAY_LEN((a)) },

CONST TAL_CLUSTER_T app_server_cluster_list[] = {
    DEF_CLUSTER_PRIVATE_CLUSTER_ID(g_private_attr_list)

2. 修改json文件能力值

在 apps/xxx_demo/appconfig.json 中修改"manufacture_name":"TZ3210"

Image

3. DP透传业务需要面板进行配合

需要注意的是,涂鸦面板中的功能与DP一一对应。开发者会定义一些私有DP,但是功能与涂鸦公版DP相同的功能,但是使用公版面板下发功能时,面板下发的为公版的DP。

注:开发时可以使用调试面板进行开发

4. 透传接收与发送

涂鸦定义了模组与网关交互的命令

Code: Select all

网关下发DP至模组:      0x04
模组应答网关下发DP:     0x05
模组主动上报DP至网关:   0x06

5. 接收入口

Code: Select all

TAL_MSG_RET_E tal_zcl_specific_msg_recv_callback(TAL_ZCL_MSG_T *msg)
switch(msg->cluster)
    case 0xEF00{
        switch(msg->command){
            case 0x04 :{
                    air_data_response(msg->dst_ep,  
                    msg->len, &(msg->playload[0]), 0x05, QOS_1)
            }
        }

    }
    ...

设备应答回复

Code: Select all

air_data_response(uint8_t ep, uint8_t len uint8_t *data, uint8_t command_id TAL_SEND_QOS_E qos ){
    tal_system_memset(&send_data, 0, SIZEOF(TAL_ZG_SEND_DATA_T));

    send_data.qos = qos;
    send_data.delay_time = 0;
    send_data.zcl_id = 0x68;

    send_data.direction = ZG_ZCL_DATA_SERVER_TO_CLIENT;
    send_data.frame_type = ZG_ZCL_FRAME_TYPE_SPEC_TO_CLUSTER;
    send_data.command_id = command_id;/*respose cmd 0x05 */
    send_data.addr.mode = SEND_MODE_DEV;
    send_data.addr.type.dev.cluster_id = 0xEF00;
    send_data.addr.type.dev.src_ep = ep;
    send_data.data.private.len = len;
    memcpy((send_data.data.private.data), data, len);

    tal_zg_clear_send_data(ZG_CLEAR_ALL_ZCL_ID, &send_data.zcl_id);
    tal_zg_send_data(&send_data, NULL, 2000);
}

6. 设备主动上报

Code: Select all

tal_system_memset(&send_data, 0, SIZEOF(TAL_ZG_SEND_DATA_T));

send_data.qos = QOS_1;
send_data.delay_time = 0;
send_data.zcl_id = 0x68;

send_data.direction = ZG_ZCL_DATA_SERVER_TO_CLIENT;
send_data.frame_type = ZG_ZCL_FRAME_TYPE_SPEC_TO_CLUSTER;
send_data.command_id = 0x06;/*report cmd*/

send_data.addr.mode = SEND_MODE_DEV;
send_data.addr.type.dev.dst_addr = TUYA_GATEWAY_ADDRESS;
send_data.addr.type.dev.dst_ep = 0x01;
send_data.addr.type.dev.src_ep = TUYA_PRIMARY_ENDPOINT;
send_data.addr.type.dev.cluster_id = CLUSTER_PRIVATE_TUYA_CLUSTER_ID;
send_data.data.private.len = 7;
send_data.data.private.data[2] = 101; /* DP id*/
send_data.data.private.data[3] = ATTR_ENUM8_ATTRIBUTE_TYPE; /*DP type*/
send_data.data.private.data[4] = 0x00;
send_data.data.private.data[5] = 0x01;/*DP len*/
send_data.data.private.data[6] = day_up_down_change_flag; /*DP data*/

tal_zg_clear_send_data(ZG_CLEAR_ALL_ZCL_ID, &send_data.zcl_id);
tal_zg_send_data(&send_data, NULL, 2000);

7. 数据格式参考下图

Image

5.2 ADC采样

5.3 PWM 输出

1.遇到调用tal_pwm_init()到tal_pwm_start()期间电平不可控时可以使用tkl_pwm_idle_level_set()来配置电平

2.遇到多路pwm 输出不同步时,可以使用tal_pwm_start(0xFF) 多路同时输出

Image

Image

5.4 低功耗设备电池采样及电量上报策略

5.5 低功耗设备poll及rejoin 配置

Code: Select all

/*
 * zigbee poll configuration
*/
typedef struct {
    UINT8_T   forever_flag;             ///< TRUE: forever poll if device no network(TAL_ZG_NWK_POWER_ON_ONLINE/TAL_ZG_NWK_JOIN_OK/TAL_ZG_NWK_REJOIN_OK)
    UINT8_T   fast_swicth_parent;       ///< TRUE: if ack isn't received, will continue polling until the max number of failures is reached before switching the parent
    UINT16_T  interval_ms;              ///< poll period (bet: ms)
    UINT16_T  max_failed_times;         ///< enter parent-lost status when poll failed x times.
    UINT16_T  duration_after_data_ms;   ///< tiemout waitting app ack (bet: ms)
    UINT_T    duration_after_join_ms;   ///< wakeup time when join success.(for gateway get cluser data) (bet:ms)
    UINT_T    duration_after_rejoin_ms; ///< wakeup time when rejoin success.(for app use) (bet:ms)
} TAL_ZG_POLL_CFG_T;

Code: Select all

/*
 * zigbee end-device rejoin config
*/
typedef struct {
    UINT8_T  power_on_active;       ///< auto rejoin when power on.
    UINT8_T  send_data_active;      ///< auto rejoin when send data if parent lost.
    UINT8_T  reserved;              ///< Reserved
    UINT8_T  attempts;              ///< max rejoin attempts when parent lost.
    UINT16_T interval;              ///< rejoin attempt interval when parent lost.
} TAL_ZG_REJOIN_CFG_T;

Code: Select all

/**
 * @brief register router or sleep device
 * @return none
 */
STATIC VOID_T app_sleep_device_node_init(VOID_T)
{
    // sleep end device node init
     TAL_ZG_NODE_CFG_T node_config = {
         .node_type = ZG_SLEEPY_END_DEVICE,
         .tx_power = 10,
         .scan_interval = 100,
         .scan_duration = ZG_SCAN_DURATION_3,
         .config.sleep_ed_cfg.poll_config.forever_flag = 1,
         .config.sleep_ed_cfg.poll_config.fast_swicth_parent = 1,
         .config.sleep_ed_cfg.poll_config.interval_ms = 250,
         .config.sleep_ed_cfg.poll_config.max_failed_times = 10,
         .config.sleep_ed_cfg.poll_config.duration_after_data_ms = 1000,
         .config.sleep_ed_cfg.poll_config.duration_after_join_ms = 60000,
         .config.sleep_ed_cfg.poll_config.duration_after_rejoin_ms = 15000,
         .config.sleep_ed_cfg.rejoin_config.power_on_active = 1,
         .config.sleep_ed_cfg.rejoin_config.send_data_active = 1,
         .config.sleep_ed_cfg.rejoin_config.attempts = 3,
         .config.sleep_ed_cfg.rejoin_config.interval = 3000,
     };
    //config zigbee node
    tal_zg_node_config(&node_config);
}

Image

Code: Select all

forever_flag 表示在网时设备是否定时发送data request向父节点请求数据;
建议开启forever_flag的设备,一般会有网关下发给该设备数据的机制,比如单火开关;
像门磁等只有状态上报而没有下发交互的设备,可以将forever_flag置为false。

fast_swicth_parent 一般用于forever_flag false 时快速判断是否与父节点断开链接
forever_flag false 时设备通过比如按键等触发数据上报,如果父节点没有数据响应,设备会最多发送 fast poll times+short poll times的data request;这个次数可能没有达到 max_failed_times。这使得一次按键没法让设备触发rejoin,需要多次按键才能让设备进行rejoin。而fast_swicth_parent 置为 TRUE后,一次按键附带的data request将会为max_failed_times 一次就会触发rejoin。

interval_ms 是设置 data request的发送间隔

max_failed_times 是发送多少次data request直到触发rejoin

duration_after_data_ms / interval_ms 是forever_flag = false时,在网发送一次数据后持续的data request次数

duration_after_join_ms / interval_ms 是forever_flag = false时,配网成功时持续的data request次数

duration_after_rejoin_ms / interval_ms 是forever_flag = false时,rejoin成功时持续的data request次数

Image

Code: Select all

power_on_active 是 lost状态 上电主动触发rejoin机制,建议开启

send_data_active 是 lost状态 发数据时触发rejoin机制,建议开启

attempts 是lost状态 触发rejoin机制一组发多少次beacon request

attempts 是lost状态 触发rejoin机制一组隔多久发一次beacon request

如上图所示:一次rejoin尝试3次beacon request,每次beacon request间隔3秒

5.6 不知道标准dp与zigbee cluster下attr和command 的对应关系

点击下载目前tuya网关接入的设备dp与zigbee cluster 下attr和command 对应关系文档

Tuya_Zigbee_subdev_dp_list

Image

如果上述文档所有品类接入的dp list,无法覆盖对应用户需要开发的设备所对应的dp 功能,则建议开发者通用对接方案。
即在 5.1 章的基础上 APP_MODEL_ID 填 TS0601;APP_CAPACITY 填 TZE204

6. 产测失败

6.1 在烧录时出现读取Auzkey失败

Image

Image

Code: Select all

1.产测部分代码sdk底层托管,应用层不需要再实现相关的串口交互

2.同时需要注意的不要在产测中添加耗时很久的设备操作,比如下图:
在进入产测处理函数中初始化IIC操作的外设,耗时过久导致上位机下发的后续数据设备无法收到

3.无法定位问题时,先将demo编译产物上传涂鸦后台,进行烧录授权,确保demo烧录授权可以正常完成,确保环境没有问题

Image

针对泰凌平台:
1.正常的量产程序,不应该存在抢占式log输出,应避免由此导致的异常
2.开启抢占式串口打印,会在打印时关闭中断源,这使得串口接收异常

Image

niezheyuan
Posts: 61

Re: Zigbee高频问题集合

手动点赞,太优秀了

caowen
Posts: 27

Re: Zigbee高频问题集合

标准dp与zigbee cluster下attr和command 的对应关系,下载的文档里,照明调光遥控器里,为什么对应clusterId,attr,command 是空的

Attachments
DP_TEST_Zigbee多功能场景遥控器.csv
(1.23 KiB) Downloaded 48 times
huanghuan
Posts: 202

Re: Zigbee高频问题集合

你好,这个设备涉及网关群组功能,特殊设备,暂不支持接入

caowen
Posts: 27

Re: Zigbee高频问题集合

那我这边如何实现通过APP将群组与遥控器的相应按键绑定

Post Reply