ESP32-DHT11温湿度数据上传MQTT服务器
- 简介
- ESP32
- DHT11
- 实验
- 实验说明
- 接线
- MQTT服务器
- 建立连接
- 添加订阅
- ESP32驱动DHT11
- ESP32向MQTT服务器发送数据
- 上传温湿度数据
- 实验结果
简介
ESP32
ESP32 系列模组集成 Wi-Fi、传统蓝牙和低功耗蓝牙功能,具有广泛的用途:Wi-Fi 支持大范围的通信连接,也支持通过路由器直接连接互联网,同时蓝牙可以让用户连接手机或者广播 Bluetooth LE Beacon 以便于信号检测,可快速搭建物联网项目。
本次实验用到是ESP32-WROOM-32的开发板,通过wifi联网后把传感器的数据上传到MQTT服务器。
DHT11
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,传感器通过一个电阻式感湿元件和一个NTC测温元件,通过单线制串行接口与单片机连接、开发即可实现稳定可靠的温湿度测量。
实验
MQTT 是轻量级的、灵活的物联网消息交换和数据传递协议,本次实验目的为通过ESP32驱动DHT11,并把DHT11的温湿度数据上传到MQTT服务器,实现远程监测。
实验说明
实验需要用到MQTT服务器,自己搭建或者购买只是用于实验的话有点浪费,可以网上找免费开放的MQTT服务器,实验完全够用。本次实验会用到EMQ X Cloud 上的免费MQTT服务器。所以需要电脑安装MQTT X这个软件,同时准备好DHT11和ESP32开发板。
接线
ESP32 | DHT11 |
---|---|
5V | V |
GND | G |
GPIO5 | D |
MQTT服务器
建立连接
首先在电脑端把MQTT服务器连接上,首先下载安装MQTT X传送门,安装好后打开点击软件主页面里的“+”加号
可以根据上面的图片配置,
- 名称可以随便填个英文名称
- Client ID默认不用管
- 服务器地址:broker.emqx.io
- 端口:1883
- 用户名:emqx
- 密码:public
- 其他参数按图片上配置就好
填好配置后点击连接
添加订阅
添加TEST/DHT11为主题的订阅,填写好后点击确定即可
界面如上图后就是已经添加好了订阅,上面的订阅主题可以自行更改。
到这一步MQTT X配置完,“放一边备用”。
ESP32驱动DHT11
由于本文的主要目的是把DHT11的数据上传到MQTT服务器,所以驱动DHT11不详细展开,直接调用“DHT Sensor Library For ESPx”这个库,建单了解一下这个库即可。先实现ESP32驱动DHT11,把温湿度从串口打印输出。
以下是调用“DHT Sensor Library For ESPx”库编写的驱动代码
#include <Arduino.h>
#include "DHTesp.h"
/** Initialize DHT sensor 1 */
DHTesp dht;
int dhtPin = 5;
/** Data from sensor 1 */
TempAndHumidity dhtData;
void setup() {
Serial.begin(115200);
// Initialize temperature sensor 1
dht.setup(dhtPin, DHTesp::DHT11);
}
void loop() {
dhtData = dht.getTempAndHumidity(); // Read values from sensor 1
Serial.println("Temp: " + String(dhtData.temperature,2) + "'C Humidity: " + String(dhtData.humidity,1) + "%");
delay(1000);
}
输出结果
ESP32向MQTT服务器发送数据
本次实验中ESP32与MQTT服务器通讯用到的“PubSubClient”和“WiFi”这两个库。
代码中定义的wifi和MQTT参数,代码移植需要修改好自己的WIFI参数和MQTT的参数。
const char *ssid="xxxxxxxx"; //WIFI名称
const char *password="xxxxxxxx"; //WIFI密码
const char *mqtt_broker = "xxxxxxxx"; //MQTT地址
const char *topic = "xxxxxxxx"; //MQTT主题
const char *mqtt_username = "xxxxxxxx"; //MQTT用户名
const char *mqtt_password = "xxxxxxxx"; //MQTT用户密码
const int mqtt_port = xxxxxxxx; //MQTT端口
上面定义好的wifi名称和密码,通以下WIFI初始化语句连使得ESP32连接WIFI
WiFi.begin(ssid,password);
“PubSubClient”库里的setServer和connect函数通过输入MQTT服务器地址、端口号和用户账号连接MQTT服务器
client.setServer(mqtt_broker,mqtt_port); //MQTT地址,端口号
client.connect(client_id.c_str(),mqtt_username,mqtt_password);
订阅主题
client.subscribe(topic); //订阅topic这个主题
再通过publish函数向MQTT服务器响应的主题发送数据
client.publish(topic,"I AM ESP32");
向MQTT服务器的"TEST/DHT11"主题
连接成功并把“I AM ESP32”上传到了MQTT服务器的"TEST/DHT11"这个topic。
#include <WiFi.h>
#include <PubSubClient.h>
//WIFI 参数配置
const char *ssid="JS-TEST";
const char *password="YXDZ@2022";
//MQTT 参数配置
const char *mqtt_broker = "broker.emqx.io"; //MQTT地址
const char *topic = "TEST/DHT11"; //MQTT主题
const char *mqtt_username = "emqx"; //MQTT用户名
const char *mqtt_password = "public"; //MQTT用户密码
const int mqtt_port = 1883; //MQTT端口
WiFiClient espClient; //创建WIFI对象
PubSubClient client(espClient);
void setup() {
// put your setup code here, to run once:
//初始化串口
Serial.begin(115200);
//初始化wifi,连接wifi
WiFi.begin(ssid,password);
//检测是否连上wifi,如果没连上一直循环,连上了往下运行
while(WiFi.status()!=WL_CONNECTED)
{
delay(500);
Serial.println("Connecting to WIFI ...");
}
Serial.println("Connecting to WIFI network");
//连接到MQTT服务器
client.setServer(mqtt_broker,mqtt_port); //MQTT地址,端口号
//进入循环开始连接MQTT服务器,连上了就退出循环,没连上就一直循环连接
while(!client.connected())//判断是否连上MQTT服务器
{
//client_id赋值加上设备mac
String client_id = "esp32-client-";
client_id +=String(WiFi.macAddress());
Serial.printf("the client %s connects to public mqtt broker\n",client_id.c_str());
if(client.connect(client_id.c_str(),mqtt_username,mqtt_password)) //连接MQTT服务器
{
Serial.println("Public emqx mqtt broker connected"); //连接成功,打印信息
}
else
{
Serial.print("failed with state");//连接失败
Serial.print(client.state()); //重新连接
delay(2000);
}
}
client.publish(topic,"I AM ESP32"); //发送信息到MQTT服务器
client.subscribe(topic); //订阅topic这个主题
}
void loop() {
// put your main code here, to run repeatedly:
client.loop();
}
MQTT接收情况
"TEST/DHT11"这个topic收到了“I AM ESP32” 并且串口返回了“Public emqx mqtt broker connected”表示成功连接MQTT服务器成功。
接下来把DHT11的温湿度数据也上传到"TEST/DHT11"这个topic。
上传温湿度数据
上面完成了EPS32驱动DHT11的程序并且也完成了ESP32向MQTT服务器发送数据的程序,把DHT11的数据上传到MQTT服务器就相当于把两个程序整合起来。
由于是免费开发的MQTT服务器,需要注意上传数据的频率,如果频繁向服务器上传数据有可能会禁用。所以这边间隔10s上传一次数据。
整合后的代码
#include <Arduino.h>
#include "DHTesp.h"
#include <WiFi.h>
#include <PubSubClient.h>
DHTesp dht11;
int dhtPin = 5;
TempAndHumidity sensorData;
//WIFI 参数配置
const char *ssid="JS-TEST";
const char *password="YXDZ@2022";
//MQTT 参数配置
const char *mqtt_broker = "broker.emqx.io"; //MQTT地址
const char *topic = "TEST/DHT11"; //MQTT主题
const char *mqtt_username = "emqx"; //MQTT用户名
const char *mqtt_password = "public"; //MQTT用户密码
const int mqtt_port = 1883; //MQTT端口
WiFiClient espClient; //创建WIFI对象
PubSubClient client(espClient);
void setup() {
// put your setup code here, to run once:
//初始化串口
Serial.begin(115200);
//初始化DHT11
dht11.setup(dhtPin, DHTesp::DHT11);
//初始化wifi,连接wifi
WiFi.begin(ssid,password);
//检测是否连上wifi,如果没连上一直循环,连上了往下运行
while(WiFi.status()!=WL_CONNECTED)
{
delay(500);
Serial.println("Connecting to WIFI ...");
}
Serial.println("Connecting to WIFI network");
//连接到MQTT服务器
client.setServer(mqtt_broker,mqtt_port); //MQTT地址,端口号
client.setCallback(callback); //连接回传信息
//进入循环开始连接MQTT服务器,连上了就退出循环,没连上就一直循环连接
while(!client.connected())//判断是否连上MQTT服务器
{
//client_id赋值加上设备mac
String client_id = "esp32-client-";
client_id +=String(WiFi.macAddress());
Serial.printf("the client %s connects to public mqtt broker\n",client_id.c_str());
if(client.connect(client_id.c_str(),mqtt_username,mqtt_password)) //连接MQTT服务器
{
Serial.println("Public emqx mqtt broker connected"); //连接成功,打印信息
}
else
{
Serial.print("failed with state");//连接失败
Serial.print(client.state()); //重新连接
delay(2000);
}
}
client.publish(topic,"ESP32_HDT11"); //发送信息到MQTT服务器
client.subscribe(topic); //订阅topic这个主题
}
void callback(char *topic, byte *payload, unsigned int length)
{
Serial.print("Message arrived in topic:");
Serial.println(topic); //打印主题名称
Serial.print("message:");zhuyi
//打印MQTT返回的信息
for(int i=0;i<length;i++)
{
Serial.print((char)payload[i]);
}
Serial.println();
Serial.println("--------------------");
}
void loop() {
// put your main code here, to run repeatedly:
// client.loop();
sensorData = dht11.getTempAndHumidity();
Serial.println("Temp: " + String(sensorData.temperature,2) + "'C Humidity: " + String(sensorData.humidity,1) + "%");
client.publish(topic,(("Temp: " + String(sensorData.temperature,2) + "'C Humidity: " + String(sensorData.humidity,1) + "%").c_str())); //发送信息到MQTT服务器
delay(10000);
}
实验结果
从上面图片中可以看到Arduino IDE的串口打后数据同步发送到了"TEST/DHT11"这个主题上。实验完成。