imx6ull/linux应用编程学习(17)利用mqtt上传开发板数据,和控制开发板led(基于正点)

1.关于如何创建自己的服务器,可看上篇文章

imx6ull/linux应用编程学习(16)emqx ,mqtt创建连接mqtt.fx-CSDN博客

2.实现任务:(正点原子教程源码改)

(1)用户可通过手机或电脑远程控制开发板上的一颗 LED 灯;

(2) 开发板客户端每隔 30 秒向服务端发送 SoC 当前的温度值,用户通过手机或电脑可查看到该温度值

首先我们需要先准备好这些:

1.首先mqtt.fx连接上服务器

2.准备好客户端id、用户名、用户名密码。

3.代码:

目录结构为

首先创建cmake文件夹、build文件夹、CMakeLists.txt、mqttClient.c文件

CMakeLists.txt(已经加上注释)

#*******************************************************************************
#  Copyright © ALIENTEK Co., Ltd. 1998-2021. All rights reserved.
#
#  顶层CMakeLists.txt
#  All rights reserved. This program and the accompanying materials
#  are made available under the terms of the Eclipse Public License v2.0
#  and Eclipse Distribution License v1.0 which accompany this distribution.
#*******************************************************************************/

# 指定最低的CMake版本要求
cmake_minimum_required(VERSION 2.8.12)

# 定义项目名称和使用的语言
project(MQTTClient C)

# 打印CMake的版本、系统名称和处理器信息
message(STATUS "CMake version: " ${CMAKE_VERSION})
message(STATUS "CMake system name: " ${CMAKE_SYSTEM_NAME})
message(STATUS "CMake system processor: " ${CMAKE_SYSTEM_PROCESSOR})

# 设置可执行文件输出路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

# 定义可执行文件目标
add_executable(mqttClient mqttClient.c)

# 指定MQTT客户端库头文件路径、库路径以及链接库
# ***大家需要根据MQTT的实际安装路径设置***

# 设置MQTT头文件搜索路径,这是ubuntu上的路径
target_include_directories(mqttClient PRIVATE /home/book/linux/tool/mqtt/paho.mqtt.c/install/include)

# 设置MQTT库文件搜索路径
target_link_directories(mqttClient PRIVATE /home/book/linux/tool/mqtt/paho.mqtt.c/install/lib)

# 链接MQTT库文件
# 你可以选择使用以下一种方式链接库文件:
# 方式1: 使用库名称进行链接
# target_link_libraries(mqttClient PRIVATE paho-mqtt3c)  #MQTT链接库 libpaho-mqtt3c.so

# 方式2: 使用库文件的完整路径进行链接,找到libpaho-mqtt3c.so文件,并且连接,意思为同步模式 MQTT 客户端库(不支持 SSL) 。
target_link_libraries(mqttClient /home/book/linux/tool/mqtt/paho.mqtt.c/install/lib/libpaho-mqtt3c.so)

在cmake文件夹中创建arm-linux-setup.cmake

arm-linux-setup.cmake

##################################
# 配置 ARM 交叉编译
##################################
set(CMAKE_SYSTEM_NAME Linux) # 设置目标系统名字
set(CMAKE_SYSTEM_PROCESSOR arm) # 设置目标处理器架构

# 指定编译器的 sysroot 路径
set(TOOLCHAIN_DIR /home/book/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf)
set(CMAKE_SYSROOT ${TOOLCHAIN_DIR}/arm-linux-gnueabihf/libc)

# 指定交叉编译器
set(CMAKE_C_COMPILER ${TOOLCHAIN_DIR}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_DIR}/bin/arm-linux-gnueabihf-g++)

# 为编译器添加编译选项
set(CMAKE_C_FLAGS "-march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7")
set(CMAKE_CXX_FLAGS "-march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7")

# 设置查找路径模式
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

编译器路径和sysroot路径自己指定,关于如何查找sysroot路径:

arm-linux-gnueabihf-gcc --print-sysroot

可得,下面就是路径,

返回上级目录,创建mqttClient.c

mqttClient.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "MQTTClient.h" //包含 MQTT 客户端库头文件
/* ########################宏定义##################### */
#define BROKER_ADDRESS "tcp://iot.ranye-iot.net:1883" //然也物联平台社区版 MQTT 服务器地址
/* 客户端 id、用户名、密码 *
* 当您成功申请到然也物联平台的社区版 MQTT 服务后
* 然也物联工作人员会给你发送 8 组用于连接社区版 MQTT 服务器
* 的客户端连接认证信息:也就是客户端 id、用户名和密码
* 注意一共有 8 组,您选择其中一组覆盖下面的示例值
* 后续我们使用 MQTT.fx 或 MQTTool 的时候 也需要使用一组连接认证信息
* 去连接社区版 MQTT 服务器!
* 由于这是属于个人隐私 笔者不可能将自己的信息写到下面 */
#define CLIENTID "您的客户端 ID" //客户端 id
#define USERNAME "您的用户名" //用户名
#define PASSWORD "您的密码" //密码
/* 然也物联社区版 MQTT 服务为每个申请成功的用户
* 提供了个人专属主题级别,在官方发给您的微信信息中
* 提到了
* 以下 dt_mqtt/ 便是笔者的个人主题级别
* dt_mqtt 其实就是笔者申请社区版 MQTT 服务时注册的用户名
* 大家也是一样,所以你们需要替换下面的 dt_mqtt 前缀
* 换成你们的个人专属主题级别(也就是您申请时的用户名)
*/
#define WILL_TOPIC "ymj/will" //遗嘱主题
#define LED_TOPIC "ymj/led" //LED 主题
#define TEMP_TOPIC "ymj/temperature" //温度主题
/* ################################################# */
static int msgarrvd(void *context, char *topicName, int topicLen,
MQTTClient_message *message)
{
if (!strcmp(topicName, LED_TOPIC)) { //校验消息的主题
if (!strcmp("2", message->payload)) //如果接收到的消息是"2"则设置 LED 为呼吸灯模式
system("echo heartbeat > /sys/class/leds/sys-led/trigger");
if (!strcmp("1", message->payload)) { //如果是"1"则 LED 常量
system("echo none > /sys/class/leds/sys-led/trigger");
system("echo 1 > /sys/class/leds/sys-led/brightness");
}
else if (!strcmp("0", message->payload)) {//如果是"0"则 LED 熄灭
system("echo none > /sys/class/leds/sys-led/trigger");
system("echo 0 > /sys/class/leds/sys-led/brightness");
}
// 接收到其它数据 不做处理
}
/* 释放占用的内存空间 */

MQTTClient_freeMessage(&message);
MQTTClient_free(topicName);
/* 退出 */
return 1;
}
static void connlost(void *context, char *cause)
{
printf("\nConnection lost\n");
printf(" cause: %s\n", cause);
}
int main(int argc, char *argv[])
{
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_willOptions will_opts = MQTTClient_willOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
int rc;
/* 创建 mqtt 客户端对象 */
if (MQTTCLIENT_SUCCESS !=
(rc = MQTTClient_create(&client, BROKER_ADDRESS, CLIENTID,
MQTTCLIENT_PERSISTENCE_NONE, NULL))) {
printf("Failed to create client, return code %d\n", rc);
rc = EXIT_FAILURE;
goto exit;
}
/* 设置回调 */
if (MQTTCLIENT_SUCCESS !=
(rc = MQTTClient_setCallbacks(client, NULL, connlost,
msgarrvd, NULL))) {
printf("Failed to set callbacks, return code %d\n", rc);
rc = EXIT_FAILURE;
goto destroy_exit;
}
/* 连接 MQTT 服务器 */
will_opts.topicName = WILL_TOPIC; //遗嘱主题
will_opts.message = "Unexpected disconnection"; //遗嘱消息
will_opts.retained = 1; //保留消息

will_opts.qos = 0; //QoS0
conn_opts.will = &will_opts;
conn_opts.keepAliveInterval = 30; //心跳包间隔时间
conn_opts.cleansession = 0; //cleanSession 标志
conn_opts.username = USERNAME; //用户名
conn_opts.password = PASSWORD; //密码
if (MQTTCLIENT_SUCCESS !=
(rc = MQTTClient_connect(client, &conn_opts))) {
printf("Failed to connect, return code %d\n", rc);
rc = EXIT_FAILURE;
goto destroy_exit;
}
printf("MQTT 服务器连接成功!\n");
/* 发布上线消息 */
pubmsg.payload = "Online"; //消息的内容
pubmsg.payloadlen = 6; //内容的长度
pubmsg.qos = 0; //QoS 等级
pubmsg.retained = 1; //保留消息
if (MQTTCLIENT_SUCCESS !=
(rc = MQTTClient_publishMessage(client, WILL_TOPIC, &pubmsg, NULL))) {
printf("Failed to publish message, return code %d\n", rc);
rc = EXIT_FAILURE;
goto disconnect_exit;
}
/* 订阅主题 dt_mqtt/led */
if (MQTTCLIENT_SUCCESS !=
(rc = MQTTClient_subscribe(client, LED_TOPIC, 0))) {
printf("Failed to subscribe, return code %d\n", rc);
rc = EXIT_FAILURE;
goto disconnect_exit;
}
/* 向服务端发布芯片温度信息 */
for ( ; ; ) {
MQTTClient_message tempmsg = MQTTClient_message_initializer;
char temp_str[10] = {0};
int fd;
/* 读取温度值 */
fd = open("/sys/class/thermal/thermal_zone0/temp", O_RDONLY);
read(fd, temp_str, sizeof(temp_str));//读取 temp 属性文件即可获取温度
close(fd);
/* 发布温度信息 */
tempmsg.payload = temp_str; //消息的内容
tempmsg.payloadlen = strlen(temp_str); //内容的长度
tempmsg.qos = 0; //QoS 等级
tempmsg.retained = 1; //保留消息
if (MQTTCLIENT_SUCCESS !=
(rc = MQTTClient_publishMessage(client, TEMP_TOPIC, &tempmsg, NULL))) {
printf("Failed to publish message, return code %d\n", rc);
rc = EXIT_FAILURE;
goto unsubscribe_exit;
}
sleep(30); //每隔 30 秒 更新一次数据
}
unsubscribe_exit:
if (MQTTCLIENT_SUCCESS !=
(rc = MQTTClient_unsubscribe(client, LED_TOPIC))) {
printf("Failed to unsubscribe, return code %d\n", rc);
rc = EXIT_FAILURE;
}
disconnect_exit:
if (MQTTCLIENT_SUCCESS !=
(rc = MQTTClient_disconnect(client, 10000))) {
printf("Failed to disconnect, return code %d\n", rc);
rc = EXIT_FAILURE;
}
destroy_exit:
MQTTClient_destroy(&client);
exit:
return rc;
}

(1)消息到达回调函数

static int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)

处理接收到的消息,根据不同的消息内容控制 LED 状态。

(2)连接丢失回调函数

static void connlost(void *context, char *cause)

当连接丢失时打印原因。

(3)变量声明和初始化

  • MQTTClient client:MQTT 客户端对象。
  • MQTTClient_connectOptions conn_opts:MQTT 连接选项结构体,用于设置连接参数。
  • MQTTClient_willOptions will_opts:MQTT 遗嘱选项结构体,用于设置遗嘱消息。
  • MQTTClient_message pubmsg:MQ

(4)#define BROKER_ADDRESS "tcp://iot.ranye-iot.net:1883" 

这个是你的服务器地址,需要改,格式“tcp://xxxxxxx:端口”

(5)注意,这里开发板和电脑/手机是不同的客户端,所以程序里面的是开发板的客户端,所以器客户端还有用户名,需要和mqtt.fx上的不一样,之后再emqx上面认证授权

进入build文件夹,cmake ../

然后make。

可见在bin中有生成文件

将mqttClient,利用scp传至开发板。

4. 测试(端口1883)

mqtt.fx 连接服务器

订阅主题,主题可以根据自己的名字改变,在emqx更新主题

注意,开发板必须要可以联网,可以用ping baidu.com来测试

执行./mqttClient发现报错

意思是没有连接开发板环境

首先找到自己的mqtt库文件路径,然后执行

export LD_LIBRARY_PATH=/home/root/tool/mqtt/install/lib:$LD_LIBRARY_PATH

在执行

./mqttClient

或者是直接执行

LD_LIBRARY_PATH=/home/root/tool/mqtt/install/lib:$LD_LIBRARY_PATH ./mqttClient

如果你的端口是1883,那么就没有问题啦,执行成功!就直接可以了

但是如果你还有服务器的端口是8883,则看还要开启SSL服务,需要mqtt库包含支持ssl的文件

libpaho-mqtt3a.so: 异步模式 MQTT 客户端库(不支持 SSL) 。

 libpaho-mqtt3as.so: 异步模式 MQTT 客户端库(支持 SSL) 。

 libpaho-mqtt3c.so: 同步模式 MQTT 客户端库(不支持 SSL) 。

 libpaho-mqtt3cs.so: 支持 SSL 的同步模式客户端库(支持 SSL) 。

我的mqtt库比较老,不支持ssl,没有,所以进行更新

5.更新mqtt

首先确认你是否安装了openssl

以下语句测试:

ls /home/book/linux/tool/mqtt/openssl-1.0.0s/include/openssl/pem.h
ls /home/book/linux/tool/mqtt/openssl-1.0.0s/include/openssl/ssl.h

如果没有,

安装openssl

sudo apt update
sudo apt install libssl-dev

我的openssl头文件目录:

/home/book/linux/tool/mqtt/openssl-1.0.0s/include/openssl

如果有,则下一步:

安装Paho MQTT C 库

sudo apt update
sudo apt install cmake build-essential libssl-dev

下载源码

git clone https://github.com/eclipse/paho.mqtt.c.git
cd paho.mqtt.c

cmake

cmake -DPAHO_WITH_SSL=ON -DOPENSSL_ROOT_DIR=/home/book/linux/tool/mqtt/openssl-1.0.0s -DOPENSSL_INCLUDE_DIR=/home/book/linux/tool/mqtt/openssl-1.0.0s/include ..

make

可以看到已经有了。为了不破坏原来路径,我将这个与原来的老mqtt库替换。

cd ~/linux/tool/mqtt/mqtt_new/paho.mqtt.c

创建install文件夹,再install文件夹创建lib和linclude文件夹

进入文件目录:/home/book/linux/tool/mqtt/mqtt_new/paho.mqtt.c

cp -r src/* install/include

进入/home/book/linux/tool/mqtt/mqtt_new/paho.mqtt.c/build

执行

cp -r src/* ../install/lib

回到/home/book/linux/tool/mqtt

cp -r mqtt_new/paho.mqtt.c paho.mqtt.c

移植成功!然后利用scp更新开发板的环境

 scp -r book@192.168.137.12:/home/book/linux/tool/mqtt/paho.mqtt.c/install /home/root/tool/mqtt

移植成功

6.测试(端口8883)

端口8883,我们需要改一些链接 

打开CMakeLists.txt文件,将最后一行的链接libpaho-mqtt3c.so改为libpaho-mqtt3cs.so支持ssl

然后打开cmake文件夹,打开arm-linux-setup.cmake

arm-linux-setup.cmake

##################################
# 配置 ARM 交叉编译
##################################
set(CMAKE_SYSTEM_NAME Linux) # 设置目标系统名字
set(CMAKE_SYSTEM_PROCESSOR arm) # 设置目标处理器架构

# 指定编译器的 sysroot 路径
set(TOOLCHAIN_DIR /home/book/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf)
set(CMAKE_SYSROOT ${TOOLCHAIN_DIR}/arm-linux-gnueabihf/libc)

# 指定交叉编译器
set(CMAKE_C_COMPILER ${TOOLCHAIN_DIR}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_DIR}/bin/arm-linux-gnueabihf-g++)

# 为编译器添加编译选项
set(CMAKE_C_FLAGS "-march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7")
set(CMAKE_CXX_FLAGS "-march=armv7ve -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a7")

# 设置查找路径模式
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

# 添加 OpenSSL 的路径
set(OPENSSL_ROOT_DIR /home/book/linux/tool/mqtt/openssl-1.0.0s)
set(OPENSSL_INCLUDE_DIR ${OPENSSL_ROOT_DIR}/include/openssl)
set(OPENSSL_CRYPTO_LIBRARY ${OPENSSL_ROOT_DIR}/libcrypto.so)
set(OPENSSL_SSL_LIBRARY ${OPENSSL_ROOT_DIR}/libssl.so)

加入openssl链接,因为8883端口需要ssl支持,所以需要加入链接。

然后重点来了!!!!!!!!!!!!

对比1883端口,8883端口需要ssl支持,所以,开发板需要CA证书文件!!!!!!!!!!!

将下载的ca证书传到开发板,记住目录,记得加到程序中,然后进行了修改:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h> // 包含open和close函数的定义
#include <unistd.h> // 包含unistd.h以使用read函数
#include "MQTTClient.h" // 包含MQTT客户端库的定义

// 定义MQTT服务器的地址和连接信息
#define BROKER_ADDRESS "ssl://d9d31e0e.ala.cn-hangzhou.emqxsl.cn:8883"
#define CLIENTID "d0800680277b44359129dd68ef11675b"
#define USERNAME "ymj3"
#define PASSWORD "123456"
#define WILL_TOPIC "ymj/will1"
#define LED_TOPIC "ymj/led1"
#define TEMP_TOPIC "ymj/temperature1"
#define CA_PATH "/home/root/mqtt_test/emqxsl-ca.crt"

// 回调函数:连接丢失时调用
void connlost(void *context, char *cause) {
    printf("\nConnection lost\n");
    printf("cause: %s\n", cause);
}

// 回调函数:接收到消息时调用
int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) {
    printf("Message arrived\n");
    printf("topic: %s\n", topicName);
    printf("message: %.*s\n", message->payloadlen, (char*)message->payload);

    // 检查是否是LED_TOPIC
    if (strcmp(topicName, LED_TOPIC) == 0) {
        if (strncmp(message->payload, "ON", message->payloadlen) == 0) {
            // 打开LED
            printf("Turning LED ON\n");
            system("echo 1 > /sys/class/leds/sys-led/brightness");
        } else if (strncmp(message->payload, "OFF", message->payloadlen) == 0) {
            // 关闭LED
            printf("Turning LED OFF\n");
            system("echo 0 > /sys/class/leds/sys-led/brightness");
        }
    }

    // 释放消息内存
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;
}

int main(int argc, char* argv[]) {
    MQTTClient client; // 定义MQTT客户端对象
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; // 初始化MQTT连接选项
    MQTTClient_willOptions will_opts = MQTTClient_willOptions_initializer; // 初始化遗嘱选项
    MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer; // 初始化SSL选项
    int rc; // 用于存储返回代码

    // 创建MQTT客户端
    MQTTClient_create(&client, BROKER_ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
    // 设置回调函数
    MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, NULL);

    // 设置遗嘱选项
    will_opts.topicName = WILL_TOPIC;
    will_opts.message = "Unexpected disconnection";
    will_opts.retained = 1;
    will_opts.qos = 0;
    conn_opts.will = &will_opts;
    conn_opts.keepAliveInterval = 30;
    conn_opts.cleansession = 1;
    conn_opts.username = USERNAME;
    conn_opts.password = PASSWORD;

    // 配置SSL选项
    ssl_opts.trustStore = CA_PATH;
    conn_opts.ssl = &ssl_opts;

    // 增加调试信息
    printf("Attempting to connect to %s with client ID %s\n", BROKER_ADDRESS, CLIENTID);
    printf("Using username: %s and password: %s\n", USERNAME, PASSWORD);
    printf("Using CA file: %s\n", CA_PATH);

    // 连接到MQTT服务器
    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) {
        printf("Failed to connect, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }

    printf("Connected to broker\n");

    // 订阅LED_TOPIC主题
    if ((rc = MQTTClient_subscribe(client, LED_TOPIC, 0)) != MQTTCLIENT_SUCCESS) {
        printf("Failed to subscribe, return code %d\n", rc);
        goto disconnect_exit;
    }

    // 发布上线消息
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    pubmsg.payload = "Online";
    pubmsg.payloadlen = strlen(pubmsg.payload);
    pubmsg.qos = 0;
    pubmsg.retained = 1;
    MQTTClient_deliveryToken token;

    if ((rc = MQTTClient_publishMessage(client, WILL_TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) {
        printf("Failed to publish message, return code %d\n", rc);
        goto unsubscribe_exit;
    }
    printf("Waiting for publication of %s\n", (char*) pubmsg.payload);
    rc = MQTTClient_waitForCompletion(client, token, 10000L);
    printf("Message with delivery token %d delivered\n", token);

    // 向服务端发布芯片温度信息
    while (1) {
        MQTTClient_message tempmsg = MQTTClient_message_initializer;
        char temp_str[10] = {0};
        int fd;

        // 读取温度值
        fd = open("/sys/class/thermal/thermal_zone0/temp", O_RDONLY);
        if (fd < 0) {
            perror("Failed to open temp file");
            continue;
        }
        read(fd, temp_str, sizeof(temp_str));
        close(fd);

        // 发布温度信息
        tempmsg.payload = temp_str;
        tempmsg.payloadlen = strlen(temp_str);
        tempmsg.qos = 0;
        tempmsg.retained = 1;
        if ((rc = MQTTClient_publishMessage(client, TEMP_TOPIC, &tempmsg, &token)) != MQTTCLIENT_SUCCESS) {
            printf("Failed to publish message, return code %d\n", rc);
            goto unsubscribe_exit;
        }
        printf("Published temperature: %s\n", temp_str);
        sleep(30); // 每隔30秒更新一次数据
    }

unsubscribe_exit:
    if ((rc = MQTTClient_unsubscribe(client, LED_TOPIC)) != MQTTCLIENT_SUCCESS) {
        printf("Failed to unsubscribe, return code %d\n", rc);
    }
disconnect_exit:
    if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) {
        printf("Failed to disconnect, return code %d\n", rc);
    }
    MQTTClient_destroy(&client);
    return rc;
}

  • 包含必要的头文件

    • stdio.hstdlib.hstring.h:标准输入输出和字符串处理函数。
    • fcntl.h:文件控制选项,包含 O_RDONLY 的定义。
    • unistd.h:POSIX 操作系统 API,包含 read 函数的定义。
    • MQTTClient.h:MQTT 客户端库的定义。
  • 定义宏

    • BROKER_ADDRESSCLIENTIDUSERNAMEPASSWORD:MQTT 服务器的连接信息。
    • WILL_TOPICLED_TOPICTEMP_TOPIC:MQTT 主题。
    • CA_PATH:CA 证书的路径。
  • 回调函数 connlost:当连接丢失时打印原因。

  • 回调函数 msgarrvd:当接收到消息时处理消息内容。如果消息主题是 LED_TOPIC,则根据消息内容控制 LED 的开关状态。

执行

/usr/local/bin/cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/arm-linux-setup.cmake -DCMAKE_BUILD_TYPE=Release ..

make

将文件传到开发板

实现功能:

  • 连接到 MQTT 服务器:通过 SSL/TLS 安全连接到指定的 MQTT 服务器。
  • 设置回调函数:设置回调函数来处理连接丢失和消息到达的情况。
  • 订阅主题:订阅 ymj/led1 主题以接收控制 LED 灯状态的消息,NO为开,OFF为关。
  • 发布上线消息:在连接到 MQTT 服务器后,发布一条上线消息到 ymj/will1 主题。
  • 定期发布温度信息:每隔30秒读取一次温度信息并发布到 ymj/temperature1 主题。
  • 控制 LED 灯:根据收到的消息内容,通过 ymj/led1 主题控制 LED 灯的状态(开/关)

注意开发板的用户名和id要和mqtt.fx不一样,然后都要到emqx进行认证和授权

演示

NO:

OFF

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 11:06:04       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 11:06:04       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 11:06:04       58 阅读
  4. Python语言-面向对象

    2024-07-11 11:06:04       69 阅读

热门阅读

  1. thinkphp:数据库复合查询-OR的使用

    2024-07-11 11:06:04       19 阅读
  2. 32. 小批量梯度下降法(Mini-batch Gradient Descent)

    2024-07-11 11:06:04       23 阅读
  3. MySQL相关函数

    2024-07-11 11:06:04       19 阅读
  4. 编程语言ju:探索、挑战与未来趋势

    2024-07-11 11:06:04       23 阅读
  5. 相机光学(三十一)——暗房设置的要求

    2024-07-11 11:06:04       26 阅读
  6. 前端开发工具

    2024-07-11 11:06:04       20 阅读
  7. 手机下载APP (uniapp/vue)

    2024-07-11 11:06:04       24 阅读
  8. 腾讯地图简单功能的封装

    2024-07-11 11:06:04       21 阅读
  9. 第四章 Redis(2023版本IDEA)

    2024-07-11 11:06:04       22 阅读
  10. Spring MVC -01

    2024-07-11 11:06:04       26 阅读
  11. 设计模式03-组合模式

    2024-07-11 11:06:04       22 阅读
  12. .net开发:NPOI生成excel文件到磁盘

    2024-07-11 11:06:04       25 阅读