欢迎光临
我们一直在努力

(七)RT-Thread物联网实战--MQTT-cJSON-OneNET

RT-Thread物联网实战 — MQTT + cJSON + OneNET云平台

前言

设备联网之后,如何将数据上传到云平台并实现远程监控?本文将串联MQTT协议、Paho MQTT库、cJSON数据解析以及OneNET云平台,构建完整的物联网数据链路:传感器 → MCU → ESP8266 → MQTT → OneNET云平台。


一、MQTT 协议

1.1 什么是MQTT?

MQTT(Message Queuing Telemetry Transport)是一种发布/订阅模式的轻量级消息传输协议,专为低带宽、不稳定网络和低功耗场景设计,是物联网通信的首选协议。

1.2 核心角色

角色说明比喻
发布者(Publisher) 发送数据的设备 投稿人
订阅者(Subscriber) 接收数据的设备 读者
代理(Broker) 消息路由中心 报社编辑部
主题(Topic) 消息分类标签 报纸栏目

发布者和订阅者不直接通信,而是通过Broker中转,实现松耦合。

1.3 工作流程

  • 设备连接Broker:通过TCP长连接,使用唯一的客户端ID注册。
  • 发布者发布消息:指定主题发送数据,如 /home/livingroom/temperature → 25°C。
  • Broker转发消息:找到所有订阅该主题的客户端,逐一推送。
  • 订阅者接收消息:处理接收到的数据。
  • 1.4 主题通配符

    • 单层通配符 +:/home/+/temperature 匹配所有房间的温度
    • 多层通配符 #:/home/# 匹配家中所有传感器数据

    1.5 QoS 消息质量

    QoS级别保证适用场景
    QoS 0 至多一次,可能丢失 温度数据等非关键信息
    QoS 1 至少一次,可能重复 开关控制指令
    QoS 2 恰好一次,不丢不重 报警状态等关键信息

    1.6 保留消息与遗嘱消息

    • 保留消息:Broker保存主题的最新消息,新订阅者加入时立即推送,适合状态同步。
    • 遗嘱消息:客户端连接时预设,意外断开时Broker自动发布,适合故障通知。

    二、Paho MQTT 库

    Paho MQTT 是RT-Thread中常用的MQTT客户端库,提供完整的连接、订阅、发布功能。

    2.1 订阅列表配置

    MQTTClient client;

    client.messageHandlers[0].topicFilter = "/device/data";
    client.messageHandlers[0].callback = mqtt_sub_callback;
    client.messageHandlers[0].qos = QOS1;

    2.2 回调函数

    回调触发时机
    connect_callback MQTT连接成功
    online_callback 客户端上线
    offline_callback 客户端掉线
    defaultMessageHandler 默认消息接收
    messageHandlers[x].callback 指定主题消息接收

    2.3 URI 格式

    tcp://iot.eclipse.org:1883 // 域名
    tcp://192.168.10.1:1883 // IPv4
    ssl://192.168.10.1:1884 // SSL加密
    tcp://[fe80::20c:29ff:…]:1883 // IPv6

    2.4 核心API

    API说明
    paho_mqtt_start(client) 启动MQTT客户端
    paho_mqtt_stop(client) 停止MQTT客户端
    paho_mqtt_subscribe(client, qos, topic, cb) 订阅主题
    paho_mqtt_unsubscribe(client, topic) 取消订阅
    paho_mqtt_publish(client, qos, topic, msg) 发布消息
    paho_mqtt_control(client, cmd, arg) 控制客户端参数

    控制命令:

    命令功能
    MQTT_CTRL_SET_CONN_TIMEO 设置连接超时时间
    MQTT_CTRL_SET_RECONN_INTERVAL 设置重连间隔
    MQTT_CTRL_SET_KEEPALIVE_INTERVAL 设置心跳间隔
    MQTT_CTRL_PUBLISH_BLOCK 设置发布阻塞/非阻塞模式

    三、cJSON 库

    cJSON是轻量级JSON解析/生成库,物联网中用于构建上传数据和解析下发命令。

    3.1 核心数据结构

    typedef struct cJSON {
    struct cJSON *next, *prev; // 链表指针
    struct cJSON *child; // 子节点(对象/数组)
    int type; // 节点类型
    char *valuestring; // 字符串值
    int valueint; // 整数值
    double valuedouble; // 浮点值
    char *string; // 键名
    } cJSON;

    支持的类型:cJSON_False、cJSON_True、cJSON_NULL、cJSON_Number、cJSON_String、cJSON_Array、cJSON_Object

    3.2 解析 JSON

    /* 解析JSON字符串 */
    const char *json_str = "{\\"temperature\\":25,\\"humidity\\":60}";
    cJSON *root = cJSON_Parse(json_str);

    /* 获取字段值 */
    cJSON *temp = cJSON_GetObjectItem(root, "temperature");
    if (cJSON_IsNumber(temp))
    {
    rt_kprintf("温度: %d\\n", temp->valueint);
    }

    /* 释放内存 */
    cJSON_Delete(root);

    3.3 构建 JSON

    /* 创建JSON对象 */
    cJSON *root = cJSON_CreateObject();
    cJSON_AddNumberToObject(root, "temperature", 25);
    cJSON_AddStringToObject(root, "status", "normal");

    /* 转为字符串 */
    char *json_str = cJSON_PrintUnformatted(root);
    rt_kprintf("JSON: %s\\n", json_str); // {"temperature":25,"status":"normal"}

    /* 释放 */
    cJSON_free(json_str);
    cJSON_Delete(root);

    3.4 常用API速查

    操作API
    解析JSON cJSON_Parse(str)
    创建对象 cJSON_CreateObject()
    创建数组 cJSON_CreateArray()
    添加数字 cJSON_AddNumberToObject(obj, key, num)
    添加字符串 cJSON_AddStringToObject(obj, key, str)
    添加子对象 cJSON_AddItemToObject(obj, key, item)
    获取字段 cJSON_GetObjectItem(obj, key)
    获取数组元素 cJSON_GetArrayItem(arr, index)
    转为字符串 cJSON_Print(obj) / cJSON_PrintUnformatted(obj)
    释放对象 cJSON_Delete(obj)
    类型检查 cJSON_IsNumber() / cJSON_IsString() 等

    3.5 RT-Thread 内存适配

    cJSON_Hooks hooks;
    hooks.malloc_fn = rt_malloc;
    hooks.free_fn = rt_free;
    cJSON_InitHooks(&hooks);


    四、OneNET 云平台

    OneNET是中国移动推出的物联网开放平台,支持设备接入、数据存储、可视化展示和远程控制。

    4.1 工作原理

    OneNET软件包基于MQTT和HTTP Client实现:

    • 数据上传:通过MQTT向特定topic发布消息
    • 命令下发:Broker将服务器命令推送给设备
    • 数据查询:通过HTTP GET/POST请求获取历史数据

    ┌─────────┐ MQTT ┌──────────┐ HTTP ┌──────────┐
    │ 设备 │ ─────────→ │ OneNET │ ←─────────→ │ 网页/APP │
    │ (MCU) │ ←───────── │ Broker │ │ (用户) │
    └─────────┘ 命令下发 └──────────┘ 数据查询 └──────────┘

    4.2 依赖库

    库用途
    cJSON 构建/解析JSON数据
    Paho MQTT MQTT连接、发布、订阅
    HTTP Client 数据查询、设备注册

    4.3 初始化

    int onenet_mqtt_init(void);

    内部流程:

  • 设置MQTT参数(URI、设备ID、用户名、密码)
  • 注册回调函数(连接/上线/掉线/消息接收)
  • 启动MQTT客户端
  • /* 核心初始化逻辑 */
    mq_client.uri = "tcp://183.230.40.96:1883";
    mq_client.condata.clientID.cstring = device_id;
    mq_client.condata.username.cstring = product_id;
    mq_client.condata.password.cstring = auth_info;
    mq_client.defaultMessageHandler = mqtt_callback;
    paho_mqtt_start(&mq_client);

    4.4 数据上传API

    上传数字数据

    rt_err_t onenet_mqtt_upload_digit(const char *ds_name, const double digit);

    /* 上传温度数据到 "temperature" 数据流 */
    onenet_mqtt_upload_digit("temperature", 25.5);

    上传字符串数据

    rt_err_t onenet_mqtt_upload_string(const char *ds_name, const char *str);

    /* 上传设备状态 */
    onenet_mqtt_upload_string("status", "running");

    上传二进制数据

    rt_err_t onenet_mqtt_upload_bin(const char *ds_name, const uint8_t *bin, size_t len);

    从文件路径上传

    rt_err_t onenet_mqtt_upload_bin_by_path(const char *ds_name, const char *bin_path);

    向指定主题发布

    rt_err_t onenet_mqtt_publish(const char *topic, const uint8_t *msg, size_t len);

    4.5 命令接收与响应

    设置命令响应回调,当云端下发命令时自动调用:

    void cmd_response(uint8_t *recv_data, size_t recv_size,
    uint8_t **resp_data, size_t *resp_size)
    {
    rt_kprintf("收到命令: %.*s\\n", recv_size, recv_data);

    /* 构建响应 */
    *resp_data = (uint8_t *)"OK";
    *resp_size = 2;
    }

    /* 注册回调 */
    onenet_set_cmd_rsp_cb(cmd_response);

    4.6 数据查询API(HTTP)

    API说明
    onenet_http_get_datastream(name, info) 获取数据流信息
    onenet_get_dp_by_limit(name, n) 获取最近N个数据点
    onenet_get_dp_by_start_end(name, start, end, n) 获取指定时间段数据点

    4.7 设备管理API

    API说明
    onenet_http_register_device(name, auth) 注册新设备
    onenet_port_save_device_info(id, key) 保存设备信息(需用户实现)
    onenet_port_get_register_info(name, auth) 获取注册信息(需用户实现)
    onenet_port_get_device_info(id, key, auth) 获取设备信息(需用户实现)
    onenet_port_is_registed() 查询设备是否已注册

    五、完整物联网数据链路

    将前面所有知识串联起来,一个完整的物联网项目数据流如下:

    ┌─────────┐ GPIO ┌──────────┐ UART+AT ┌──────────┐
    │ DHT11 │ ──────────→ │ STM32 │ ──────────→ │ ESP8266 │
    │ 传感器 │ 温湿度数据 │ RT-Thread│ AT命令控制 │ WiFi模块 │
    └─────────┘ └──────────┘ └──────────┘
    │ │
    cJSON构建数据 MQTT发布
    │ │
    ▼ ▼
    ┌──────────┐ ┌──────────┐
    │ OneNET │ ←────────── │ MQTT │
    │ 云平台 │ 数据入库 │ Broker │
    └──────────┘ └──────────┘

    网页/APP展示

    关键技术栈对应:

    环节技术RT-Thread组件
    数据采集 GPIO/传感器框架 PIN设备、传感器框架
    设备联网 AT命令 + WiFi AT组件、ESP8266库
    数据格式化 JSON cJSON库
    数据传输 MQTT协议 Paho MQTT库
    云端对接 OneNET API OneNET软件包

    总结

    要点内容
    MQTT协议 发布/订阅模式,轻量高效,支持QoS
    Paho MQTT RT-Thread的MQTT客户端库
    cJSON 轻量级JSON解析/生成,物联网数据格式标准
    OneNET 中国移动物联网平台,支持MQTT+HTTP
    数据链路 传感器 → MCU → WiFi → MQTT → 云平台 → 用户
    赞(0)
    未经允许不得转载:171主机测评 » (七)RT-Thread物联网实战--MQTT-cJSON-OneNET
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址