本帖最后由 damiaa 于 2024-3-25 20:46 编辑
【 正点原子瑞芯微RV1126测评】7 mqtt客户端编程
一、下载mqtt源码,路径如下:
二、下载到电脑后通过共享文件夹放到ubuntu里面。
编译mqtt源代码包
gcc交叉编译器安装目录如下:
把下载的mqtt源码包拷贝到下面的文件夹并解压,奇怪加压处理的是1.3.13不管他能用就行。
在cmake目录里面新建一个文件arm-linux-setup.cmake并且写入下面内容
在paho.mqtt.c-1.3.13目录里面建一个build目录。操作如下
进入到 build 目录下,执行 cmake 进行构建:
cmake -DCMAKE_BUILD_TYPE=Release - DCMAKE_INSTALL_PREFIX=/home/ alientek/tools/paho.mqtt.c-1.3.13/install - DCMAKE_TOOLCHAIN_FILE=../cmake/arm-linux-setup.cmake -DPAHO_WITH_SSL=TRUE - DPAHO_BUILD_SAMPLES=TRUE ..
Build目录执行make
注意:MQTT 客户端库依赖于 openssl 库,通常在移植 MQTT 客户端库的时候,需要先移植 openssl、交叉编译 openssl 得到库文件以及头文件,因为开发板出厂系统中已经移植好了 openssl 库,并且使用ubuntu里面的交叉编译器在编译工程源码的时候会链接 openssl 库(sysroot 路径指定的)。
执行sudo make install
在install目录里面有如下库文件,从上面也可以看出来头文件在哪些目录,这些就是后面我们板子上运行mqtt和编译应用程序要用到的。
二、编译mqtt客户端程序
应用程序的Cmake目录里面建立一个文件指定好编译路径
编写cmakefile.lst文件
从上面编译的时候知道库文件和头文件目录如下,在cmakefile.lst中设置正确
mqtt测试程序
#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 "192.168.0.1031883"
#define CLIENTID "clientid123456" //客户端id
#define USERNAME "mqtttest" //用户名
#define PASSWORD "123456" //密码
#define WILL_TOPIC "dt_mqtt/will" //遗嘱主题
#define LED_TOPIC "dt_mqtt/led" //LED主题
#define TEMP_TOPIC "dt_mqtt/temperature" //温度主题
#define ADC_TOPIC "dt_mqtt/adc" //ADC主题
/* ################################################# */
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/user-led/trigger");
if (!strcmp("1", message->payload)) { //如果是"1"则LED常量
system("echo none > /sys/class/leds/user-led/trigger");
system("echo 1 > /sys/class/leds/user-led/brightness");
}
else if (!strcmp("0", message->payload)) {//如果是"0"则LED熄灭
system("echo none > /sys/class/leds/user-led/trigger");
system("echo 0 > /sys/class/leds/user-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};
char adc_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);
/* 读取ADC值 */
fd = open("/sys/bus/iio/devices/iio\:device0/in_voltage3_raw", O_RDONLY);
read(fd, adc_str, sizeof(adc_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;
}
/* 发布ADC信息 */
tempmsg.payload = adcc_str; //消息的内容
tempmsg.payloadlen = strlen(adc_str); //内容的长度
tempmsg.qos = 0; //QoS等级
tempmsg.retained = 1; //保留消息
if (MQTTCLIENT_SUCCESS !=
(rc = MQTTClient_publishMessage(client, ADC_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;
}
建立build空目录
Build目录里面执行
cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/arm-linux-setup.cmake - DCMAKE_BUILD_TYPE=Release ..
执行make
这就是我们编译的客户端程序
四、编译的mqtt库拷贝到板子
将编译得到的库文件拷贝到开发板 Linux 系统/usr/lib 目录下,将编译得到的客户端程序mattclient拷贝到板子统/home/testmqtt下,如下所示:
修改执行属性,为实验准备。
五、实验准备
电脑安装mqtt的服务器。
准备好网线连接主板,并查看电脑的ip 看他们是不是同一网段,拼一下看通不通,安装好mqtt工具mqtt.fx-1.71在电脑里。
六、实验测试
主板运行mqttclient程序,电脑里mqtt.fx-1.71设置好ip和用户名,密码。面查看并看互动结果如下:
说明通了。注意:电脑上的mqtt.fx-1.71设置的clientid和板子不要一样。也就是一个网络里面clientid不能 重复!!!否则会有一个下线。
到此,通信就算是成功了。
好实验先到这里,谢谢大家。