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

比特青焰引
• 阅读 3436

简介

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

本示例的总体架构如下

通过基于 NodeMCU (ESP8266) 将传感器数据上传至 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)请参考如下截图

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

Arduino 配置

  • 下载并安装 CH340G USB 驱动
  • 安装 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 服务等时候需要根据目标云服务的安全要求设定连接方式。本文为了简单起见,使用了非安全的连接方式,在正式生产环境中必须设定安全认证方式的连接。

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

  • 查看 broker 连接地址

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

代码编写

#include <ESP8266WiFi.h>

#include <PubSubClient.h>

#include "DHT.h"

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

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

#define DHTTYPE DHT11   // DHT 11

WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(DHTPIN, DHTTYPE);

void setup() {
    Serial.begin(115200);
    setup_wifi();
    client.setServer(mqtt_server, 1883);
    dht.begin();
}

void setup_wifi() {
    delay(10);
    WiFi.begin(wifi_ssid, wifi_password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
}

void reconnect() {
    // Loop until we're reconnected
    while (!client.connected()) {
        Serial.print("Attempting MQTT connection...");
        if (client.connect("nodeMcuDHT11")) {
            Serial.println("connected");
        } else {
            Serial.print("failed, rc=");
            Serial.print(client.state());
            Serial.println(" try again in 5 seconds");
            delay(5000);
        }
    }
}

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

long lastMsg = 0;
float temp = 0.0;
float hum = 0.0;
float diff = 1.0;

void loop() {
    if (!client.connected()) {
        reconnect();
    }
    client.loop();

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

        float newTemp = dht.readTemperature();
        float newHum = dht.readHumidity();
        if (checkBound(newTemp, temp, diff)) {
            temp = newTemp;
            Serial.print("New temperature:");
            Serial.println(String(temp).c_str());
            client.publish(temperature_topic, String(temp).c_str(), true);
        }

        if (checkBound(newHum, hum, diff)) {
            hum = newHum;
            Serial.print("New humidity:");
            Serial.println(String(hum).c_str());
            client.publish(humidity_topic, String(hum).c_str(), true);
        }
    }
}

按照以下操作编辑代码以适合您自己的 Wi-Fi 和 MQTT 设置

  • Wi-Fi 设置

    #define wifi_ssid ""
    #define wifi_password ""
  • Broker 服务器设置

    #define mqtt_server "broker-internet-facing-f1429d8cb54ca4a7.elb.us-east-1.amazonaws.com"
  • Arduion 配置

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

运行

  • 代码上传

    将 NodeMCU 通过 USB 连接到 PC 并在 Arduion IDE 中选择 115200 端口,使用 upload 按钮编译草图并将其上传到设备

  • 打开 Arduino monitor window 查看数据上报

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

  • MQTT 客户端接受消息

    • 使用 MQTT Websocket Toolkit 测试上报消息

      MQTT Websocket Toolkit 是 EMQ 最近开源的一款 MQTT (WebSocket) 测试工具,支持线上 (tools.emqx.io) 访问使用, 我们可以方便的用于验证 NodeMCU 是否上报 MQTT 消息。
      1. 创建 MQTT 连接
        通过基于 NodeMCU (ESP8266) 将传感器数据上传至 MQTT 云服务
      2. 订阅主题,接受测试消息
        通过基于 NodeMCU (ESP8266) 将传感器数据上传至 MQTT 云服务
    • 使用Python MQTT 客户端查看上报消息

      from paho.mqtt import client as mqtt
      
      
      def on_connect(client, userdata, flags, rc):
          # connect mqtt broker
          client.subscribe([("temperature", 0), ("humidity", 0)])
      
      
      def on_message(client, userdata, msg):
          # sub dht11 temperature/humidity data
          print(f"{msg.topic}: {msg.payload.decode()}")
      
      
      def run():
          client = mqtt.Client()
          # Edit MQTT Cloud address
          client.connect("broker-internet-facing-f1429d8cb54ca4a7.elb.us-east-1.amazonaws.com", 1883)
          client.on_connect = on_connect
          client.on_message = on_message
          client.loop_forever()
      
      
      if __name__ == '__main__':
          run()

      Python 脚本运行截图:

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

  • 故障排除:为了执行故障排除,然后将 USB 适配器与 PC 连接并在 Arduino IDE 中选择 USB-TTL 适配器的端口。打开“串行监视器”以查看由串行输出产生的调试信息

总结

至此为止,完成了从 NodeMCU 采集数据,并上传到 EMQ 提供的 MQTT 云服务,最后由 Python 写的后端程序对数据进行处理的简单过程。但在实际的生产应用中,会需要更高的要求,比如,

  • 更加安全的连接方式
  • 对物联网数据进行实时处理
  • 对数据进行持久化
  • 更大规模的连接要求

EMQ 企业版在解决上述问题已经提供了很好的解决方案,有兴趣的读者可以参考相关链接了解更多的信息。

为了实现数据的高安全性(避免上传到云端),降低业务处理时延,以及数据传输成本,在解决方案中可以考虑采用边缘计算。Azure IoT Edge 和 AWS 的 Greengrass 提供了在边缘端的解决方案。EMQ 也提供了开源的超轻量级边缘物联网实时数据分析 (IoT Edge streaming analytics) 方案 Kuiper,读者可以参考这篇文章以获取更详细的信息。

版权声明: 本文为 EMQ 原创,转载请注明出处。

原文链接:https://www.emqx.io/cn/blog/u...

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Stella981 Stella981
3年前
Arduino Esp8266开发 (三)上传数据到阿里云MQTT服务器
一、前言1、能够使用Arduino的软串口控制Esp8266接入网络,可以看看我的前两个博客。2、了解MQTT协议,阿里云搭建MQTT服务器(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Feditor.csdn.net%2Fmd%2F%3FarticleId%3D10
Stella981 Stella981
3年前
Android 物联网开发:设备通过 MQTT 协议接入阿里云 IoT
!(https://oscimg.oschina.net/oscnet/712210b89e30d12f8ef3bca535fd295f177.png)在全球智能手机市场里,谷歌开发的Android移动操作系统市场占有率已经高达90%。随着物联网智能硬件升级,也逐渐成为智能摄像头,智能对讲门禁,人脸识别闸机,智能电视,智能广告屏等IoT设备的首选
Stella981 Stella981
3年前
STM32 MQTT协议 连接中国移动OneNet服务器 上传接收数据(一)
STM32ESP8266MQTT协议连接中国移动OneNet服务器上传接收数据(一)之前写过一篇通过自己的服务器来搭建MQTT的服务器的博客,但是我相信不是所有人都有自己的服务器,毕竟服务器是要钱的啊😨,没有服务器没关系,我们今天来看一下可以免费使用,且
Easter79 Easter79
3年前
STM32 MQTT协议 连接中国移动OneNet服务器 上传接收数据(一)
STM32ESP8266MQTT协议连接中国移动OneNet服务器上传接收数据(一)之前写过一篇通过自己的服务器来搭建MQTT的服务器的博客,但是我相信不是所有人都有自己的服务器,毕竟服务器是要钱的啊😨,没有服务器没关系,我们今天来看一下可以免费使用,且
Wesley13 Wesley13
3年前
activeMQ+MQTT实现点对点发送消息
问题的提出:最近在做若干安卓设备(共享项目使用的硬件)和服务器通信实现MQTT消息的的接收。由于MQTT的限制(注意:不管你用的是paho的库还是其他任何MQTT的库都一样,这是MQTT协议的限制。)而无法实现服务器只给某一台机器(根据机器的IMEI号)发送消息。一开始使用的方法,就是服务器只管群发(消息体里会带一个终端ID字段信息),安卓端收到消息后,
Wesley13 Wesley13
3年前
MQTT实战之MQTT入门
MQTT入门介绍(一)一.MQTT简述MQTT(MessageQueuingTelemetryTransport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在
Wesley13 Wesley13
3年前
MQTT初始篇笔记整理
MQTT简介MQTT(MessageQueuingTelemetryTransport,消息队列遥测传输),基于TCP/IP协议栈而构建,虽然叫消息队列遥测传输,但是她与消息队列毫无关系,她是一个IBM开发的客户端服务端架构的发布/订阅模式的消息传输协议;她的设计思想是轻巧、开放、简单、规范、易于实现,因此MQTT比较
Stella981 Stella981
3年前
MQTT消息协议、服务器及其客户端
    MQTT是一个轻量级的消息协议。从2014年12月IOIT大会上得到的消息,该协议已经被OASIS标准组织接收,成立了专门的工作组,以意味着该规范正式走向了标准化之路。    目前MQTT的标准组织官网:http://www.mqtt.org(https://www.oschina.net/action/GoToLink?urlhttp%3
GeorgeGcs GeorgeGcs
1个月前
【HarmonyOS 5】鸿蒙中如何使用MQTT
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、MQTT是什么?MQTT(MessageQueuingTelemetryTransport,消息队列遥测传输)是一种轻量级、基于发布/订阅(Publish/Subscribe)模式的即