tobot 发表于 2021-12-27 13:39

使用mqtt记录环境温湿度

本帖最后由 tobot 于 2022-1-13 00:45 编辑

#申请原创#
@21小跑堂

在学校的气象社团中,有一项很重要的任务,就是需要每天记录特定时刻里的气象数据,包括了风向、风速、气温、湿度、降雨量等等。其中测量空气的温度和湿度的仪表一般是放在操场外草坪上百叶箱中,包括了温度表、湿度表、最高和最低温度表等,人工抄表不仅费事,而且在开关百叶箱门时,可能造成数据的破坏。现今已经到了物联网时代,这项工作早就可以用远程抄表的方式替代了。本项目实现了温湿度的远程抄表功能。首先是选取器件:1)传感器使用DHT11,这个器件已经在https://bbs.21ic.com/icview-3186340-1-1.html中尝试自己写代码逐位读取,本文中直接调用Arduino库。2)MCU使用ESP8266,ESP8266价格低廉,提供一个非常低速的Wifi接口,但是在本文的要求中是足够用的,本文中的开发环境是Arduino。3)电池使用普通的3.7V锂电池其次是选择合适的通信协议:在这个项目中,实时性要求并不高,数据量也很少,而且在校园中,属于开放Wifi覆盖范围内(但信号质量并不好),可以使用MQTT协议传输数据。MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一个基于客户端-服务器的消息发布/订阅(publish/subscribe)的轻量级通讯协议,一般基于TCP(基于UDP的叫做MQTT-SN),可靠性是有保证的;使用文本形式,固定长度的头部只有2个字节,可以做到低开销、低带宽占用;同时无需应用程序耦合,提供一对多的消息发布,简单、开放、易于实现、可控性好,已经成为IoT中最为广泛的通信协议之一了。考虑到成本和易于实现,选择了broker.emqx.io作为MQTT的服务器,该服务器支持非认证的用户发布和订阅消息。具体实现如下:1)首先是下载和安装arduino环境:在https://www.arduino.cc/en/Main/Software中下载安装(过程略),由于Arduino缺省没有ESP8266支持,因此还需加入ESP8266的开发板。打开应用程序,在菜单“文件-首选项”对话框的附加开发板管理网址中加入:http://arduino.esp8266.com/stable/package_esp8266com_index.json多个网址可以用逗号隔开。在菜单“工具-开发板管理器”中打开的对话框会自动出现对应的板卡,因为板卡数量很多,可以增加关键字过滤找到“esp8266”。选择合适版本安装。安装完成后,可以直接在菜单中选择支持ESP8266的板卡,例如“Generic ESP8266 Module”。在菜单“项目-加载库-管理库”中选择安装MQTT库。 可供选择的MQTT支持库很多,这里选择了Adafruit MQTT Library。至此,开发环境就搭建好了。2)硬件连接:需要把DHT11、ESP8266和电源连接起来,我这里因为都是开发板,因此选择的是杜邦线连接,个人建议使用焊接会更好一些。ESP8266开发板上可供选择管脚比较多,这里使用的是16脚。DHT11直接从ESP8266的开发板上取电。3)传感器侧的开发:MQTT的开发从例程改相对简单,选择菜单“文件-示例-Adafruit MQTT Library-mqtt_esp8266”打开例程,并另存一个目录。将附件Dht11.zip解压出的dht11.c和dht11.h放在上述同一目录下。文件中增加头文件的引用:#include "dht11.h"根据硬件的实际连接修改管脚定义:#define DHT11PIN 16根据开放的wifi网络情况,修改WLAN_SSID和WLAN_PASS根据所选的MQTT server修改相关定义,因为使用匿名连接,所以用户名和关键字都不用填写:#define AIO_SERVER      "broker.emqx.io"#define AIO_SERVERPORT1883                   // use 8883 for SSL#define AIO_USERNAME    ""#define AIO_KEY         ""删除掉例程中的订阅部分,修改发布主题为/test:Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/test");再增加dht11的读取:因为dht11读取容易失败,所以可以加上校验:while (DHT11.read(DHT11PIN)!=DHTLIB_OK){    Serial.println("Reading error!");    delay(2000);    Serial.println("Try again...");}发布读取信息:Serial.println("Get values:");String s1="Humidity (%):";char t1;dtostrf(DHT11.humidity,2,2,t1);s1=s1+t1;String s2="Temperature (oC): ";char t2;dtostrf(DHT11.temperature,2,2,t2);s2=s2+t2;Serial.println(s1);Serial.println(s2);MQTT_connect();bool tran=false;while(!tran){    bool a=photocell.publish(s1.c_str());    bool b=photocell.publish(s2.c_str());    tran=a and b;}Serial.println("ok"); 4)电脑侧开发:在电脑上订阅主题相对简单,使用python代码如下:import paho.mqtt.client as mqttbroker = 'broker.emqx.io'port = 1883topic = "/test" def on_connect(client, userdata, flags, rc):    print("Connected with result code: " + str(rc))def on_message(client, userdata, msg):    print(msg.topic + " " + str(msg.payload.decode('UTF-8'))) client = mqtt.Client()client.on_connect = on_connectclient.on_message = on_messageclient.connect(broker, port, 10)client.subscribe(topic, qos=0)client.loop_forever() 运行该python代码,可以得到当前温湿度: 考虑到用户都是些小学生,文字对他们吸引力不足,因此将该订阅信息改为面板显示,同时需要记录24小时的最大最小值。可以用tk编写界面,用正则表达式截取订阅消息里面关键字段填入StringVar,并在对应Entry中引用,实现图形化显示。目前监控点2和监控点3还没部署,只预留了接口。

tobot 发表于 2021-12-27 13:59

补充上传库文件

lospring 发表于 2021-12-30 16:41

谢谢分享

tobot 发表于 2021-12-30 22:14

lospring 发表于 2021-12-30 16:41
谢谢分享

不客气,我觉得玩python,我是专业的。。。有空聊聊

hi0712 发表于 2022-1-8 18:22

哦 看到了

qbwww 发表于 2022-1-10 16:23

学习了,之前用腾讯云配置mqtt,感觉好麻烦。
页: [1]
查看完整版本: 使用mqtt记录环境温湿度