1 项目分享|基于ELF 1开发板的MQTT远程温湿度监测系统-德赢Vwin官网 网
0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

项目分享|基于ELF 1开发板的MQTT远程温湿度监测系统

ElfBoard 2024-04-26 09:54 次阅读

今天非常荣幸向各位小伙伴详细展示一个由共创社成员完成的MQTT远程温湿度监控系统项目。该项目借助ELF 1开发板作为核心技术支撑,成功实现了对各类环境空间中温湿度数据的实时、远程、稳定监测。该系统不仅集成了先进的数据采集模块,用于精确感知现场环境变化,同时利用MQTT协议的轻量级特性,确保了数据在复杂网络环境下的可靠传输。在此接下来,就为各位小伙伴详尽展示这一项目的相关细节。

1、Linux开发板开发环境搭建

(1)开发板动态分配ip地址

(开发板与家用路由器连接,路由器支持DHCP自动IP地址分配)

root@ELF1:~# udhcpc -i eth0

wKgZomYrABiAL5FMAAD4aceXtZc667.png

(2)将nfs服务器挂载到开发板的/mnt目录

(其中“192.168.1.10”是Ubuntu的ens36的ip)

root@ELF1:~# mount -t nfs -o nolock,vers=3 192.168.1.10:/home/book/nfs_rootfs /mnt

wKgZomYrAEeARo1OAACjstu0MMc843.png

可以看到开发板的/mnt目录已经有了文件。

2、Ubuntu编译环境搭建:

(1)将paho mqtt的官方库克隆到Ubuntu的“~/nfs_rootfs”路径

book@100ask:~/nfs_rootfs$ git clone https://github.com/eclipse/paho.mqtt.c.git

(2)修改“~/nfs_rootfs/paho_mqtt/paho.mqtt.c”路径下的Makefile文件

wKgaomYrAH2ARc4LAAI3XHXO5U4881.png

修改prefix所代表的工具链路径:

wKgaomYrAImAKsMsAABDGqaG_Yo240.png

修改编译器:

wKgZomYrAMuAXkLTAABqJSDRCjI959.png

(3)编译后得到链接库

book@100ask:~/nfs_rootfs/paho_mqtt/paho.mqtt.c$ make

arm-gcc编译生成的.so库文件,保存在paho.mqtt.c/build/output里面。

将.so库文件安装到本地PC:

book@100ask:~/nfs_rootfs/paho_mqtt/paho.mqtt.c$ sudo make install

(4)将.so库文件安装到开发板的“/lib”路径,开发板才能运行paho mqtt编译后的可执行文件

root@ELF1:~# install /mnt/paho_mqtt/paho.mqtt.c/build/output/libpaho-mqtt3* /lib

以上开发环境搭建完成!

3、工程文件的建立

(1)将“~/nfs_rootfs/paho_mqtt/paho.mqtt.c”

路径中的src文件夹拷贝到“~/nfs_rootfs/mqtt_iot”路径下

book@100ask:~$ cp -r ~/nfs_rootfs/paho_mqtt/paho.mqtt.c ~/nfs_rootfs/mqtt_iot

(2)在“~/nfs_rootfs/mqtt_iot”路径下添加文件:

wKgZomYrAJqAZRDVAADUJjIvdQg640.png

4、阿里云服务器设置:

(1)服务器的注册及产品、设备设置可以参照ElfBoard官方文档:《01-1 ELF1、ELF1S开发板_软件教程_V1》第5章-5.4小节。

(2)工程文件中所需要的服务器参数查找

查看服务器地址

wKgaomYrAUKAE9kLAACdn25W2ow817.png

查看DeviceName、DeviceSecret

wKgZomYrAUKAD6CFAAD8FOKLADA186.png

查看MQTT连接参数

wKgZomYrAUOAKv9VAAENTNejk3o069.png

5.工程文件的编译执行

(1)编译工程文件,得到可在Linux开发板上执行的Main二进制文件

book@100ask:~/nfs_rootfs/mqtt_iot$ arm-buildroot-linux-gnueabihf-gcc main.c mqtt_iot.c -o main -lpaho-mqtt3c -lpthread

MQTT的异步通信收发,依赖的库是libpaho-mqtt3a,MQTT的同步通信收发,依赖的库就是libpaho-mqtt3c。此外工程编译的时候需要链接线程的库pthread,所以编译的时候要加上-lpthread。

(2)开发板运行程序

root@ELF1:/mnt/mqtt_iot# ./main

(3)实验结果

Linux开发板将采集到的温度、湿度数据每5s上传一次阿里服务器,串口窗口显示数据发送成功字符。此外通过阿里服务器日志服务可以看到湿度、温度数据。

wKgZomYrAaqASiKBAAICBtwiVjM910.pngwKgaomYrAaqAe9CMAAFOAY5XFMU291.png

通过阿里服务器调试窗口给开发板发送LED1、LED2控制指令。

wKgZomYrAaqAFxCkAAEUD_6woBA592.pngwKgZomYrAcaALfm-AAGP2LpxajM518.png

6、下面将贴出工程文件的代码,并介绍其思路

(1)main.c文件

//main.c //定义线程句柄 pthread_t discon_t; pthread_t thread_AT20Read_t; pthread_t thread_ledctrl_t; static int isConnected = 0;//表明客户端和服务器是断开还是连接状态(1-连接状态,-1断开状态) static void *thread_AT20Read(void *paramater) { int fd = -1; unsigned int databuf[2]; int c1,t1; float hum,temp; int ret = 0; msgbuf pubMsg = {2, 0}; while(fd < 0){ fd = open(AHT20_DEV, O_RDWR); if(fd < 0){ printf("can't open file %s\r\n", AHT20_DEV); sleep(1); }else{ printf("open file %s successfully\r\n", AHT20_DEV); } } while(1){ ret = read(fd, databuf, sizeof(databuf)); if(ret == 0){ c1 = databuf[0]*1000/1024/1024; t1 = databuf[1] *200*10/1024/1024-500; hum = (float)c1/10.0; temp = (float)t1/10.0; //printf("hum = %0.2f temp = %0.2f \r\n",hum,temp); pubMsg.mtext[0] = (unsigned int)(hum*100); pubMsg.mtext[1] = (unsigned int)(temp*100); int ret1 = msgsnd(pubmsg_d, &pubMsg.mtype, sizeof(pubMsg.mtext), IPC_NOWAIT); // 非阻塞发送 if(ret1 != 0) { printf("Failed to send message.\r\n"); } } sleep(5); } } static void *thread_ledctrl(void *paramater) { int on=1; int led; int fd; msgbuf subMsg = {1, 0}; fd = open(LED_BRIGHTNESS, O_WRONLY); if(fd < 0) { perror("open device leds"); exit(1); } system(LED1_OFF); system(LED2_OFF); while(1) { int res = msgrcv(submsg_d, &subMsg, sizeof(subMsg.mtext), 0, 0);//阻塞 if(res < 0) continue; else{ if((subMsg.mtext[0] & 0x01)== 1){ system(LED1_ON); }else{ system(LED1_OFF); } if((subMsg.mtext[0] & 0x02)== 0x02){ system(LED2_ON); }else{ system(LED2_OFF); } } } } //断开和mqtt服务器连接的线程入口函数 static void *mqtt_disconnect_t(void* argv) { int retval; while(1) { char ch; ch = getchar(); if(ch=='Q' || ch=='q') { printf("Try to exit mqtt task\n"); if(mqtt_disconnect() == EXIT_SUCCESS) break; } } isConnected = -1; pthread_exit(&retval); // 退出线程 return NULL; } int main(void) { //初始化mqtt成功建立客户端和服务器的连接后,将主动断开服务器的任务放到一个线程里面去 //成功建立客户端和服务器的连接且订阅主题后才创建断开连接的线程 if(mqtt_iot() == 0) { isConnected = 1; pthread_create(&discon_t, 0, mqtt_disconnect_t, NULL); } //AT20 read thread int ret = pthread_create(&thread_AT20Read_t, NULL, thread_AT20Read, NULL); if(ret != 0) { printf("Failed to create AT20Read thread.\n"); return -1; } //led control thread ret = pthread_create(&thread_ledctrl_t, NULL, thread_ledctrl, NULL); if(ret != 0) { printf("Failed to create ledctrl thread.\n"); return -1; } while(1) { //printf("isConnected state:%d\n",isConnected); sleep(5); } return 0; }

(2)mqtt_iot.c文件

//mqtt_iot.c volatile MQTTClient_deliveryToken deliveredtoken; pthread_t threads[2]; sem_t discon_sem;//信号量 int pubmsg_d = -1; int submsg_d = -1; msgbuf subMsg = {1, 0}; msgbuf pubMsg = {2, 0}; pthread_t thread_mqtt_publish_t; MQTTClient client; //定义一个MQTT客户端client MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; //传递给MQTTClient_setCallbacks的回调函数,消息发送成功后,调用此回调函数 void delivered(void *context, MQTTClient_deliveryToken dt) { printf("Message with token value %d delivery confirmed\n", dt); deliveredtoken = dt; } //传递给MQTT-Client_setCallbacks的回调函数 消息到达后,调用此回调函数 int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) { printf("---------------------------------------------------------------\n"); printf("Message arrived\n"); printf(" topic: %s\n", topicName); printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); printf("---------------------------------------------------------------\n"); subMsg.mtext[0] = 0; unsigned short len = message->payloadlen; char *buf = (char*)message->payload; for(unsigned short i=0; i='0') subMsg.mtext[0] = subMsg.mtext[0]*10 + buf[i] - '0'; } int ret = msgsnd(submsg_d, &subMsg.mtype, sizeof(subMsg.mtext), IPC_NOWAIT); // 非阻塞发送 if(ret != 0) { printf("Failed to send message.\r\n"); } MQTTClient_freeMessage(&message); // 释放消息 MQTTClient_free(topicName); // 释放主题名 return 1; } //传递给MQTTClient_setCallbacks的回调函数 连接异常断开后调用此回调函数 void connlost(void *context, char *cause) { printf("\nConnection lost\n"); printf(" cause: %s\n", cause); } //实现MQTT的发布 void *mqtt_publish(void *argv) { MQTTClient_message pubmsg = MQTTClient_message_initializer; MQTTClient_deliveryToken token; char data[9]; int rc; pubmsg.qos = QOS; pubmsg.retained = 0; while(1) { //接收消息(消息队列的ID,存放消息的指针,指定接收消息的大小,0-读取消息队列中第一个数据,阻塞) int res = msgrcv(pubmsg_d, &pubMsg, sizeof(pubMsg.mtext), 0, 0); if(res < 0) continue; { //printf("Publish_hum: %d\n", pubMsg.mtext[0]); //printf("Publish_temp: %d\n", pubMsg.mtext[1]); sprintf(data, "%d,%d", pubMsg.mtext[0],pubMsg.mtext[1]); pubmsg.payload = data; pubmsg.payloadlen = sizeof(data); if((rc = MQTTClient_publishMessage(client, PUB_TOPIC, &pubmsg, &token)) != MQTTCLIENT_SUCCESS) { printf("Failed to publish message, return code %d\n", rc); break; } rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); printf("Message with delivery token %d delivered\n", token); } } if((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) //断开和服务器的连接 { printf("Failed to disconnect, return code %d\n", rc); } pthread_exit(&threads[PubThread]); return NULL; } //封装主动断开连接服务器的函数 int mqtt_disconnect(void) { int rc = EXIT_SUCCESS; //两个参数:MQTT客户端和断开连接超时时间 if ((rc = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS) //断开和服务器的连接 { printf("Failed to disconnect, return code %d\n", rc); rc = EXIT_FAILURE; } else { printf("MQTT disconnect success\n"); MQTTClient_destroy(&client); } return rc; } // mqtt建立客户端、连接服务器、订阅主题的封装入口函数 int mqtt_iot(void) { int rc = EXIT_SUCCESS; //创建客户端 if ((rc = MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL)) != MQTTCLIENT_SUCCESS) { printf("Failed to create client, return code %d\n", rc); goto exit; } //设置回调函数(连接丢失处理回调函数,处理订阅消息的回调函数,成功发布消息后的回调函数) if((rc = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered)) != MQTTCLIENT_SUCCESS) { printf("Failed to set callbacks, return code %d\n", rc); goto destroy_exit; } conn_opts.username = USERNAME; conn_opts.password = PASSWORD; conn_opts.keepAliveInterval = 60;//保活周期,客户端向服务器发送心跳包的周期,单位秒 conn_opts.cleansession = 1; //连接服务器 if((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d\n", rc); goto destroy_exit; } //订阅主题(传入客户端句柄、订阅的主题以及消息质量) if ((rc = MQTTClient_subscribe(client, SUB_TOPIC, QOS)) != MQTTCLIENT_SUCCESS) { printf("Failed to subscribe, return code %d\n", rc); goto destroy_exit; } //初始化信号量 if(sem_init(&discon_sem, 1, 0) != 0) { printf("Failed to init semaphore\n"); return -1; } //创建队列 pubmsg_d = msgget(0x1234, IPC_CREAT); submsg_d = msgget(0x5678, IPC_CREAT); if(pubmsg_d == -1 || submsg_d==-1) //返回错误码-1 { printf("Failed to create a mqtt message, pubid:%d, subid:%d\n", pubmsg_d, submsg_d); return -1; } else { printf("Publish message id: %d\n", pubmsg_d); printf("Subscribe message id: %d\n", submsg_d); } int ret = pthread_create(&thread_mqtt_publish_t, NULL, mqtt_publish, NULL); if(ret != 0) { printf("Failed to create mqtt_publish thread.\n"); return -1; } printf("MQTT connect success, press 'Q' or 'q' to disconnect mqtt server\n"); return 0; destroy_exit: MQTTClient_destroy(&client); //释放客户端的资源, 参数-同步客户端的句柄 return -1; exit: return -1; }

至此,就完成了关于ELF 1开发板研发的MQTT远程温湿度监测系统介绍。希望这套实践案例能够成为各位小伙伴的宝贵参考,启迪创新思维,推进各位嵌入式爱好者在学习的道路上不断前进。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5082

    文章

    19104

    浏览量

    304790
  • 监测系统
    +关注

    关注

    8

    文章

    2719

    浏览量

    81305
  • 开发板
    +关注

    关注

    25

    文章

    5032

    浏览量

    97371
收藏 人收藏

    评论

    相关推荐

    【小e开发板申请】基于WIFI的家庭温湿度情况播报系统

    的智能家居系统,包括家庭温湿度,报警,洗衣机,冰箱,空调等等连接在一起的一个智能居住环境。项目描述:初步方案:开发板作为一个终端,进行温湿度
    发表于 12-22 11:57

    基于单片机的远程温湿度监测系统。(有报酬)

    基于单片机的远程温湿度监测系统。单片机监测温湿度,在LCD上面显示出来。用zigbee再把温湿度
    发表于 05-14 16:26

    【钛极小龟试用申请】钛极小龟云环境监测温湿度远程调控实验

    项目名称:钛极小龟云环境监测温湿度远程调控实验试用计划:本人从事多年软件开发工作, 擅长Java,Android程序
    发表于 11-13 17:09

    鸿蒙软、硬件综合案例——农业大棚温湿度监测控制系统

    农业大棚温湿度监测控制系统,包括三部分:鸿蒙手表应用端:实时显示土壤湿度、空气温湿度,可控制风扇与水泵华为云ECS:提供MQTT服务Hi38
    发表于 12-11 10:01

    库房无线温湿度监控方案 无线温湿度监控系统 仓储物流无线温湿度

    数据的实时显示、曲线显示、数据存储等功能。 四、无线温湿度监控拓扑图 五 系统功能 、特点1系统软件功能:通过监测软件实现对
    发表于 03-01 10:15

    NUC980开发板DIY项目大挑战合集

    开发板,采用Rt-Thread系统搭建平台,测定环境的温湿度。工程框图:以下为本项目的总体框图。原作者:Cainhu、weizheng110
    发表于 06-08 14:32

    【天启教育M1开发板试用体验】MQTT温湿度

    【目的】建立一个温湿度计,并通过MQTT上传到服务器1、连接wifi:2、设置mqtt服务器连接信息:3、连接成功后,获取温湿度,并上传给服
    发表于 09-15 09:44

    ELF 1开发板试用】+传感器检测

    ELF 1开发板通过几种传感器的测试,如温湿度、六轴传感器等,而在配备功能扩展板的情况下,还能进行光照强度的检测。 温湿度检测
    发表于 11-29 11:59

    ELF 1开发板试用】板载资源测试4:体验温湿度传感器

    飞凌嵌入式ELF1开发板(以下简称为“开发板”)将温湿度传感器器AHT20集成在了底板上,此次依旧做最基础的测试,以下是测试过程记录。一、实验名称E
    发表于 12-18 11:09

    基于 LabVIEW 的温湿度监测系统设计与实现

    基于LabVIEW的温湿度监测系统123456
    发表于 11-24 16:59 60次下载

    基于手机短信的设施农业温湿度远程监测系统的设计

    基于手机短信的设施农业温湿度远程监测系统的设计
    发表于 01-04 15:02 0次下载

    GPRS和3G通信的粮仓温湿度远程监测系统

    为了解决现有粮仓温湿度监测系统存在的自动化程度低、性价比较低、传输距离受限等问题,本文设计了一种基于GPRS 和 3G 通信的粮仓温湿度远程
    发表于 04-24 10:56 7次下载
    GPRS和3G通信的粮仓<b class='flag-5'>温湿度</b><b class='flag-5'>远程</b><b class='flag-5'>监测</b><b class='flag-5'>系统</b>

    【天启教育M1开发板试用体验】MQTT温湿度

      本文来源德赢Vwin官网 社区,作者:刘建华, 帖子地址: https://bbs.elecfans.com/jishu_2305668_1_1.html 【目的】建立一个温湿度计,并通过MQTT上传
    的头像 发表于 10-17 11:31 727次阅读
    【天启教育M<b class='flag-5'>1</b><b class='flag-5'>开发板</b>试用体验】<b class='flag-5'>MQTT</b><b class='flag-5'>温湿度</b>计

    温湿度远程监控系统概述

    中易云温湿度监控系统专为温湿度监控设计,使用各种物联网温湿度监控硬件及云平台,在检测环境温湿度数据的同时,还可以
    的头像 发表于 12-16 15:36 3266次阅读

    项目分享|基于ELF 1开发板远程监测及人脸识别项目

    今天非常荣幸地向各位小伙伴分享一个由共创社成员完成的远程监测及人脸识别项目,该项目依托ELF1开发板
    的头像 发表于 03-13 16:41 516次阅读
    <b class='flag-5'>项目</b>分享|基于<b class='flag-5'>ELF</b> <b class='flag-5'>1</b><b class='flag-5'>开发板</b>的<b class='flag-5'>远程</b><b class='flag-5'>监测</b>及人脸识别<b class='flag-5'>项目</b>