Skip to content

概述

腾讯云物联网开发平台 IoT Explorer(腾讯云物联网平台 = 云端的设备管理后台)是腾讯云提供的物联网一站式开发平台,配套微信小程序「腾讯连连」给设备配网(配网 = 把 Wi-Fi 账号密码"告诉"开发板)和控制设备。本教程通过官方 qcloud_demo 示例工程,把 Ai-WB2 开发板接入腾讯云 IoT Explorer:使用腾讯连连小程序蓝牙辅助配网,配网成功后开发板自动连接 Wi-Fi 并接入云平台,按 KEY 键控制板载 LED 亮灭并上报属性(上报 = 设备→云端发数据),也可以从小程序/控制台下发指令(下发 = 云端→设备发指令)远程开关灯。

用大白话讲:腾讯云物联网平台就像「微信服务器」,产品 ID、设备名称、设备密钥是平台发的「账号密码」;配网就是通过微信小程序「腾讯连连」把家里 Wi-Fi 的账号密码"说"给开发板听(走蓝牙通道,不用接线);之后你按开发板上的按键,灯的状态就会像「发朋友圈」一样实时上报到云端,云端的设备「替身」同步更新;反过来,在小程序里点开关,指令也会像「发私信」一样下发到开发板把灯点亮。

本教程基于安信可官方 SDKAi-Thinker-Open/Ai-Thinker-WB2,版本 release_bl_iot_sdk_1.6.40)的官方示例 applications/iot-solution/qcloud_demo 编写,代码可在本地 SDK 中直接找到。

🎯本页目标在腾讯云 IoT Explorer 创建产品与设备,用腾讯连连小程序给开发板配网,让开发板接入云平台并按按键上报属性、接收云端下发指令。
🧰前置条件① Ai-WB2 开发板一块(Type-C 数据线,板载/外接 LED 与按键)② 2.4GHz 路由器(能访问公网)③ 一个腾讯云账号(需实名认证)④ 手机安装微信(含「腾讯连连」小程序)⑤ 已按 [SDK 安装](../sdk/sdk_intro) 完成环境搭建。
🔗相关章节另两个云平台见 [连接阿里云物联网平台](./ali_iot) 与 [连接AWS IoT 平台](./aws_iot);蓝牙配网原理见 [blufi 配网](../ble/blufi);MQTT 基础见 [MQTT 通信](../wireless/wifi/mqtt)。

注册腾讯云账号,创建产品与设备

这一步在云端"办账号":创建产品和设备,拿到设备登录平台用的三元组(产品 ID/设备名称/设备密钥)。

  1. 打开腾讯云官网,注册并登录账号(新用户需完成实名认证)。
  2. 搜索进入「物联网开发平台 IoT Explorer」控制台(首次进入需开通服务,公共实例免费)。
  3. 新建项目(如 WB2_Demo)→ 在项目下新建产品:产品类别选「标准品类」→ 智慧生活 → 电工照明 → ;联网方式选 Wi-Fi,配网方式选「标准 BLE 辅助」(本教程用蓝牙配网),并勾选「设备数据协议」的数据模板。
  4. 「设备调试 → 新建设备」,输入设备名称(如 wb2_light),创建成功后看到设备密钥(DeviceSecret)——只在创建时显示一次,务必保存。
  5. 在产品「设备列表」中可看到 产品 ID(ProductId)设备名称(DeviceName)——这两样随时可查,不用特意保存。

💡 接入云平台需要三元组:产品 ID + 设备名称 + 设备密钥(密钥只在创建设备时显示一次);示例代码还预留了**产品密钥(ProductSecret)**用于动态注册(可选功能,本教程用不到)。这些值下一步要填进代码。

硬件确认:本示例用开发板 GPIO 控制灯与按键,接线如下(默认已按 Ai-WB2-32S-Kit 配置):

外设 引脚
LED(灯) GPIO14
KEY(按键,按一下上报一次开关状态) GPIO8
重新配网键(长按约 5 秒清除 Wi-Fi 配置) GPIO4
进入示例工程

打开终端,进入官方 qcloud_demo 示例工程目录:

cd ~/Ai-Thinker-WB2/applications/iot-solution/qcloud_demo

说明:cd 是「进入目录」的命令,进入官方示例工程;后面所有 make 命令都要在这个目录下执行。

📌 该工程由多个源文件组成,完整代码章节只展示 main.c,其余文件可在官方工程中找到:

文件 作用
sdk_app_qcloud/main.c 主程序:Wi-Fi 连接 + 判断配网/上云流程,本教程主要看的文件
sdk_app_qcloud/light_data_template_sample.c 数据模板核心:属性上报/下发控制、LED 与按键逻辑
sdk_app_qcloud/qcloud_wifi_config_sample.c 配网流程(含配网方式开关宏 WIFI_PROV_*)与 Start_Qcloud_Demo()
sdk_app_qcloud/ble_qiot_ble_device.c / ble_qiot_ble_service.c 蓝牙辅助配网服务(腾讯连连小程序配网通道)
components/qcloud_iot_c_sdk/ 腾讯官方 IoT SDK(IOT_Template_* 系列接口所在),三元组在这里配置
修改参数(换成你自己的三元组)

打开 components/qcloud_iot_c_sdk/platform/HAL_Device_freertos.c,把示例三元组换成你在控制台拿到的值:

/* product Id  */
static char sg_product_id[MAX_SIZE_OF_PRODUCT_ID + 1] = "你的产品ID";
/* device name */
static char sg_device_name[MAX_SIZE_OF_DEVICE_NAME + 1] = "你的设备名称";
/* device secret of PSK device */
static char sg_device_secret[MAX_SIZE_OF_DEVICE_SECRET + 1] = "你的设备密钥";

⚠️ 该文件按配网方式分了两组三元组(WIFI_PROV_SOFT_AP_ENABLE 组与 WIFI_PROV_BT_COMBO_CONFIG_ENABLE 组),只编译你当前配网方式对应的一组。本教程默认蓝牙配网,改蓝牙组(#elif WIFI_PROV_BT_COMBO_CONFIG_ENABLE 分支下的三个变量)即可。若开启动态注册,还需把 DEV_DYN_REG_ENABLED 分支下的 sg_product_secret 换成你的产品密钥。

确认配网方式:打开 sdk_app_qcloud/qcloud_wifi_config_sample.c 顶部,默认是蓝牙辅助配网(WIFI_PROV_BT_COMBO_CONFIG_ENABLE 1,其余 WIFI_PROV_* 为 0),保持默认即可:

#define WIFI_PROV_BT_COMBO_CONFIG_ENABLE 1  ///< wifi provisioning method: bt combo config, need Wechat Applets
编写代码

本教程使用官方示例工程,无需新写代码,sdk_app_qcloud/main.c 完整代码已移至文末,见:

📜 完整代码 — 位于本页「完整代码」章节,默认折叠,点击展开,与官方示例(applications/iot-solution/qcloud_demo/sdk_app_qcloud/main.c)完全一致。数据模板上报/下发逻辑在 light_data_template_sample.c,配网逻辑在 qcloud_wifi_config_sample.c,其余文件见官方工程。

代码要点:

代码 作用
led_gpio_init(LED_PIN) / key_init(KEY_PIN) 初始化 LED 与按键引脚,不初始化灯不会亮、按键按了没反应
easyflash_init() 初始化掉电保存库,配网信息存在这里,不初始化读不到已保存的 Wi-Fi
wifi_info_read() 从掉电保存区读出 Wi-Fi 账号密码,没有就自动进入配网模式(LED 闪烁)
Q_Cloud_Config_Net_Start() 启动腾讯连连配网流程(蓝牙通道),配网是设备上云的第一步
Start_Qcloud_Demo() 配网/联网成功后启动云平台数据模板 Demo,设备正式接入云端
IOT_Template_Report(...) 把属性(如开关状态)上报到云端,不调用云上看不到设备状态
编译工程

在工程目录执行编译:

make -j8

说明:make 是「编译」命令,把代码变成开发板能运行的固件(烧进开发板的程序);-j8 表示用 8 个 CPU 核并行编译,更快。

编译成功后生成固件 build_out/sdk_app_qcloud.bin

⚠️ 若提示 riscv64-unknown-elf-gcc: command not found,说明工具链权限未配置,先执行 cd toolchain/riscv/Linux && . chmod755.sh 再重新编译。

烧录固件

开发板保持 USB 连接,确认串口设备号后执行烧录:

make flash p=/dev/ttyUSB0 b=921600

说明:make flash 是「烧录」命令,把编译好的固件写进开发板芯片。p= 后面是串口设备号(Linux 下常为 /dev/ttyUSB0,Windows 下是 COM3 之类,以你电脑实际为准,可用 ls /dev/ttyUSB* 查看),b=921600 是烧录波特率(串口传数据的速度),保持默认即可。

⏳ 烧录过程中按提示长按开发板 EN 键进入下载模式,等待进度条完成即烧录成功。

运行验证(配网 → 上云 → 按键上报 → 云端下发)

烧录完成后开发板自动重启,因为还没配过网,会自动进入配网模式(板载 LED 闪烁)。打开串口监视器(串口调试助手软件,波特率选 921600,波特率 = 串口传数据的"语速",两边必须一致)可以看到配网相关日志。

第一步:小程序配网。手机微信搜索「腾讯连连」小程序 → 进入「添加设备」→ 小程序自动扫描附近的设备 → 扫到后按提示选择你家 Wi-Fi、输入密码完成配网(配网 = 把 Wi-Fi 账号密码"告诉"开发板)。

第二步:等待上云。配网成功后开发板自动连接路由器并接入云平台,串口打印:

[APP] [EVT] GOT IP ...
Cloud Device Construct Success
Register data template propertys Success

第三步:按键上报。按开发板 KEY 键(GPIO8),LED 亮灭切换,串口打印 data template reporte success;打开腾讯连连小程序,能看到设备在线,灯的开关状态跟着变化。

第四步:云端下发。在腾讯连连小程序/控制台里点击开关,开发板 LED 同步点亮/熄灭,串口打印收到下发的控制消息。

出现 Cloud Device Construct Success 且腾讯连连小程序里设备在线、开关状态同步,即为成功;如果只看到 GOT IP 而没出现 Cloud Device Construct Success,说明还没成功,对照文末「常见问题与踩坑提示」排查。

代码执行流程

例程从启动到运行的完整流程如下(图中的循环箭头表示反复执行):


本文 API 汇总

Start_Qcloud_Demo()

配网/联网成功后启动云平台数据模板 Demo:创建 bl_qcloud_main 任务接入腾讯云(自研接口,源码在 sdk_app_qcloud/qcloud_wifi_config_sample.c)。

参数

返回值:无

Q_Cloud_Config_Net_Start()

启动腾讯连连配网流程(默认蓝牙辅助配网),配网成功后把 Wi-Fi 账号密码存入掉电保存区(自研接口,源码在 sdk_app_qcloud/qcloud_wifi_config_sample.c)。

参数

返回值:无

IOT_Template_Construct(pParams, pMqttClient)

构造数据模板客户端:解析三元组、创建 MQTT 连接(腾讯官方 SDK 接口,头文件 components/qcloud_iot_c_sdk/include/exports/qcloud_iot_export_data_template.h)。

参数

  • pParamsTemplateInitParams 结构体指针(区域、超时等,示例为 { "china", NULL, NULL, NULL, 2000, 1000, 1, 1, { 0 } }
  • pMqttClient:已有 MQTT 客户端句柄,无则传 NULL(由本函数内部创建)

返回值:成功返回客户端句柄(void *);失败返回 NULL

IOT_Template_Start_Yield_Thread(pClient)

启动独立的收发线程,自动循环调用 IOT_Template_Yield 维持心跳与消息收发,之后主循环无需再手动 Yield。

参数

  • pClientIOT_Template_Construct 返回的客户端句柄

返回值:成功返回 QCLOUD_RET_SUCCESS(0);失败返回负值错误码

IOT_Template_Register_Property(pClient, pProperty, callback)

注册数据模板属性(如灯开关 light_switch),并绑定下发控制回调——云端下发修改该属性时,回调会被调用。

参数

  • pClient:客户端句柄
  • pPropertyDeviceProperty 结构体指针(属性键名、类型、数据指针)
  • callback:下发控制回调(示例为 OnControlMsgCallback

返回值:成功返回 QCLOUD_RET_SUCCESS(0);失败返回负值错误码

IOT_Template_JSON_ConstructReportArray(handle, jsonBuffer, sizeOfBuffer, count, pReportDataList)

把待上报的属性列表拼装成 JSON 报文(上报 = 设备→云端发数据),供 IOT_Template_Report 使用。

参数

  • handle:客户端句柄
  • jsonBuffer:输出缓冲区(示例为 sg_data_report_buffer[2048]
  • sizeOfBuffer:缓冲区大小
  • count:属性个数
  • pReportDataListDeviceProperty * 数组,存放待上报的属性

返回值:成功返回 QCLOUD_RET_SUCCESS(0);失败返回负值错误码

IOT_Template_Report(handle, pJsonDoc, sizeOfBuffer, callback, userContext, timeout_ms)

把属性 JSON 报文上报到云端,云端收到后回调 callback 确认结果。

参数

  • handle:客户端句柄
  • pJsonDoc:属性 JSON 报文
  • sizeOfBuffer:报文长度
  • callback:上报应答回调(示例为 OnReportReplyCallback
  • userContext:透传数据,无则传 NULL
  • timeout_ms:超时毫秒数(示例 QCLOUD_IOT_MQTT_COMMAND_TIMEOUT

返回值:成功返回 QCLOUD_RET_SUCCESS(0);失败返回负值错误码

IOT_Template_ControlReply(handle, pJsonDoc, sizeOfBuffer, replyPara)

回复云端的下发控制消息——收到控制指令必须应答,否则云端会认为设备没收到而保留消息。

参数

  • handle:客户端句柄
  • pJsonDoc:应答报文缓冲区
  • sizeOfBuffer:缓冲区大小
  • replyParasReplyPara 结构体指针(处理结果 code 与超时等)

返回值:成功返回 QCLOUD_RET_SUCCESS(0);失败返回负值错误码

IOT_Template_Yield(pClient, timeout_ms)

让 SDK 处理与云端的消息收发与心跳保活,必须在主循环反复调用(示例循环 200ms 调一次),断线时返回 QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT

参数

  • pClient:客户端句柄
  • timeout_ms:超时毫秒数,示例 200

返回值:成功返回 QCLOUD_RET_SUCCESS(0);重连中返回 QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT

📌 数据模板的属性(light_switchcolorbrightness 等)要与控制台产品「数据模板」里定义的属性一致;示例用按键中断 + 信号量通知上报任务的方式触发上报,主循环负责收发与应答。


完整代码

以下为 sdk_app_qcloud/main.c 完整源码,与官方示例(applications/iot-solution/qcloud_demo/sdk_app_qcloud/main.c)完全一致(数据模板逻辑在 light_data_template_sample.c,配网逻辑在 qcloud_wifi_config_sample.c,其余文件见官方工程):

📜 点击展开 sdk_app_qcloud/main.c 完整代码
c
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#include <aos/kernel.h>
#include <aos/yloop.h>
#include <lwip/tcpip.h>
#include <bl_sys.h>
#include <hal_wifi.h>
#include <blog.h>
#include <hal_sys.h>
#include <easyflash.h>
#include <wifi_mgmr_ext.h>
#include "FreeRTOS.h"
#include "task.h"
#include <hal_hwtimer.h>


#define KEY_PIN     (8)
#define LED_PIN     (14)
#define restore_key (4)

extern void key_init(uint8_t pin);
extern void led_gpio_init(uint8_t pin);
extern void restore_key_init(uint8_t pin);

static wifi_conf_t conf =
{
    .country_code = "CN",
};

extern  char sta_ssid[33];
extern char sta_passwd[65];
extern hw_timer_t* qcloud_demo_handle;
extern void Start_Qcloud_Demo(void);

static void wifi_sta_connect(char* ssid, char* password)
{
    wifi_interface_t wifi_interface;

    wifi_interface = wifi_mgmr_sta_enable();
    wifi_mgmr_sta_connect(wifi_interface, ssid, password, NULL, NULL, 0, 0);
}

static bool wifi_info_read()
{
    size_t len;
    ef_get_env_blob("ssid", sta_ssid, sizeof(sta_ssid), &len);
    if (strlen(sta_ssid) ==0) {
        blog_error("[NV] get sta_ssid fail:%d ", len);
        return false;
    }
    else {
        blog_info("sta_ssid:%s", sta_ssid);
    }

    ef_get_env_blob("pwd", sta_passwd, sizeof(sta_passwd), &len);
    if (strlen(sta_passwd) ==0) {
        blog_error("[NV] get sta_passwd fail:%d ", len);
    }
    else {
        blog_info("sta_passwd:%s", sta_passwd);
    }
    return true;
}

static void event_cb_wifi_event(input_event_t* event, void* private_data)
{
    extern bool q_cloud_IsConnected;
    static bool wifi_info_isSet = false;
    switch (event->code) {
        case CODE_WIFI_ON_INIT_DONE:
        {
            blog_info("[APP] [EVT] INIT DONE %lld", aos_now_ms());
            wifi_mgmr_start_background(&conf);
        }
        break;
        case CODE_WIFI_ON_MGMR_DONE:
        {
            blog_info("[APP] [EVT] MGMR DONE %lld", aos_now_ms());
            if (wifi_info_read())
            {
                wifi_info_isSet = true;
                wifi_sta_connect(sta_ssid, sta_passwd);
            }
            else
            {
                extern void Q_Cloud_Config_Net_Start(void);
                Q_Cloud_Config_Net_Start();
            }
        }
        break;
        case CODE_WIFI_ON_MGMR_DENOISE:
        {
            blog_info("[APP] [EVT] Microwave Denoise is ON %lld", aos_now_ms());
        }
        break;
        case CODE_WIFI_ON_SCAN_DONE:
        {
            blog_info("[APP] [EVT] SCAN Done %lld", aos_now_ms());
            wifi_mgmr_cli_scanlist();
        }
        break;
        case CODE_WIFI_ON_SCAN_DONE_ONJOIN:
        {
            blog_info("[APP] [EVT] SCAN On Join %lld", aos_now_ms());
        }
        break;
        case CODE_WIFI_ON_DISCONNECT:
        {
            blog_info("[APP] [EVT] disconnect %lld, Reason: %s",
                   aos_now_ms(),
                   wifi_mgmr_status_code_str(event->value));
            q_cloud_IsConnected = 0;
        }
        break;
        case CODE_WIFI_ON_CONNECTING:
        {
            blog_info("[APP] [EVT] Connecting %lld", aos_now_ms());
        }
        break;
        case CODE_WIFI_CMD_RECONNECT:
        {
            blog_info("[APP] [EVT] Reconnect %lld", aos_now_ms());
        }
        break;
        case CODE_WIFI_ON_CONNECTED:
        {
            blog_info("[APP] [EVT] connected %lld", aos_now_ms());
        }
        break;
        case CODE_WIFI_ON_PRE_GOT_IP:
        {
            blog_info("[APP] [EVT] connected %lld", aos_now_ms());
        }
        break;
        case CODE_WIFI_ON_GOT_IP:
        {
            blog_info("[APP] [EVT] GOT IP %lld", aos_now_ms());
            blog_info("[SYS] Memory left is %d Bytes", xPortGetFreeHeapSize());
            if (wifi_info_isSet)
            {
                qcloud_demo_handle = hal_hwtimer_create(100, Start_Qcloud_Demo, 1);
            }
            else
            {
                q_cloud_IsConnected = 1;
            }
        }
        break;
        case CODE_WIFI_ON_EMERGENCY_MAC:
        {
            blog_info("[APP] [EVT] EMERGENCY MAC %lld", aos_now_ms());
            hal_reboot(); // one way of handling emergency is reboot. Maybe we should also consider solutions
        }
        break;
        case CODE_WIFI_ON_PROV_CONNECT:
        {
            blog_info("[APP] [EVT] [PROV] [CONNECT] %lld", aos_now_ms());
            blog_info("connecting to %s:%s...", sta_ssid, sta_passwd);
            wifi_sta_connect(sta_ssid, sta_passwd);
        }
        break;
        case CODE_WIFI_ON_PROV_DISCONNECT:
        {
            blog_info("[APP] [EVT] [PROV] [DISCONNECT] %lld", aos_now_ms());
        }
        break;
        case CODE_WIFI_ON_AP_STA_ADD:
        {
            blog_info("[APP] [EVT] [AP] [ADD] %lld, sta idx is %lu", aos_now_ms(), (uint32_t)event->value);
        }
        break;
        case CODE_WIFI_ON_AP_STA_DEL:
        {
            blog_info("[APP] [EVT] [AP] [DEL] %lld, sta idx is %lu", aos_now_ms(), (uint32_t)event->value);
        }
        break;
        default:
        {
            blog_info("[APP] [EVT] Unknown code %u, %lld", event->code, aos_now_ms());
            /*nothing*/
        }
        break;
    }
}

/**
 * @brief 直接串口打印系统任务管理器
 */
void show_task_state_task(void* param)
{
    char* pcWriteBuffer = malloc(1024);

    for (;;)
    {
        blog_info("=============================================");
        blog_info("name \t\tstatus \tprio \tfree \tpid");
        vTaskList((char*)pcWriteBuffer);
        blog_info("%s", pcWriteBuffer);
        blog_info("\n=============================================");

        blog_info("=====================================");
        blog_info("FreeHeapSize is %d bytes", xPortGetFreeHeapSize());
        blog_info("MinimumEverFreeHeapSize is %d bytes", xPortGetMinimumEverFreeHeapSize());
        blog_info("=====================================");

        vTaskDelay(pdMS_TO_TICKS(2000));
    }
}

static void proc_main_entry(void* pvParameters)
{
    easyflash_init();
    aos_register_event_filter(EV_WIFI, event_cb_wifi_event, NULL);

    hal_wifi_start_firmware_task();
    /*Trigger to start Wi-Fi*/
    aos_post_event(EV_WIFI, CODE_WIFI_ON_INIT_DONE, 0);

    vTaskDelete(NULL);
}

int main(void)
{
    led_gpio_init(LED_PIN);
    key_init(KEY_PIN);
    restore_key_init(restore_key);
    bl_sys_init();
    xTaskCreate(proc_main_entry, (char*)"main_entry", 1024, NULL, 15, NULL);

    // xTaskCreate(show_task_state_task, (char *)"status_show", 512, NULL, 8, NULL);

    tcpip_init(NULL, NULL);
    blog_info("qcloud demo running");

    return 0;
}

常见问题与踩坑提示

⚠️ 一直没出现 Cloud Device Construct Success(连不上云平台)
原因:三元组没改全或改错组(HAL_Device_freertos.c 里 softAP 组与蓝牙组各有一套,默认只编译蓝牙组)、产品品类与代码属性不符
解决:核对蓝牙组(WIFI_PROV_BT_COMBO_CONFIG_ENABLE 分支)的 sg_product_id/sg_device_name/sg_device_secret 与控制台一致(注意区分大小写);产品品类建议选「智慧生活 → 电工照明 → 灯」,数据模板需包含开关等属性

⚠️ 腾讯连连小程序扫描不到设备 / 配网失败
原因:开发板没进配网模式(LED 未闪烁)、手机蓝牙/定位权限未开、或产品配网方式没选「标准 BLE 辅助」
解决:确认烧录后 LED 是否闪烁(闪烁 = 在配网模式);小程序授权蓝牙与定位权限;控制台产品「配网方式」勾选「标准 BLE 辅助」;手机靠近开发板再试

⚠️ 配网成功后一直 Connecting 不 GOT IP(连不上路由器)
原因:配网时 Wi-Fi 密码输错、路由器是 5GHz 频段、或信号过弱
解决:长按 GPIO4 键约 5 秒清除已保存的 Wi-Fi 配置,重新配网;确认路由器开 2.4GHz;开发板靠近路由器;可先单独跑 连接 Wi-Fi 验证联网

⚠️ 按键后小程序里开关状态没变化
原因:按键对应 GPIO8 没接好、或上报的属性与产品数据模板不一致
解决:确认 KEY 按键接 GPIO8、LED 接 GPIO14;检查上报 JSON 里的属性名与「产品 → 数据模板」中的定义一致

⚠️ 串口找不到设备 / 打不开
原因:USB 转串口驱动未装、权限不足,或数据线只能充电不能传数据
解决:Linux 用 lsusb/dmesg 查看设备,权限不足执行 sudo usermod -aG dialout $USER 后重新登录,或 sudo chmod 666 /dev/ttyUSB0;Windows 装驱动后到设备管理器查 COM 口;换一根能传数据的线

⚠️ 烧录一直等待 / 失败
原因:未进入下载模式、波特率不对、或串口号填错
解决:烧录时按提示长按 EN 键进入下载模式;确认 p=/dev/ttyUSB0 换成你实际的串口;换 USB 口或数据线重试

运行自检

腾讯连连小程序配网成功、串口出现 Cloud Device Construct Success,按 KEY 键串口打印 data template reporte success,且小程序里设备在线、开关状态与 LED 同步变化(云端下发也能点亮 LED),即接入腾讯云物联网平台验证通过。

遇到问题?

如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23