发新帖本帖赏金 100.00元(功能说明)我要提问
返回列表
打印
[APM32F4]

ETH应用:使用mbedos自带的mbed-mqtt库与云平台通信(MQTT协议)

[复制链接]
5107|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
DKENNY|  楼主 | 2024-4-24 18:28 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 DKENNY 于 2024-4-25 16:37 编辑

#申请原创# @21小跑堂

最近了解了MQTT协议,发现mbed-os中自带了一个mbed-mqtt库,这个库把mqtt通信基本上都封装成了一个API,使用起来较为方便,这篇文档主要介绍一下如何使用mbedos自带的mbed-mqtt库,并使用APM32F407IG-Tiny的板载ETH接口与物联网云平台建立通信,把我们实时获取的数据存放云平台的服务器中。

1、mqtt协议介绍
MQTT(Message Queuing Telemetry Transport)是一种轻量级的、开放式的消息协议,用于在客户端和服务器之间进行通信。它最初由IBM开发,现在由OASIS(Organization for the Advancement of Structured Information Standards)进行标准化。MQTT被设计用于可靠地在受限的网络环境中进行通信,如物联网设备、传感器等。

以下是 MQTT 协议的一些关键特性和概念:

1. **发布/订阅模型**:
   MQTT 使用发布/订阅模型进行通信。发布者(Publisher)发布消息到特定的主题(Topic),订阅者(Subscriber)订阅感兴趣的主题,并接收发布到这些主题的消息。

2. **主题(Topic)**:
   主题是 MQTT 中用于消息过滤和路由的核心概念。发布者将消息发布到一个或多个主题,而订阅者则订阅一个或多个主题以接收消息。主题是用斜杠(/)分隔的字符串,例如:`/sensor/temperature`。

3. **QoS(服务质量)**:
   MQTT 支持三种不同级别的服务质量:
   - QoS 0:最多一次传输。消息发布者将消息发送出去,但不进行确认。消息可能会丢失。
   - QoS 1:至少一次传输。消息发布者将消息发送出去,并等待接收到的确认。如果确认未收到,消息将被重新发送。
   - QoS 2:恰好一次传输。消息发布者和接收者都会进行确认,确保消息不会丢失且不会重复。

4. **保留消息(Retained Messages)**:
   发布者可以选择保留消息,这意味着最新的消息将会被存储在 MQTT 服务器上,并在有新的订阅者连接时立即发送给它们。

5. **清理会话(Clean Session)**:
   客户端可以选择使用清理会话标志,如果设置为true,则客户端和服务器之间的会话信息在断开连接时会被清除。

6. **遗嘱消息(Last Will and Testament)**:
   客户端可以指定遗嘱消息,当客户端异常断开连接时,服务器将会发布这条消息到指定的主题。

7. **连接和断开**:
   MQTT 客户端通过 TCP/IP 或其他支持的传输协议连接到 MQTT 服务器。连接后,客户端可以发布和订阅消息。断开连接时,客户端发送一个断开连接的消息给服务器。

8. **安全性**:
   MQTT 支持使用 TLS/SSL 进行加密通信,并可以使用用户名和密码进行身份验证。

总的来说,MQTT 是一种灵活、可靠且适用于各种网络环境的消息传输协议,特别适用于物联网和实时数据传输场景。


2、mbedos mqtt库

在 Mbed OS 中,我们可以使用 Mbed OS 的 MQTT 库来实现 MQTT 协议的功能。Mbed OS 是一个嵌入式操作系统,旨在为物联网设备提供支持,而 MQTT 则是一种常用的通信协议,适用于物联网和传感器网络等场景。

Mbed OS 提供了一个名为 `Mbed OS MQTT` 的库,可以帮助你在设备上轻松实现 MQTT 客户端功能。以下是关于 Mbed OS MQTT 库的一些介绍:

1. **简化的 API**:
   Mbed OS MQTT 库提供了一个简化的 API,使得在设备上实现 MQTT 客户端变得简单和直观。我们可以使用这些 API 来连接到 MQTT 服务器、发布消息、订阅主题等。

2. **与 Mbed OS 互操作性**:
   由于 Mbed OS MQTT 库是专为 Mbed OS 设计的,因此它与 Mbed OS 的其他组件和功能良好地集成在一起。我们可以轻松地将 MQTT 功能与其他 Mbed OS 组件,如传感器、网络连接等结合起来,构建出完整的物联网应用程序。

3. **支持多种传输协议**:
   Mbed OS MQTT 库支持多种传输协议,包括 TCP、TLS 和 WebSocket 等。这使得它可以在各种网络环境下运行,包括本地网络和互联网。

4. **安全性支持**:
   MQTT 库提供了对 TLS/SSL 的支持,可以对通信进行加密,确保数据的安全性。我们可以使用 TLS/SSL 来保护 MQTT 客户端与服务器之间的通信。

5. **灵活的配置选项**:
   Mbed OS MQTT 库提供了一些配置选项,可以根据你的需求进行调整。我们可以配置消息质量服务(QoS)、连接超时、遗嘱消息等参数,以满足你的具体需求。

6. **示例和文档**:
   Mbed OS MQTT 库附带了示例代码和详细的文档,帮助我们快速上手并了解如何在你的应用程序中集成 MQTT 功能。

总的来说,Mbed OS MQTT 库是一个强大而灵活的工具,可以帮助我们轻松地在 Mbed OS 上实现 MQTT 客户端功能,并构建出可靠和安全的物联网应用程序。


3、使用mbedos MQTT库进行APM32开发
1、软件准备
mbed-os库获取:https://github.com/GeehySemi/mbed-os
mbed-mqtt库获取:https://github.com/ARMmbed/mbed-mqtt
免费的物联网在线云平台:http://www.nlecloud.com(其他的云平台也可,只要遵循相应的mqtt协议即可)

2、在mbed studio中新建工程,把mbed-os库(如果下载的源码带-master,需要先改名为"mbed-os")以及mbed-mqtt库(如果下载的源码带-master,需要先改名为"mbed-mqtt")复制到项目的根目录下。


3、浏览器输入http://www.nlecloud.com,打开开发者中心(没有创建账号的,需要先创建一个免费的账号)



4、创建一个新项目,输入新建项目的一些信息(由于使用的是板载 ETH,这里需要选择以太网通信)



5、点击设备和传感器,新建一个设备。



6、输入新建设备的一些信息,注意,这里我们选择MQTT协议进行通信。



7、点击传感器管理,新建一个传感器。我这里只新建了一个传感器,用于在线显示adc采集的数据,其他的也可自行创建。



8、查看云平台开发文档(http://www.nlecloud.com/doc/),找到MQTT协议介绍,下载相关资料。



9、MQTT开发文档里面规定了数据上传的 topic 以及 json 格式,我这里主要使用的是publish,主要使用的topic也只有一个,若要使用其余的topic,可以自行查看开发文档,这里就不过多介绍了。



10、编写main函数

/*
* Copyright (c) 2006-2020 Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*/
#include "mbed.h"

#include "EthernetInterface.h"
#include <MQTTClientMbedOs.h>
#include <cstring>
#include <string>
#include "MQTTNetwork.h"

SocketAddress ipAddress; //ip地址

char* mqtt_server = "mqtt.nlecloud.com"; //mqtt服务器域名
int mqtt_port = 1883;                    //mqtt服务器端口号

char* project_id = "896774";             //项目id
char* device_id = "957380";              //设备id
char* client_id = "apm32f407";           //设备标识符
char* device_key = "228c9236ac99407c92dcd9dacfdce115";//设备密钥

AnalogIn adc_data(PA_0);

int main(void)
{
    nsapi_error_t err;

    printf("ETH MQTT Test!\r\n");

    //使用默认的网络服务,APM32F407IG默认设置的是ETH接口
    NetworkInterface *net = NetworkInterface::get_default_instance();

    //使用DHCP动态分配IP地址
    net->connect();

    //打印测试ip地址是否分配成功
    err = net->get_ip_address(&ipAddress);
    printf("IP address : %s \r\n",ipAddress.get_ip_address());

    //新建一个MQTTNetwork网络接口
    MQTTNetwork mqttNetwork(net);

    //新建一个MQTTClient
    MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork);
    printf("Connect to %s: %d\r\n",mqtt_server,mqtt_port);

    //连接mqtt服务器
    err = mqttNetwork.connect(mqtt_server, mqtt_port);
    if(err != 0)
    {
        printf("mqtt server connect fail!\r\n");
        return -1;
    }

    //配置连接的项目参数
    MQTTPacket_connectData conn_data = MQTTPacket_connectData_initializer;
    conn_data.MQTTVersion = 3;
    conn_data.clientID.cstring = client_id; //client_id为设备标识符
    conn_data.username.cstring = device_id; //device_id为分配的设备id
    conn_data.password.cstring = device_key;//device_key为生成的密钥

    //客户端连接云平台,并打印相关信息
    if(client.connect(conn_data) != 0)
    {
        printf("mqtt server connect fail!\r\n");
        return -1;
    }
    else
    {
        printf("mqtt server connect success!\r\n");
    }

    //新建一个变量存储adc采集的数据
    unsigned short voltage = adc_data.read_u16();
    char buf[100];

    // buf = "{\"datatype\":1,\"datas\":{\"adc_data\":0.2}";
    sprintf(buf,"{\"datatype\":1,\"datas\":{\"adc_data\":%d}",voltage);

    //message为MQTTpublish的配置信息
    MQTT::Message message;
    message.dup = false;
    message.qos = MQTT::QOS1;
    message.retained = false;

    while(1)
    {
        //获取adc采集的数据
        voltage = adc_data.read_u16();
        sprintf(buf,"{\"datatype\":1,\"datas\":{\"adc_data\":%d},\"msgid\":001}",voltage);//json格式的上报数据信息,用buf缓存,上传的数据格式需要根据开发文档定义
        message.payload = (void*)buf;
        message.payloadlen = strlen(buf);

        //客户端上传数据
        client.publish("/sys/896774/957380/sensor/datas",message);//订阅的topic,topic 格式需要根据开发文档对应

        //每隔1s上传一次
        ThisThread::sleep_for(1s);
    }

    return 0;
}

上面的代码基本上都有注释,应该是不难理解的。
注意:我编写的main函数是DHCP自动获取IP地址的,当然也可以使用静态IP地址,这里就不介绍了。

上述代码主要实现的功能点:
这段代码是一个基于 Mbed OS 的以太网(ETH)和 MQTT 通信的示例程序。

### 功能概述

该程序的主要功能是从模拟输入(ADC)读取数据,将数据通过 MQTT 协议上传到指定的 MQTT 服务器(mqtt.nlecloud.com),并将数据发布到指定的主题 ("/sys/896774/957380/sensor/datas")。程序使用了 Mbed OS 的网络接口和 MQTTClientMbedOs 库来实现以太网连接和 MQTT 通信。

### 主要步骤和功能点分析

1. **网络连接设置**

   - 使用 `NetworkInterface::get_default_instance()` 获取默认的网络接口实例(此处为以太网接口)。
   - 调用 `net->connect()` 进行网络连接,使用 DHCP 动态分配 IP 地址。

2. **MQTT 客户端设置**

   - 创建 `MQTTNetwork` 实例 `mqttNetwork`,用于将 MQTT 客户端连接到底层网络。
   - 创建 `MQTT::Client<MQTTNetwork, Countdown>` 实例 `client`,该实例用于与 MQTT 服务器通信。

3. **连接 MQTT 服务器**

   - 使用 `mqttNetwork.connect()` 方法连接指定的 MQTT 服务器 (`mqtt.nlecloud.com`,端口 `1883`)。

4. **MQTT 客户端连接配置**

   - 配置 MQTT 连接所需的参数,包括 MQTT 版本、客户端 ID、用户名(设备 ID)、密码(设备密钥)等信息。

5. **建立 MQTT 连接**

   - 调用 `client.connect()` 方法与 MQTT 服务器建立连接,使用之前配置的连接参数。

6. **数据采集和上传**

   - 循环中,使用模拟输入 (`AnalogIn adc_data(PA_0)`) 读取 ADC(模拟数字转换器)采集的数据。
   - 将采集的数据格式化为 JSON 格式,并存储在 `buf` 中,格式类似 `{"datatype":1,"datas":{"adc_data":123}}`。
   - 使用 `client.publish()` 将格式化后的数据发布到指定的 MQTT 主题 ("/sys/896774/957380/sensor/datas")。

7. **循环上传数据**

   - 在循环中,定时(每隔1秒)读取 ADC 数据,并使用 MQTT 协议上传到 MQTT 服务器。

### 关键说明

- **IP 地址获取**:通过 `net->get_ip_address()` 获取分配给设备的 IP 地址,并打印在终端上。
- **MQTT 连接**:连接 MQTT 服务器后,根据设备 ID 和设备密钥配置 MQTT 连接参数,并通过 `client.connect()` 建立连接。
- **数据发布**:将格式化的数据使用 MQTT 协议发布到指定的主题 ("/sys/896774/957380/sensor/datas"),确保 MQTT 主题的格式符合预期。

### 注意事项

- 确保设备可以访问指定的 MQTT 服务器 (`mqtt.nlecloud.com:1883`)。
- 检查设备 ID 和设备密钥是否正确,以确保连接 MQTT 服务器成功。
- JSON 格式化数据的构建和 MQTT 主题的定义需要符合云平台的要求,确保数据能够被正确解析和处理。

这段代码展示了如何在 Mbed OS 中使用以太网和 MQTT 客户端实现数据上传到云平台的基本操作流程。

4、实验现象

1、代码烧录后,用一根网线把开发板和路由器连接,正常运行的话,mbed studio的串口打印下面的信息。


2、同时云平台的设备状态会由"离线"改为"在线"。



3、打开设备后的数据实时显示,可以看到数据的动态变化。


4、也可以查看设备的历史记录,可以看到数据每隔1s上传一次的。




参考资料
1、ETH类使用参考:
https://os.mbed.com/docs/mbed-os/v6.16/apis/ethernet.html

2、mbed-mqtt库使用参考:
https://github.com/ARMmbed/mbed-mqtt/blob/master/README.md

以上就是如何让使用mbedos自带的mbed-mqtt库与云平台建立通信的全部内容,希望本次分享的内容对开发有所帮助,如有问题,欢迎讨论交流。

附件:main.cpp源码(mbed-os库以及mbed-mqtt库需要手动下载)
main.cpp文件.zip (1.54 KB)















使用特权

评论回复

打赏榜单

21小跑堂 打赏了 100.00 元 2024-04-28
理由:恭喜通过原创审核!期待您更多的原创作品~

评论
21小跑堂 2024-4-28 15:55 回复TA
在极海MCU上移植mbedos MQTT库,实现单片机与云平台进行数据交互,文章详细介绍了所使用的MQTT协议以及mbedos mqtt库,最终的实验效果也十分理想。 
沙发
WoodData| | 2024-4-28 23:21 | 只看该作者
学习学习

使用特权

评论回复
发新帖 本帖赏金 100.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

39

主题

66

帖子

6

粉丝