This example will demonstrate how to use the ESP8266-based NodeMCU to upload temperature and humidity data collected through the DHT11 sensor to the MQTT cloud service using the MQTT protocol. It will also show how the application side subscribes to these data and processes them. The reason for using the MQTT protocol is that it is lightweight and energy-efficient, making it very suitable for IoT-related usage scenarios. Currently, major public cloud providers have opened IoT Hub services based on the MQTT protocol, such as AWS IoT Core and Azure IoT Hub. The MQTT protocol allows for easy integration of this data into these public cloud services.
The overall architecture of this example is as follows
Hardware Configuration
-
NodeMCU board x 1: NodeMCU is an open-source IoT (hardware) development platform that includes firmware that can run on the ESP8266 Wi-Fi SoC chip, as well as hardware based on the ESP-12 module. “NodeMCU” generally refers to the firmware rather than the development kit. The firmware uses the Lua scripting language.
-
DHT11 temperature/humidity sensor x 1: The DHT11 digital temperature and humidity sensor is a composite sensor that outputs calibrated digital signals.
-
Breadboard x 1
-
Jumper wires several
-
Connection Graph: Please refer to the screenshot below
Arduino Configuration
-
Download and install the CH340G USB (https://kig.re/downloads/CH34x_Install.zip) driver
-
Install the ESP8266 module
-
Install the PubSubClient library (by Nick O’Leary) Sketch -> Include Library -> Manage Libraries… -> Type PubSub in Search field -> Install
MQTT Cloud Service
After successfully collecting data via NodeMCU, it needs to be sent to the MQTT cloud service. This article uses the MQTT cloud service provided by EMQX, but readers can choose other MQTT cloud services according to their situation, such as Azure IoT Hub or AWS IoT Core. Each cloud service requires different authentication methods for access, so when connecting NodeMCU to the MQTT service in the cloud, it is necessary to set the connection method according to the security requirements of the target cloud service. For simplicity, this article uses an unsecured connection method, and in a production environment, secure authentication connection methods must be set.
-
Click EMQX Cloud (https://accounts.emqx.io/signin?continue=https://cloud.emqx.io) to register
-
After registration, click EMQX Cloud (https://cloud.emqx.io/console/deployments/0?oper=new) to apply for a free trial deployment for 15 days
-
View the broker connection address
#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);
}
}
}
Edit the code according to your own Wi-Fi and MQTT settings as follows:
-
Wi-Fi Settings
#define wifi_ssid "" #define wifi_password ""
-
Broker Server Settings
#define mqtt_server "broker-internet-facing-f1429d8cb54ca4a7.elb.us-east-1.amazonaws.com"
-
Arduino Configuration
-
Code Upload
Connect NodeMCU to the PC via USB and select the
115200
port in the Arduino IDE, use theupload
button to compile the sketch and upload it to the device -
Open the Arduino monitor window to view data reporting
-
MQTT Client Receives Messages
-
Use MQTT Websocket Toolkit(http://tools.emqx.io/) to test reported messages
MQTT Websocket Toolkit is a recently open-sourced MQTT (WebSocket) testing tool by EMQ, supporting online (tools.emqx.io) access. It can be conveniently used to verify whether NodeMCU reports MQTT messages.
-
Create MQTT Connection
-
Use Python MQTT client to view reported messages
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 script running screenshot:
-
Troubleshooting: To perform troubleshooting, connect the USB adapter to the PC and select the port of the USB-TTL adapter in the Arduino IDE. Open the “Serial Monitor” to view the debugging information generated by the serial output
So far, we have completed the simple process of collecting data from NodeMCU and uploading it to the MQTT cloud service provided by EMQ, and finally processing the data with a backend program written in Python. However, in actual production applications, higher requirements will be needed, such as:
-
More secure connection methods
-
Real-time processing of IoT data
-
Data persistence
-
Higher scale connection requirements
For more information, please visit our official website
https://emqx.io,
or follow our open-source project
https://github.com/emqx/emqx,
for detailed documentation, please visit the official documentation
https://docs.emqx.io/broker/en