我的账户
中国电子DIY

科技成就未来

亲爱的游客,欢迎!

已有账号,请

如尚未注册?

通过 NodeMCU (ESP8266) 将传感器数据上传至 MQTT 云服务

[复制链接]
emqttx 发表于 2020-6-19 03:25:45 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
本帖最后由 emqttx 于 2020-6-19 03:28 编辑

简介
本示例将演示如何通过 基于 ESP8266 的 NodeMCU,把通过 DHT11 传感器搜集到的温、湿度数据通过 MQTT 协议将其上报到云端的 MQTT 服务,并且展示应用端如何订阅到这些数据并对之进行处理的过程。本文使用 MQTT 协议的原因在于该协议比较轻量级,节约能耗,非常适合于物联网的相关使用场景;目前各大公有云云提供商基本上都开放了基于 MQTT 协议的 IoT Hub 服务。比如 AWS 的 IoT Core,以及 Azure 的 IoT Hub 等,通过 MQTT 协议可以非常方便的将这些数据直接接入这些公有云服务。
本示例的总体架构如下

配置硬件配置
  • NodeMCU board x 1:NodeMCU 是一个开源的 IoT (硬件)开发平台,NodeMCU 包含了可以运行在 ESP8266 Wi-Fi SoC芯片之上的固件,以及基于 ESP-12 模组的硬件。“NodeMCU” 缺省一般指的是固件,而不是开发套件。固件使用 Lua 脚本语言。
  • DHT11 temperature/humidity sensor x 1:DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器
  • 面包板(Breadboard )x 1
  • 跳线(Jumper wires)若干
  • 连接图(Connection Graph)请参考如下截图
      
Arduino 配置
  • 下载并安装 CH340G USB(https://kig.re/downloads/CH34x_Install.zip) 驱动
  • 安装 ESP8266模块
  • 安装 PubSubClient 库 (by Nick O'Leary) Sketch -> Include Library -> Manage Libraries... -> Type PubSub in Search field -> Install
MQTT 云服务
通过 NodeMCU 将数据采集成功后,需要将其发送到云端的 MQTT 云服务。本文使用由 EMQX 提供的 MQTT 云服务, 读者也可以根据自己的情况来选择别的 MQTT 云服务,比如 Azure IoT Hub 或者 AWS IoT Core,每种云服务在接入的时候需要提供不同的认证方式,因此通过 NodeMCU 连接云端的 MQTT 服务等时候需要根据目标云服务的安全要求设定连接方式。本文为了简单起见,使用了非安全的连接方式,在正式生产环境中必须设定安全认证方式的连接。
  • 点击 EMQX Cloud(https://cloud.emqx.io/cn/) 注册地址注册
  • 注册后点击 EMQX Cloud 申请免费试用15天部署
  • 查看 broker 连接地址


代码编写
  1. #include <ESP8266WiFi.h>

  2. #include <PubSubClient.h>

  3. #include "DHT.h"

  4. #define DHTPIN D4     // what pin we're connected to
  5. #define wifi_ssid "xxxxx"
  6. #define wifi_password "xxxxx"

  7. #define mqtt_server "broker-internet-facing-f1429d8cb54ca4a7.elb.us-east-1.amazonaws.com"  // MQTT Cloud address
  8. #define humidity_topic "humidity"
  9. #define temperature_topic "temperature"

  10. #define DHTTYPE DHT11   // DHT 11

  11. WiFiClient espClient;
  12. PubSubClient client(espClient);
  13. DHT dht(DHTPIN, DHTTYPE);

  14. void setup() {
  15.     Serial.begin(115200);
  16.     setup_wifi();
  17.     client.setServer(mqtt_server, 1883);
  18.     dht.begin();
  19. }

  20. void setup_wifi() {
  21.     delay(10);
  22.     WiFi.begin(wifi_ssid, wifi_password);
  23.     while (WiFi.status() != WL_CONNECTED) {
  24.         delay(500);
  25.         Serial.print(".");
  26.     }
  27. }

  28. void reconnect() {
  29.     // Loop until we're reconnected
  30.     while (!client.connected()) {
  31.         Serial.print("Attempting MQTT connection...");
  32.         if (client.connect("nodeMcuDHT11")) {
  33.             Serial.println("connected");
  34.         } else {
  35.             Serial.print("failed, rc=");
  36.             Serial.print(client.state());
  37.             Serial.println(" try again in 5 seconds");
  38.             delay(5000);
  39.         }
  40.     }
  41. }

  42. bool checkBound(float newValue, float prevValue, float maxDiff) {
  43.     return newValue < prevValue - maxDiff || newValue > prevValue + maxDiff;
  44. }

  45. long lastMsg = 0;
  46. float temp = 0.0;
  47. float hum = 0.0;
  48. float diff = 1.0;

  49. void loop() {
  50.     if (!client.connected()) {
  51.         reconnect();
  52.     }
  53.     client.loop();

  54.     long now = millis();
  55.     if (now - lastMsg > 30000) {
  56.         // Wait a few seconds between measurements
  57.         lastMsg = now;

  58.         float newTemp = dht.readTemperature();
  59.         float newHum = dht.readHumidity();
  60.         if (checkBound(newTemp, temp, diff)) {
  61.             temp = newTemp;
  62.             Serial.print("New temperature:");
  63.             Serial.println(String(temp).c_str());
  64.             client.publish(temperature_topic, String(temp).c_str(), true);
  65.         }

  66.         if (checkBound(newHum, hum, diff)) {
  67.             hum = newHum;
  68.             Serial.print("New humidity:");
  69.             Serial.println(String(hum).c_str());
  70.             client.publish(humidity_topic, String(hum).c_str(), true);
  71.         }
  72.     }
  73. }
复制代码
按照以下操作编辑代码以适合您自己的 Wi-Fi 和 MQTT 设置
  • Wi-Fi 设置
    1. #define wifi_ssid ""
    2. #define wifi_password ""
    复制代码

  • Broker 服务器设置
    1. #define mqtt_server "broker-internet-facing-f1429d8cb54ca4a7.elb.us-east-1.amazonaws.com"
    复制代码

  • Arduion 配置


运行
  • 代码上传
    将 NodeMCU 通过 USB 连接到 PC 并在 Arduion IDE 中选择 115200 端口,使用 upload 按钮编译草图并将其上传到设备
  • 打开 Arduino monitor window 查看数据上报
  • MQTT 客户端接受消息
    使用 MQTT Websocket Toolkit 测试上报消息
    MQTT Websocket Toolkit 是 EMQ 最近开源的一款 MQTT (WebSocket) 测试工具,支持线上 (tools.emqx.io) 访问使用, 我们可以方便的用于验证 NodeMCU 是否上报 MQTT 消息。

    创建 MQTT 连接

    订阅主题,接受测试消息
  • 使用Python MQTT 客户端查看上报消息 Python 脚本
    运行截图:

    代码如下:
  1. from paho.mqtt import client as mqtt


  2. def on_connect(client, userdata, flags, rc):
  3. # connect mqtt broker
  4. client.subscribe([("temperature", 0), ("humidity", 0)])


  5. def on_message(client, userdata, msg):
  6. # sub dht11 temperature/humidity data
  7. print(f"{msg.topic}: {msg.payload.decode()}")


  8. def run():
  9. client = mqtt.Client()
  10. # Edit MQTT Cloud address
  11. client.connect("broker-internet-facing-f1429d8cb54ca4a7.elb.us-east-1.amazonaws.com", 1883)
  12. client.on_connect = on_connect
  13. client.on_message = on_message
  14. client.loop_forever()


  15. if __name__ == '__main__':
  16. run()
复制代码
5. 故障排除:为了执行故障排除,然后将 USB 适配器与 PC 连接并在 Arduino IDE 中选择 USB-TTL 适配器的端口。打开“串行监视器”以查看由串行输出产生的调试信息

总结
至此为止,完成了从 NodeMCU 采集数据,并上传到 EMQ 提供的 MQTT 云服务,最后由 Python 写的后端程序对数据进行处理的简单过程。但在实际的生产应用中,会需要更高的要求,比如,
  • 更加安全的连接方式
  • 对物联网数据进行实时处理
  • 对数据进行持久化
  • 更大规模的连接要求
EMQ 企业版,及其云服务在解决上述问题已经提供了很好的解决方案,有兴趣的读者可以参考相关链接了解更多的信息。
为了实现数据的高安全性(避免上传到云端),降低业务处理时延,以及数据传输成本,在解决方案中可以考虑采用边缘计算。Azure IoT Edge 和 AWS 的 Greengrass 提供了在边缘端的解决方案。EMQ 也提供了开源的超轻量级边缘物联网实时数据分析 (IoT Edge streaming analytics) 方案 Kuiper。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关注0

粉丝0

帖子0

发布主题
最新发布
推荐阅读
关注我们
中国电子DIY官方微信

客服电话:000-000-0000

客服邮箱:776513803@qq.com

周一至周五 9:00-18:00

公司地址:深圳市南山区美丽湾大厦B座

Powered by Discuz! X3.4@ 2001-2013 Comsenz Inc.