# TuyaLink 光源

**URL:** <https://forum.hinearlink.com/t/tuyalink/27>\
**Category:** 造物工坊\
**Created:** [2026 年10 月 26 日 07:06 UTC](https://forum.hinearlink.com/t/tuyalink/27 "2026-10-26T07:06:03Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

作者： ![gaoxiaolon](https://forum.hinearlink.com/letter_avatar_proxy/v4/letter/g/d26b3c/32.png) [@gaoxiaolon](https://forum.hinearlink.com/u/gaoxiaolon)\
发布日期： [2026 年10 月 26 日 07:06 UTC](https://forum.hinearlink.com/t/tuyalink/27/1 "2026-10-26T07:06:04Z")

</div>

**通过 TuyaLink 开放协议接入涂鸦云 / 涂鸦 App：手机扫码绑定，远程开关板载 LED，周期上报 CPU 占用率与芯片温度。**

> 仓库地址:[https://gitcode.com/hinearlink/samples](https://gitcode.com/hinearlink/samples)(本样例位于 `ws63/tuya_light`)

## 概述

本示例把 WS63 开发板接入 **涂鸦 IoT 开发者平台** （TuyaLink 开放协议），实现：

- 板子自己连 Wi-Fi（STA）→ NTP 对时 → MQTT over TLS 连涂鸦云（中国区 `m1.tuyacn.com:8883`）
- **手机涂鸦 App 扫二维码绑定** ，App 里点开关 → 云端下发 → 板载 LED 亮/灭，状态实时回显
- 板子每 30 秒上报 **CPU 占用率** 、 **芯片温度** 两个自定义数据点，平台「设备日志」可查

 ![整体数据流向：App ↔ 涂鸦云 ↔ WS63](https://forum.hinearlink.com/uploads/default/original/1X/4382940e6b582c027acdf46316f021fc8d3b3ceb.webp)

**为什么选涂鸦生态** ：涂鸦智能 App 是现成的成熟 App，不用自己写手机端；涂鸦云提供设备管理、日志、DP（功能点）模型，接一个设备只需要一套 HMAC 鉴权 + MQTT 收发。

**成果演示视频** （17 秒）：手机涂鸦 App 远程开关板载 LED，开关状态与 CPU / 芯片温度实时回显。

 ![演示视频：App 远程开关 LED](https://forum.hinearlink.com/uploads/default/original/1X/5746d191a69afd99336494befe3a085d4280e69b.webp "gallery")

▶ 高清完整版（17 秒）：[videos/demo.mp4](https://gitcode.com/hinearlink/samples/blob/main/ws63/tuya_light/videos/demo.mp4)

* * *

## 项目结构

```auto
tuya_light/
├── README.md # 本文档
├── images/ # 教程配图（平台/App 截图、表格图、视频 GIF 预览）
├── videos/ # 演示视频
│ └── demo.mp4 # 成果演示（17 秒：手机 App 远程开关 LED）
└── src/ # 复制到 SDK 的源码（模块化：6 个 .c/.h + Kconfig/CMakeLists）
    ├── tuya_light.c # 入口与主流程（联网 → 对时 → 连云/重连 → 定时上报）
    ├── tuya_led.c / .h # LED（GPIO）驱动
    ├── tuya_wifi.c / .h # Wi-Fi STA 联网（扫描 → 匹配 → 关联 → DHCP）
    ├── tuya_ntp.c / .h # NTP 对时 + 系统时间
    ├── tuya_mqtt.c / .h # TuyaLink 鉴权 + MQTT over TLS 收发
    ├── tuya_dp.c / .h # 三个功能点（开关 / CPU / 温度）的上报与下发处理
    ├── tuya_common.h # 公共定义（日志宏、tick 常量）
    ├── Kconfig # 需要你填的配置（Wi-Fi + 涂鸦凭证，menuconfig 里填）
    └── CMakeLists.txt # 编译配置

```

| 文件 | 职责 | 主要接口 |
| --- | --- | --- |
| `tuya_light.c` | 入口与主流程：LED 初始化 → Wi-Fi → NTP → 连云/断线重连 → 定时上报 | `app_run(tuya_light_entry)` |
| `tuya_wifi.c/.h` | Wi-Fi STA：全信道扫描 → 匹配 SSID → 关联 → DHCP | `tuya_wifi_connect()` |
| `tuya_ntp.c/.h` | NTP 对时（UDP 123，阿里云 NTP，域名解析失败走 IP 兜底） | `tuya_ntp_sync()` / `tuya_now()` |
| `tuya_mqtt.c/.h` | TuyaLink 签名鉴权、MQTT over TLS 连接/订阅、报文上报 | `tuya_mqtt_connect()` / `tuya_publish_json()` |
| `tuya_dp.c/.h` | 三个功能点：开关下发解析与状态回报；CPU/温度定时采集上报 | `tuya_dp_on_downlink()` / `tuya_dp_report_switch()` / `tuya_dp_report_sysinfo()` |
| `tuya_led.c/.h` | 板载 LED：GPIO 初始化、点亮/熄灭、极性适配 | `tuya_led_init()` / `tuya_led_set()` / `tuya_led_get()` |
| `tuya_common.h` | 公共定义：日志宏 `TUYA_PRINT`、tick/秒换算常量 | — |

* * *

## 开发环境准备

| 项目 | 要求 |
| --- | --- |
| 操作系统 | Windows 10/11或 Ubuntu / WSL，二选一 |
| Python | 3.x（实测 3.11）。SDK 的构建、menuconfig 都是 Python 脚本 |
| 构建依赖 | cmake、kconfiglib（menuconfig 终端界面打包在 kconfiglib 里）；Windows 再加 windows-curses —— 正常开发环境里通常都已就绪，见下 |
| Ninja | 可选：装了自动用 Ninja 加速编译，没装自动退回 make |
| SDK | `git clone https://gitcode.com/HiSpark/fbb_ws63.git`，编译器随仓库自带（`tools/bin/compiler/`），不用单独装工具链 |
| 烧录工具 | HiSpark Studio，或命令行 BurnToolCmd（见步骤 6） |

> SDK 仓库自带更详细的官方环境文档：`docs/zh-CN/get-started/environment-setup.md`。

* * *

## 硬件准备

| 项目 | 说明 |
| --- | --- |
| 开发板 | WS63-01S（板载 LED 接在 GPIO\_14） |
| 网络 | 2.4G Wi-Fi（WS63 不支持 5G 频段） |
| 串口 | UART0，115200 8N1，看运行日志 |
| 烧录 | HiSpark Studio 或烧录工具（见 SDK 内 `tools/` 目录文档） |

 ![Little Pond WS63-01S 开发板](https://forum.hinearlink.com/uploads/default/original/1X/26708ef17680388584ed513e5a02392825eba687.webp)

**同款开发板购买** （Little Pond WS63-01S）：

- 商品链接：[https://www.jlc-yx.com/products/detail/622649373851631617](https://www.jlc-yx.com/products/detail/622649373851631617)
- 扫码直达：

 ![购买二维码：扫码购买同款 WS63-01S 开发板](https://forum.hinearlink.com/uploads/default/original/1X/927eaa74f3b4ff992bebedf2a2807b860c625f9b.webp)

**ESP-01S 烧录器** ：

- 商品链接：[https://e.tb.cn/h.jaQLfzdfKpTSadp?tk=z2YOTrU0LYD](https://e.tb.cn/h.jaQLfzdfKpTSadp?tk=z2YOTrU0LYD)

> 如果你的板子 LED 引脚不同，改 [src/tuya\_led.c](https://gitcode.com/hinearlink/samples/blob/main/ws63/tuya_light/src/tuya_led.c) 顶部的 `TUYA_LED_PIN` / `TUYA_LED_ACTIVE_HIGH` 即可。

* * *

## 第一部分：涂鸦开发者平台（图文）

### 1.1 注册并创建产品

打开 [涂鸦 IoT 开发者平台](https://platform.tuya.com)（国际版用 [iot.tuya.com](http://iot.tuya.com)），注册登录后进入 **产品开发** （直达链接 `platform.tuya.com/pmg/list`，左侧边栏「概况」下也能找到）：

 ![产品列表](https://forum.hinearlink.com/uploads/default/original/1X/893cc08af540540fb2bf6b3f8dc3250907fb1d75.webp)

点右上角 **创建产品** ，跟着向导走 4 步：

**① 选品类** ：标准类目 → **照明** → 选 **光源** 卡片：

 ![选择品类：照明 → 光源](https://forum.hinearlink.com/uploads/default/original/1X/caaf560e58983ec976e79a1879e531ac63d14349.webp)

**② 选智能化方式** ：选 **生态设备接入** （适用于已有成品/存量设备接入平台）：

 ![智能化方式：生态设备接入](https://forum.hinearlink.com/uploads/default/original/1X/e3462ed7292d57b2a679d44a090f3d423624b744.webp)

**③ 确认方案** ：平台自动匹配 **TuyaLink自定义方案** （开发方式 TuyaLink 方案）：

 ![自动匹配 TuyaLink 自定义方案](https://forum.hinearlink.com/uploads/default/original/1X/6dfd4fc7fc1e25cac136f85d7766a8daddaa2548.webp)

**④ 完善产品信息** ，点 **创建产品** ：

 ![完善产品信息](https://forum.hinearlink.com/uploads/default/original/1X/522e4b82065646ce64066dfa3d0ca3868cd6772e.webp)

| 表单字段 | 填法 |
| --- | --- |
| 产品名称 | **任意** （示例填「流程验证」） |
| 产品型号 | **任意，可留空** （示例填 WS63-DEMO） |
| 产品描述 | **可留空** |

> **数据中心** ：这个向导里不单独选，跟随账号注册区域（中国区账号 = 中国数据中心）。代码里 `TUYA_MQTT_HOST` 要和它保持一致（默认 `m1.tuyacn.com` 就是中国区）。

创建后进入产品页，顶部能看到 **产品 ID（PID）** ——待会要填到代码里。

### 1.2 功能定义（DP）

功能定义决定设备和云之间的数据协议。本示例一共需要 **3 个功能点** ，逐个说明每个字段怎么选。

> 注意： **这条接入路线创建的产品功能定义是空的** ——「开关」不会默认自带，3 个功能点都要手动添加；加完后「功能定义」页最终应该长这样：

 ![功能定义](https://forum.hinearlink.com/uploads/default/original/1X/af51fd87a60baf3e68bc148a6517b9b62ba7adff.webp)

刚创建完产品时，「产品标准功能」和「自定义功能」两个列表都是空的（正常现象）：

 ![新建产品时功能定义为空](https://forum.hinearlink.com/uploads/default/original/1X/2c38df51feb4faf2a8ced3cb7c9c4242bdb2efbd.webp)

#### 1. 开关 `switch_led`（从标准功能库添加）

点「产品标准功能」右上角的 **+ 添加功能** ，在标准功能库里搜「开关」，勾选 `switch_led` 加入并 **确定** （DP ID 自动分配，通常为 101）。添加时对照下面截图和表格确认各字段：

 ![开关字段](https://forum.hinearlink.com/uploads/default/original/1X/97e13441ada58066374ed1d9235574e4d3683cc6.webp)

| 字段 | 选择 |
| --- | --- |
| 高级功能名称 | 开关 |
| 标识符 | `switch_led`（标准功能固定，不用改） |
| 功能类型 | 属性 |
| 数据类型 | 布尔型（Bool） |
| 数据传输类型 | 可下发可上报（rw）← App 下发、设备回报都靠它 |

> 之后想修改字段，点该行的 **编辑** 即可（添加和编辑是同一个表单）。

#### 2. CPU占用率 `cpu_usage`（自定义功能，新建）

在「自定义功能」区域点 **+ 添加功能** ，按下面截图和表格填：

 ![CPU占用率字段](https://forum.hinearlink.com/uploads/default/original/1X/16f42b3c6f8922800757f77077953823a5f67054.webp)

| 字段 | 选择 |
| --- | --- |
| 高级功能名称 | CPU占用率（随便起，App 上显示这个） |
| 标识符 | `cpu_usage` ← 必须一字不差，代码按它上报 |
| 功能类型 | 属性 |
| 数据类型 | 数值型（Value） |
| 数值范围 | 0 ~ 100 |
| 间距 | 1 |
| 倍数 | 0 |
| 单位 | % |
| 数据传输类型 | 只上报（ro）（设备只上报，不需要 App 下发） |

#### 3. 芯片温度 `chip_temp`（自定义功能，新建）

同样 **+ 添加功能** ，按下面截图和表格填：

 ![芯片温度字段](https://forum.hinearlink.com/uploads/default/original/1X/a01247a00beb94fab8955f1cdb881776cc5d37b3.webp)

| 字段 | 选择 |
| --- | --- |
| 高级功能名称 | 芯片温度（随便起） |
| 标识符 | `chip_temp` ← 必须一字不差 |
| 功能类型 | 属性 |
| 数据类型 | 数值型（Value） |
| 数值范围 | -40 ~ 125 |
| 间距 | 1 |
| 倍数 | 0 |
| 单位 | ℃ |
| 数据传输类型 | 只上报（ro） |

**注意事项** ：

- 三个功能的 **标识符** 是代码和云端约定好的（`switch_led` / `cpu_usage` / `chip_temp`），名字和范围可以改，标识符不能改。
- 平台的 **DP ID** （101/102/103）是自动分配的，你创建时不一定一样， **不用管** ——代码按标识符收发。唯一用到 DP ID 的地方是 `tuya_dp.c` 顶部的 `TUYA_DP_SWITCH_LED`（兜底解析，填「开关」行显示的 DP ID 即可）。

### 1.3 激活验证 —— 注册设备、拿凭证

先确认接入方式：进 **设备开发** 标签，在「已选接入方式」里选 **开放协议接入** （点 **选择此接入方式** ；不选的话激活验证流程进不去）：

 ![选择接入方式：开放协议接入](https://forum.hinearlink.com/uploads/default/original/1X/cd4ffc9569bf0c84bac531732585ae2fa156dd15.webp)

然后进入 **设备开发 → 激活验证** ：

 ![激活验证（DeviceStatus 点「刷新」看实况）](https://forum.hinearlink.com/uploads/default/original/1X/cd70e0b2cf0da0859e3e7701ecc74ef7899b6eb7.webp)

1. 没有授权码就先点右上角 **免费领取授权码** ——不是即时的，确认领取后一般 5 分钟内分配到账（页面显示「预计等待 5 分钟，分配进度」，右上角「剩余授权码」变为 1 个后才可注册）。免费额度： **每个产品赠送 2 个** 、账号级最多 6 个， **领取后不可撤销** ，且一个授权码只能接入一个设备：

2. 点 **注册设备** 。注册成功后弹出 **「注册完成」** 窗口，里面就是 注册ID / ProductID / DeviceID / DeviceSecret，点 **一键复制凭证** 即可：

| 平台字段 | 对应 menuconfig 选项（TuyaLink Light Sample 子菜单） |
| --- | --- |
| ProductID | Tuya product ID (PID) |
| DeviceID | Tuya device ID |
| DeviceSecret | Tuya device secret |

> 凭证以后可以随时回来调取： **设备开发 → 激活验证** ，在「请选择注册ID获取设备凭证」下拉框里选注册ID，注册ID / ProductID / DeviceID / DeviceSecret / DeviceStatus 会全部重新列出来（DeviceSecret 默认打码，点「显示」看明文）；这一页底部的按钮是「查看日志 / 一键复制 / 下一步」。
> 
> **DeviceStatus 提示的是打开页面那一刻的快照** （可能是缓存的旧值「离线」），点旁边的 **刷新** 才拿实况：固件没烧进板子前离线是正常的，烧录后点「刷新」变 **在线** ，就说明接入成功。

### 1.4 把设备绑定到手机 App

> **前提：先配置绑定范围。** 在 **产品配置 → 设备绑定范围配置 → 设置** 里选「全部可用」（或「仅当前账号可用」）并 **保存配置** ——没保存过的话二维码拿去也绑不上。弹层里那句「使用前，请前往产品配置进行【设备绑定范围配置】」是固定文案，配置完成后也不会消失，忽略即可。

 ![设备绑定范围配置：设置里选「全部可用」并保存配置](https://forum.hinearlink.com/uploads/default/original/1X/2bce39f7e5f1f89472fdf7f6cb93c7032f1264c7.webp)

**1. 在开发者平台拿绑定二维码**

开发者平台 → **设备管理** ，找到刚注册的设备，点操作列的 **绑定二维码** ：

 ![设备管理](https://forum.hinearlink.com/uploads/default/original/1X/b3ef14c5f652ba0144929cbc02a22c54bb80fc7b.webp)

> 设备状态列注意： **未绑定** 的设备会 **固定** 显示「未绑定离线」——就算设备 MQTT 在线、日志实时进数也照样这么显示，别当成离线；绑定成功后才会变成「已绑定 在线」（上图就是绑定后的状态）。要确认在线，看 1.5 的设备日志页，或激活验证页点「刷新」。

弹出的对话框就是绑定二维码（`Bind Code` 是同一件事的文本形式，一般用二维码即可）：

 ![绑定二维码对话框](https://forum.hinearlink.com/uploads/default/original/1X/b9772b258abf00403ba3ffb4bab5ce6190600fb7.webp "gallery")

**2. 在 App 里扫码添加**

手机安装 **涂鸦智能 / Tuya Smart** App，注册登录（和开发者平台 **可以是不同账号** ）。App 首页右上角 **+** → **扫一扫** ：

 ![App 扫一扫](https://forum.hinearlink.com/uploads/default/original/1X/f6fc66576242e2dba3832efa901e5da2df7bbdf6.webp "gallery")

对准上面弹出的二维码扫描，按提示确认即可绑定。

> **注意** ：TuyaLink 开放协议接入的设备 **不会** 出现在 App「添加设备」的自动发现/配网列表里——固件自己连 Wi-Fi，不经过 App 配网， **只能扫码绑定** 。

绑定成功后，App 首页出现设备卡片：

 ![App 首页设备卡片](https://forum.hinearlink.com/uploads/default/original/1X/f9f2c9939fed6a6ebbd5a000a0df966f88fd4cd2.webp "gallery")

点进卡片就是控制页。注意 CPU 占用率 / 芯片温度在 App 里显示为 `dp_cpu_usage` / `dp_chip_temp`（App 直接显示功能点标识符，属正常现象）。

### 1.5 验证数据上报

设备运行后，平台 **设备管理 → 日志** ，能看到：

 ![设备日志](https://forum.hinearlink.com/uploads/default/original/1X/b2a9930ce5aefa605303b9c40260664bdfd3c071.webp)

- 每 30 秒一条「设备属性上报」：`{"chip_temp":49,"cpu_usage":4}`
- 「数据上报」事件里 CPU 占用率、芯片温度分列展示

* * *

## 第二部分：SDK 集成

### 步骤 1：复制源码到 SDK

把 `src/` 下的 **全部文件** （6 个 `.c`/`.h` 模块 + `tuya_common.h` + `Kconfig` + `CMakeLists.txt`）复制到 SDK 的 `application/samples/wifi_test/tuya_light/` 目录（没有就新建）：

```auto
application/samples/wifi_test/
├── tuya_light/ <-- 新建，放入 src/ 下全部文件
│ ├── tuya_light.c
│ ├── tuya_led.c / tuya_led.h
│ ├── tuya_wifi.c / tuya_wifi.h
│ ├── tuya_ntp.c / tuya_ntp.h
│ ├── tuya_mqtt.c / tuya_mqtt.h
│ ├── tuya_dp.c / tuya_dp.h
│ ├── tuya_common.h
│ ├── Kconfig
│ └── CMakeLists.txt
├── CMakeLists.txt <-- 步骤 2 要改
├── Kconfig <-- 步骤 2 要改
└── ...

```

### 步骤 2：修改 SDK（注册样例 + TLS 关键修复）

SDK 侧一共 **3 处修改，全部手动改** ——都是复制/删除几行代码，不需要打补丁：

#### 2.1 注册样例：`application/samples/wifi_test/CMakeLists.txt`

在文件末尾 `set(SOURCES ...)` 之前插入：

```cmake
if(DEFINED CONFIG_SAMPLE_SUPPORT_TUYA_LIGHT)
    add_subdirectory_if_exist(tuya_light)
    set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/tuya_light/" PARENT_SCOPE)
endif()

```

#### 2.2 注册样例：`application/samples/wifi_test/Kconfig`

在 `choice / prompt "Sample"` 块内（比如 STA Sample 后面）插入：

```kconfig
config SAMPLE_SUPPORT_TUYA_LIGHT
    bool "Support TuyaLink Light Sample"

if SAMPLE_SUPPORT_TUYA_LIGHT
osource "application/samples/wifi_test/tuya_light/Kconfig"
endif

```

#### 2.3 ⚠ 关键修复：`drivers/drivers/driver/security_unified/mbedtls_harden_adapt/mbedtls_platform_hardware_config.h`

这个头文件被 SDK 全局注入 mbedtls（`-DMBEDTLS_USER_CONFIG_FILE`），它在默认路径下 **`#undef` 掉了 ECDHE 密钥交换** ：

```c
#if !defined(CONFIG_SUPPORT_HILINK) && !defined(CONFIG_SUPPORT_MBEDTLS_SAMPLE)
#undef MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED

#undef MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED // <-- 删掉这行
                                                   //
#undef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED // <-- 删掉这行
#endif

```

删掉两个 ECDHE 的 `#undef`（DHE 的保留）即可。

**不删会怎样** ：ClientHello 里一个前向保密套件都没有，涂鸦云直接回 `alert 71 insufficient_security` 拒绝 TLS 握手，串口表现为 MQTT 一直连不上（`MQTT 连接失败 rc=...`）。这是本教程踩过的最大坑，排查时优先看这里。

### 步骤 3：用 menuconfig 勾选样例（关键）

```bash
python build.py ws63-liteos-app menuconfig

```

menuconfig 是终端图形界面，操作键：

- **↑ / ↓** 移动光标； **→** （或回车）进入子菜单； **←** （或 ESC）返回上一级
- **空格** 切换勾选（在单选组里就是选中该项）
- 顶层按 **S** 保存；按 **Q** 退出（退出时会问是否保存，选 y）
- 嫌找得慢：按 **/** ，输入 `SAMPLE_SUPPORT_TUYA_LIGHT` 回车，直接跳到这一项

按下面路径逐级勾选（三层）：

```auto
Application --->
    [*] Enable Sample. ← 默认已勾，确认保持 [*]
        [*] Enable the Sample of WIFI. ← 空格勾上
            Sample（单选组）
                ( ) Support WIFI STA Sample
                (X) Support TuyaLink Light Sample ← 空格选中这一项
                ( ) Support ALILINK Sample
                ( ) Support WIFI SoftAP Sample.
                ( ) Support BLE WIFI CFG Sample
                ( ) Support HILINK
                ( ) Support UAPI.

```

要点：

- 这是 **单选组** （圆括号），选了 TuyaLink 就不会同时选 STA Sample——正常现象。
- 勾完一路 `←` 退回顶层，按 **S** 保存。
- 保存后可以核对 `build/config/target_config/ws63/menuconfig/acore/ws63_liteos_app.config` 里出现 `CONFIG_ENABLE_WIFI_SAMPLE=y` 和 `CONFIG_SAMPLE_SUPPORT_TUYA_LIGHT=y`，但 **始终用 menuconfig 勾选，不要手改 config 文件** ——保存时工具会按当前 Kconfig 重新生成整份配置（顺带清理旧版本残留的符号），手改的内容容易漏依赖或被覆盖。

选中 TuyaLink 后，菜单里会多出一个 **TuyaLink Light Sample** 子菜单——Wi-Fi 和涂鸦凭证在这个子菜单里填，见「步骤 4」。

### 步骤 4：填写配置（menuconfig 里直接填）

接着步骤 3，在 menuconfig 里选中 TuyaLink 后进入子菜单，只有 5 项要填（Wi-Fi 和涂鸦平台拿到的凭证）：

 ![menuconfig：TuyaLink Light Sample 子菜单，5 项配置已填（凭证已打码）](https://forum.hinearlink.com/uploads/default/original/1X/82d1f5c6b2f97c6735001d9855e4f20287725e6a.webp "gallery")

```auto
Application --->
    [*] Enable Sample.
        [*] Enable the Sample of WIFI.
            Sample（单选组）
                (X) Support TuyaLink Light Sample
                    TuyaLink Light Sample ---> ← 进入这个子菜单
                        () Wi-Fi SSID (2.4G only) ← 填你的 2.4G Wi-Fi 名称
                        () Wi-Fi password ← 填 Wi-Fi 密码
                        () Tuya product ID (PID) ← 1.3 节拿到的 PID
                        () Tuya device ID ← 1.3 节拿到的 DeviceID
                        () Tuya device secret ← 1.3 节拿到的 DeviceSecret

```

其他都不用管：LED 引脚、DP 标识符、上报周期、数据中心这些默认值不在 menuconfig 里，直接写在对应模块文件的顶部 `#define`，按需自取：

- `tuya_led.c`：`TUYA_LED_PIN`（默认 `GPIO_14`）、`TUYA_LED_ACTIVE_HIGH`、`TUYA_LED_DEFAULT_ON`
- `tuya_dp.c`：`TUYA_DP_SWITCH_LED_NAME`（`switch_led`）、`TUYA_DP_CPU_USAGE_NAME`、`TUYA_DP_CHIP_TEMP_NAME`、`TUYA_DP_SWITCH_LED`（101）
- `tuya_mqtt.c`：`TUYA_MQTT_HOST`（`m1.tuyacn.com`）、`TUYA_MQTT_PORT`、`TUYA_SKIP_CERT_VERIFY`、`TUYA_DEBUG_MQTT_TRACE`
- `tuya_light.c`：`TUYA_CPU_REPORT_INTERVAL_S`（30 秒）

没填凭证就编译烧录的话，开机串口会直接提示「配置还没填」，不会对着空配置瞎连。

> 命令行爱好者也可以在 SDK 根目录一条命令填完（kconfiglib 工具写入，和 menuconfig 等价）：
> 
> ```bash
> python build/script/usr_config.py --command setconfig --chip ws63 --core acore --target ws63-liteos-app \
> TUYA_LIGHT_WIFI_SSID=你的SSID TUYA_LIGHT_WIFI_PASSWORD=你的密码 \
> TUYA_LIGHT_DEVICE_ID=你的DeviceID TUYA_LIGHT_DEVICE_SECRET=你的DeviceSecret TUYA_LIGHT_PID=你的PID
> 
> ```

> 凭证会随配置写进 `build/config/target_config/ws63/menuconfig/acore/ws63_liteos_app.config`——该文件在 SDK 仓库里是被 Git 跟踪的，填过凭证后别把 SDK 仓库推到公开仓库（自己的私有 fork 没问题）。本样例源码本身不含任何凭证，公开仓库里是空的。

### 步骤 5：编译

```bash
python build.py ws63-liteos-app

```

产物：`output/ws63/fwpkg/ws63-liteos-app/ws63-liteos-app_all.fwpkg`。

### 步骤 6：烧录

用 HiSpark Studio 把 `ws63-liteos-app_all.fwpkg` 烧到开发板（参考 SDK 内 `tools/HiSparkStudio插件版编译及烧录.md`）。

想用命令行的话，HiSpark Studio 自带 BurnToolCmd（把 `COMx` 换成你的串口，实测可用）：

```bash
cd "<HiSpark Studio 安装目录>/tools/BurnToolCmd"
./BurnToolCmd.exe --burn -n ws63 -m serial COMx --baudRate 921600 \
  -f "<SDK目录>/src/output/ws63/fwpkg/ws63-liteos-app/ws63-liteos-app_all.fwpkg" \
  -re 1

```

运行后工具会提示 `Please reset the device, the waiting time is about 30 seconds.`—— **这时按一下开发板上的复位键** （约 30 秒内有效，没按上就重跑一次），工具就开始烧写。`-re 1` 表示烧完自动复位。

用串口工具看日志： **115200 8N1** 。

* * *

## 运行现象（串口 115200）

```auto
[TUYA_LIGHT] ==== TuyaLink 光源启动 ====
[TUYA_LIGHT] PID=your_pid DeviceID=your_device_id
[TUYA_LIGHT] LED -> OFF
[TUYA_LIGHT] 全扫到 29 个 AP:
[TUYA_LIGHT] [0] ssid='MyHome' ch=1 band=1 rssi=-12 sec=2
[TUYA_LIGHT] [1] ssid='Neighbor' ch=6 band=1 rssi=-40 sec=3
...（全信道扫描结果，方便确认目标热点在不在、是不是 5G）
[TUYA_LIGHT] 找到 AP MyHome, security=2
[TUYA_LIGHT] 获取到 IP: 192.168.1.52
[TUYA_LIGHT] Wi-Fi 就绪
[TUYA_LIGHT] NTP 对时成功, unix=1791632942
[TUYA_LIGHT] MQTT 已连接: ssl://m1.tuyacn.com:8883
[TUYA_LIGHT] 已订阅 tylink/<DeviceID>/thing/property/set
[TUYA_LIGHT] 上报 {"msgId":"2620","time":1791632943,"data":{"switch_led":false}}
[TUYA_LIGHT] 上报 {"msgId":"2622","time":1791632943,"data":{"cpu_usage":9,"chip_temp":46}}
[TUYA_LIGHT] 上报 {"msgId":"5623","time":1791632973,"data":{"cpu_usage":0,"chip_temp":47}}
...（每 30s 上报一次 cpu_usage / chip_temp）

```

手机 App 点开关，串口同步打印：

```auto
[TUYA_LIGHT] 收到下发 [tylink/<DeviceID>/thing/property/set] {"msgId":"3ba7...","time":...,"data":{"switch_led":true}}
[TUYA_LIGHT] LED -> ON
[TUYA_LIGHT] 上报 {"msgId":"34747","time":...,"data":{"switch_led":true}} ← 状态回报，App 显示同步

```

App 控制页（开关拨动即下发；CPU 占用率 / 芯片温度每 30s 刷新一次）：

 ![App 控制页](https://forum.hinearlink.com/uploads/default/original/1X/33286a4849f48308cd898f68190fc01b18e0400a.webp "gallery")

此时回到平台 **激活验证** 页点「刷新」，DeviceStatus 变为 **在线** 。

* * *

## 常见问题（FAQ）

**1. MQTT 一直连不上，串口只看到「MQTT 连接失败」**  
先查 2.3 的 ECDHE 修复是否生效（涂鸦云 TLS 会以 `alert 71 insufficient_security` 拒绝）。如果开了 paho 日志（`tuya_mqtt.c` 顶部 `TUYA_DEBUG_MQTT_TRACE` 改 1）能看到 `ssl handshake fail`。

**2. paho 初始化相关失败 / MQTTClient\_create 返回错误**  
LiteOS 版 paho 不会自动创建内部互斥锁，**必须先调一次 `MQTTClient_init()`**（源码里已处理，`g_mqtt_lib_inited` 保证只调一次）。自己改代码时注意别把这行删了。

**3. Wi-Fi 扫不到 / 连不上**

- WS63 只支持 **2.4G** ，5G SSID 扫不到（扫描日志里能看到所有 AP，对比确认）。
- SSID 带中文/特殊字符、隐藏 SSID 都可能匹配失败。
- 代码是全信道扫描后在结果里精确匹配 SSID，匹配逻辑在 `tuya_wifi_match()`。

**4. 显示连上云了，但平台 DeviceStatus 还是「离线」**

- 先点激活验证页的 **刷新** ：这个页面的 DeviceStatus 初始值是 **缓存的快照** ，可能是旧的「离线」。
- 别被 **设备管理** 列表的状态列误导： **未绑定** 设备恒显示「未绑定离线」，设备明明在线也不变；以设备日志页（每 30s 有属性上报）为准。
- DeviceID/DeviceSecret 和平台上注册的设备是不是同一对（换产品/重新注册后要同步更新）。
- NTP 是否对时成功——鉴权用的 timestamp 来自 NTP，时间不对签名直接被拒（串口会打印「时间未同步,无法鉴权」）。
- 数据中心不一致：中国区设备连 `m1.tuyaus.com`（美西）之类的会导致鉴权失败，`tuya_mqtt.c` 顶部的 `TUYA_MQTT_HOST` 要和创建产品时选的数据中心一致。

**5. App 扫码绑定失败 / 绑定后马上离线**

- 先确认 **设备绑定范围配置** 已保存（见 1.4 节开头），这是最常见的坑。
- 只有 **已上线的设备** 才能绑定成功：先在平台激活验证页点「刷新」确认在线。
- App 要选对区域：中国数据中心 ↔ 涂鸦智能 App（国内账号）；海外 ↔ Smart Life / Tuya Smart。跨区域会绑定失败。
- TuyaLink 设备不会出现在 App「添加设备」的自动发现列表里，只能扫码绑定（见 1.4 节）。

**6. App 点开关，LED 没反应**

- 平台「功能定义」里开关的 **标识符必须是 `switch_led`** （不是名字叫开关就行，看标识符字段）。改了标识符就同步改 `tuya_dp.c` 顶部的 `TUYA_DP_SWITCH_LED_NAME`。
- 看串口有没有「收到下发」——有下发说明链路通，问题在 LED 引脚/极性。

**7. Windows 上编译报 `error while loading shared libraries: ?`（全新 clone 的 SDK）**  
SDK 里 riscv 工具链目录下少 4 个 Windows 运行库：`libgcc_s_sjlj-1.dll`、`libssp-0.dll`、`libstdc++-6.dll`、`libwinpthread-1.dll`（`tools/bin/compiler/riscv/cc_riscv32_musl_105/` 下两套工具链各 3 个目录需要）。从其它能正常编译的 SDK 拷贝补齐，或按 `tools/WSL子系统编译及烧录.md` 改用 WSL 编译。

* * *

## 协议速查（TuyaLink 开放协议）

| 项目 | 值 |
| --- | --- |
| Broker | `m1.tuyacn.com:8883`（TLS 1.2，MQTT） |
| clientId | `tuyalink_<DeviceID>` |
| username | `<DeviceID>|signMethod=hmacSha256,timestamp=<unix>,secureMode=1,accessType=1` |
| password | `hex( HMAC-SHA256(DeviceSecret, "deviceId=<DeviceID>,timestamp=<unix>,secureMode=1,accessType=1") )` |
| 下行订阅 | `tylink/<DeviceID>/thing/property/set` |
| 上行发布 | `tylink/<DeviceID>/thing/property/report` QoS1 |

上行 payload：`{"msgId":"...","time":<unix>,"data":{...}}`；下行 payload 的 `data` 里是功能点，如 `{"switch_led":true}`。

* * *

## 注意事项

1. **证书校验** ：示例默认 `tuya_mqtt.c` 里 `TUYA_SKIP_CERT_VERIFY 1`（不校验证书，方便首次打通链路）。量产应改为 0 并内置涂鸦根证书。
2. **授权码** ：注册设备消耗授权码（注册设备 ≠ 烧录，同一设备重新烧录固件不用重新注册）。
3. **凭证保密** ：在 menuconfig 里填的 Wi-Fi 密码和设备密钥会写进 SDK 的 `ws63_liteos_app.config` 配置文件和构建产物，别把这些推到公开仓库；样例源码本身不含任何凭证。
4. **本示例为教学用途** ：错误重连、状态机都尽量直白，生产环境建议加上看门狗、参数持久化（掉电保存开关状态）等。

* * *

**作者** : GaoXiaolong

**邮箱** : [gaoxiaolon@gmail.com](mailto:gaoxiaolon@gmail.com)

**日期** : 2026.10.10

* * *

- 分类：通信
- 许可证：Apache-2.0
- 代码仓库：[samples/ws63/tuya\_light · 星闪开源社区/samples - AtomGit](https://gitcode.com/hinearlink/samples/tree/main/ws63/tuya_light)

站内项目：[TuyaLink 光源 · 海星社区](https://hinearlink.com/workshop/tuya-light)

> 这条主题由主站发布项目时自动创建；主站与论坛的评论会互相同步。
