一. ThingsCloud 云平台介绍
ThingsCloud 是一款面向物联网(IoT,Internet of Things)场景的云平台,旨在帮助开发者和企业快速实现设备上云、数据采集、远程监控和智能联动等功能。该平台提供设备管理、数据可视化、消息通信、规则引擎、OTA 升级等核心能力,支持 MQTT、HTTP、CoAP 等多种主流物联网通信协议,可广泛应用于智能家居、工业物联网、智慧农业、环境监测等领域。
平台核心概念
设备类型(Device Type)
设备类型是对同一类设备共有属性和功能的抽象定义。在 ThingsCloud 中,用户需要先创建"设备类型",定义该类设备的功能模型(包括属性、事件、服务等),然后再基于该类型创建具体的设备实例。例如,"温湿度传感器"可以作为一种设备类型,定义其包含温度、湿度两个属性。
设备(Device)
设备是物联网中的实际物理终端或虚拟终端,是数据采集和执行指令的基本单元。每个设备归属于某个设备类型,继承该类型的功能定义,并拥有唯一的设备标识和通信凭证。例如,某一块具体的 Arduino UNO Q 开发板就是一个设备实例。
属性(Property)
属性是设备功能模型中的基本数据单元,用于描述设备的状态信息。属性可以是只读的(如传感器上报的温度值)、可读写的(如 LED 开关状态),或者只写的。平台支持多种数据类型,包括布尔型(bool)、数值型(int / float / double)、字符串(string)、枚举(enum)等。
MQTT(Message Queuing Telemetry Transport)
MQTT 是一种基于发布/订阅模式的轻量级物联网通信协议,具有低带宽占用、低功耗、双向通信等特点,是 ThingsCloud 平台支持的核心协议之一。设备通过 MQTT 协议与云平台建立长连接,实现数据的实时上报和指令下发。
访问凭证(Access Credential)
每个设备在创建后会自动生成唯一的访问凭证(包括设备 ID、用户名、密码或证书),设备端需要配置这些凭证才能成功连接到云平台并进行身份认证。凭证是保障设备通信安全的关键。
控制台(Console)
控制台是 ThingsCloud 提供的 Web 管理界面,用户登录后可在控制台中完成设备类型创建、设备管理、属性定义、数据查看、规则配置等所有平台操作。控制台是用户与云平台交互的主要入口。
二. 创建设备类型和设备
- 登录网址 ThingsCloud - 物联网云平台 - 让万物互联更简单,进入云平台,点击"进入控制台";
-
点击"立即免费注册"注册账号,输入邮箱和设置密码,如之前有注册过则可直接登录;
-
注册成功之后则进入个人云平台;
-
开始创建设备类型;点击左边框的"设备类型";
- 点击"创建设备类型";
- 选择"创建自定义类型",并依次填入以下信息,最后点击"创建";其中,设备类型名称按实际项目命名(如"Arduino UNO Q"),协议类型选择 MQTT,认证方式选择 Token 认证;
- 创建设备类型成功;
-
开始创建设备;点击左边框的"所有设备";
-
点击"创建设备";
- 依次填入以下信息,并点击"创建";设备名称按实际设备命名(如"UNO Q-01"),设备类型选择上一步创建的"Arduino UNO Q",设备描述可填写备注信息便于后续识别;
- 创建成功;设备创建完成后,系统会自动生成该设备的访问凭证(包括设备 ID、用户名、密码等信息),请妥善保存这些信息,后续设备端代码配置将用到;
三. 为设备添加属性
-
点击"设备类型",选择我们刚刚创建的"Arduino UNO Q";
-
选择"功能定义",并点击"添加属性";
- 依次填入下列信息,点击"保存并继续添加";属性名称填写属性标识(如"temperature"),数据类型根据实际需求选择,读写权限根据需要设置为"只读"“读写"或"只写”;
- 依次填入下列信息,并保存;如需添加多个属性(如温度、湿度、LED 状态等),重复步骤 3~4,逐个添加即可;
自此,云平台配置全部完成。
四. 测试连接云平台
完成前面的云平台配置和代码准备后,本节将指导您将 Arduino UNO Q 开发板连接到 ThingsCloud 云平台,并验证连接是否成功。
前置条件: 其一,请确保 Arduino UNO Q 已按照首次配置指南完成初始设置,且已正常连接 WiFi 网络。如果尚未配置 WiFi,请先完成网络配置再继续以下步骤。其二,案例代码中的云平台信息需要替换成自己的云平台信息;
4.1 连接开发板到电脑
使用 USB-C 数据线将 Arduino UNO Q 开发板连接到电脑的 USB 接口。连接后,开发板的电源指示灯(PWR)应亮起,表示供电正常。
注意: 请使用支持数据传输的 USB-C 线缆(非仅充电线),确保电脑能够识别开发板。
4.2 打开 Arduino App Lab
在电脑上启动 Arduino App Lab 集成开发环境。App Lab 将自动检测已连接的 Arduino UNO Q 开发板,并在界面中显示设备信息。
4.3 导入测试代码
在 Arduino App Lab 中分别打开 sketch.ino 和 main.py 两个文件,并将以下代码填入对应文件。注意,云平台信息需要替换成自己的;
sketch.ino(微控制器侧代码):
/*
* sketch.ino - Arduino UNO Q 云平台连接测试 (微控制器侧)
* 功能:初始化串口与 Linux 模块通信,LED 状态指示
* 架构:MCU <--UART--> Linux 模块 <--TCP--> ThingsCloud
*/
#include <Arduino.h>
#define LINUX_BAUD_RATE 115200
#define DEBUG_BAUD_RATE 115200
#define LED_BLINK_FAST 200
#define LED_BLINK_SLOW 1000
enum ConnectionState {
STATE_INIT, STATE_WAITING, STATE_READY, STATE_CONNECTED, STATE_ERROR
};
ConnectionState g_state = STATE_INIT;
unsigned long g_last_blink = 0;
bool g_led_on = false;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(DEBUG_BAUD_RATE);
while (!Serial) { delay(10); }
Serial1.begin(LINUX_BAUD_RATE);
Serial.println(F("Arduino UNO Q - Cloud Connect Test"));
Serial.println(F("[MCU] Initializing..."));
Serial1.println(F("MCU:READY"));
g_state = STATE_WAITING;
}
void loop() {
handleLinuxData();
handleDebugInput();
updateLED();
}
void handleLinuxData() {
while (Serial1.available() > 0) {
String line = Serial1.readStringUntil('\n');
line.trim();
if (line.length() == 0) continue;
Serial.print(F("[Linux] "));
Serial.println(line);
if (line.startsWith("CONNECTED")) { g_state = STATE_CONNECTED; }
else if (line.startsWith("ERROR")) { g_state = STATE_ERROR; }
else if (line.startsWith("DISCONNECTED")) { g_state = STATE_WAITING; }
}
}
void handleDebugInput() {
while (Serial.available() > 0) {
Serial1.print(Serial.read());
}
}
void updateLED() {
unsigned long now = millis();
unsigned long interval;
switch (g_state) {
case STATE_INIT:
case STATE_WAITING:
case STATE_READY: interval = LED_BLINK_FAST; break;
case STATE_CONNECTED: interval = LED_BLINK_SLOW; break;
case STATE_ERROR: digitalWrite(LED_BUILTIN, HIGH); return;
default: interval = LED_BLINK_FAST; break;
}
if (now - g_last_blink >= interval) {
g_last_blink = now;
g_led_on = !g_led_on;
digitalWrite(LED_BUILTIN, g_led_on ? HIGH : LOW);
}
}
main.py(Linux 侧代码):
"""
main.py - Arduino UNO Q 云平台连接测试 (Linux 侧)
功能:TCP 连接 ThingsCloud → 发送注册包 → 保持长连接
前提:WiFi 已在首次配置时连接好,无需重复连接
"""
import socket
import time
import sys
# ThingsCloud TCP 服务器
TCP_HOST = "gz-3-device.iot-api.com"
TCP_PORT = 28801
# 注册包 (ProjectKey + AccessToken)
REGISTRATION_PACKET = "需要替换成自己的"
HEARTBEAT_INTERVAL = 60
MAX_RETRIES = 5
def connect_and_register():
"""建立 TCP 连接并发送注册包"""
print(f"[TCP] Connecting to {TCP_HOST}:{TCP_PORT} ...")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(15)
try:
sock.connect((TCP_HOST, TCP_PORT))
print("[TCP] Connection established.")
sock.sendall(REGISTRATION_PACKET.encode("utf-8"))
print(f"[TCP] Registration packet sent: {REGISTRATION_PACKET}")
return sock
except socket.timeout:
print("[TCP] Connection timed out.")
return None
except Exception as e:
print(f"[TCP] Error: {e}")
return None
def keep_alive(sock):
"""长连接保活循环"""
print("[Heartbeat] Starting keep-alive loop ...")
sock.settimeout(HEARTBEAT_INTERVAL)
last_heartbeat = time.time()
while True:
try:
try:
data = sock.recv(1024)
if data:
print(f"[Recv] {len(data)} bytes")
else:
print("[TCP] Server closed the connection.")
break
except socket.timeout:
pass
now = time.time()
if now - last_heartbeat >= HEARTBEAT_INTERVAL:
sock.sendall(b"\x00")
print("[Heartbeat] Ping sent.")
last_heartbeat = now
except (ConnectionResetError, BrokenPipeError):
print("[TCP] Connection lost.")
break
except Exception as e:
print(f"[TCP] Error: {e}")
break
def main():
print("=" * 50)
print(" Arduino UNO Q - ThingsCloud TCP Connection Test")
print("=" * 50)
sock = None
for attempt in range(1, MAX_RETRIES + 1):
sock = connect_and_register()
if sock is not None:
break
print(f"[Retry] Attempt {attempt}/{MAX_RETRIES}, retrying in 5s ...")
time.sleep(5)
if sock is None:
print("[FATAL] TCP connection failed after all retries. Exiting.")
sys.exit(1)
try:
keep_alive(sock)
except KeyboardInterrupt:
print("\n[Exit] User interrupted.")
finally:
sock.close()
print("[TCP] Connection closed.")
if __name__ == "__main__":
main()
代码配置说明: 以上代码中,TCP 服务器地址 gz-3-device.iot-api.com 和端口 28801 为 ThingsCloud 平台提供的 TCP 透传接入点,注册包 fG9wT1qtEl&tksc9thd5fqr27rn 由云平台的 ProjectKey 和 AccessToken 拼接而成(格式为:ProjectKey&AccessToken)。在实际使用中,请根据您自己的设备凭证替换注册包内容。
4.4 运行程序
代码填写完成后,点击 Arduino App Lab 界面中的"Run"按钮,系统将自动编译 sketch.ino 并启动 main.py。您可以在 App Lab 底部的输出面板中观察程序运行日志。
运行过程说明:
程序启动后将依次执行以下步骤:
- 微控制器初始化:sketch.ino 启动,初始化串口通信(Serial1 连接 Linux 模块),板载 LED 开始快速闪烁(表示等待连接状态);
- TCP 连接:main.py 向 ThingsCloud 服务器
gz-3-device.iot-api.com:28801发起 TCP 连接请求; - 发送注册包:连接建立后立即发送注册包进行身份认证,平台验证通过后设备上线;
- 心跳保活:连接成功后,每 60 秒发送一次心跳包维持长连接。
LED 状态指示:
| LED 行为 | 状态含义 |
|---|---|
| 快速闪烁(200ms/次) | 等待连接或正在连接中 |
| 慢速闪烁(1000ms/次) | 云平台已成功连接 |
| 常亮 | 发生错误,请检查日志 |
4.5 验证连接结果
返回 ThingsCloud 云平台控制台,进入"所有设备"页面,查看设备 uno q01 的状态。如果一切正常,设备状态应显示为"在线"(绿色指示灯),表示 Arduino UNO Q 已成功连接到云平台。
至此,Arduino UNO Q 已可以正常连接 ThingsCloud 云平台,后续可在此基础上添加数据上报、指令下发等业务功能。
附录:测试代码简介
测试代码由两个文件组成,分别运行在 Arduino UNO Q 的两个处理器上,二者通过 UART 串口协同工作。
sketch.ino — 微控制器侧(STM32U5 / RA4M1)
此文件运行在 Arduino UNO Q 的微控制器上,主要职责包括:
- 串口通信管理:通过 Serial1(UART)与 Linux 模块交换数据,接收 Linux 侧的状态消息并解析;
- 状态指示:通过板载 LED 的不同闪烁模式直观反映当前连接状态(等待→连接中→已连接→错误);
- 调试桥接:通过 Serial(USB)将调试信息输出到电脑,同时支持从 USB 向 Linux 模块转发指令。
main.py — Linux 模块侧
此文件运行在 Arduino UNO Q 的 Linux 协处理器上,主要职责包括:
- TCP 客户端:使用 Python 标准库
socket建立到 ThingsCloud 服务器的 TCP 长连接; - 设备注册:连接建立后立即发送注册包(ProjectKey&AccessToken),完成设备身份认证;
- 心跳保活:每 60 秒发送一个心跳字节
\x00,防止长连接因空闲超时被服务器断开; - 自动重连:TCP 连接失败时自动重试(最多 5 次,每次间隔 5 秒)。























