Node-Red ESP8266 MQTT Publish Example

 Here it is shown how ESP8266 can be used to publish MQTT based message on the web using Node-Red as IoT platform. MQTT is a lightweight TCP protocol for building Internet of Things application. Here Mosqitto MQTT server/client application is used. Node-Red is open source graphical programming platform which can be used as Internet of Things platform. 

Here ESP8266 based NodeMCU board is used to read temperature and humidity data from DHT11 sensor and send publish that over WiFi to the WiFi server so that it can be accessed by anyone over the internet.

To accomplish this we can divide the work  in 3 steps involved as follows.

1. Interfacing ESP8266 with DHT11

2. Programming ESP8266

3. Set up and run MQTT server

4. Set up Node-Red for MQTT service

5. Publish MQTT service

The steps are described now below.

1. Interfacing ESP8266 with DHT11

The first step is to connect DHT11 to the ESP8266(NodeMCU) module. The interfacing diagram of DHT11 and  NodeMCU ESP8266 is shown below.

NodeMCU Node Red Industrial Iot platform

 The ESP8266 3.3V power pin is connected to the DHT11 Vcc pin and the ground pin of ESP8266 is connected to the ground of DHT11. The data pin of DHT11 is connected to the D7 pin of ESP8266 NodeMCU module. The following picture shows the hardware realized on actual breadboard.

DHT11 and NodeMCU

2. Programming ESP8266

Once the hardware connection between ESP8266 and the DHT11 is made, the next step is to write program for ESP8266 NodeMCU. The program will read the humidity and temperature data from the DHT11 module and send the data via WiFi to the MQTT server. The following is the program for ESP8266 that does this.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"

// DHT11 
#define DHTTYPE DHT11

// Credentials for WiFi
const char* ssid = "Your_WiFI_SSID";
const char* password = "Your_WiFi_Password";

// MQTT Server(eg 192.168.1.4)
const char* mqtt_server = "Your MQTT IP address";

// WiFi Client
WiFiClient nodeClient;
PubSubClient client(nodeClient);

// DHT Sensor pin at GPIO 13(D7)
const int DHTPin = 13;

// Initialize DHT sensor
DHT dht(DHTPin, DHTTYPE);

// Function to connect NodeMCU to WiFi router
void wifiConfig(){
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected, NodeMCU IP address: ");
  Serial.println(WiFi.localIP());
}

// Function to reconnect NodeMCU with MQTT broker
void reconnect(){
    while (!client.connected()) {
      Serial.print("Attempting MQTT connection...");
  
      if (client.connect("MQTTClient")){
        Serial.println("connected");  
      } 
      else{
        Serial.print("failed, State: ");
        Serial.print(client.state());
        Serial.println("try again in 5 seconds...");
        delay(5000);
      }
    }
}

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

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  if(!client.loop())
    client.connect("MQTTClient");
    
    // Read Humidity
    float H = dht.readHumidity();    
    // Read temperature as Celsius (the default)
    float T = dht.readTemperature();

    // Check if any reads failed and exit early (to try again).
    if (isnan(H) || isnan(T)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    } 

    //Convert float to string and store them in arrays
    static char humidity[7];
    dtostrf(H, 6, 2, humidity);
    static char temperature[7];
    dtostrf(T, 6, 2, temperature);

    // Publishes Temperature and Humidity values
    client.publish("dht11/temperature", temperature);
    client.publish("dht11/humidity", humidity);
    delay(5000);
} 

The above program does the followings.

a.  DHT11 library is used for making connection to DHT11 module and retrieve humidity and temperature data. This is done using the following statements in various parts of the program.


#include "DHT.h"
// DHT11 
#define DHTTYPE DHT11
// DHT Sensor pin at GPIO 13(D7)
const int DHTPin = 13;
// Initialize DHT sensor
DHT dht(DHTPin, DHTTYPE);
The following starts the DHT sensor in the setup() function.

dht.begin();
The following reads humidity and temperature data in the loop() function.

// Read Humidity
float H = dht.readHumidity();    
// Read temperature as Celsius (the default)
float T = dht.readTemperature();

b. Setting up connection to the WiFi router

This is done using the ESP8266WiFi library. The following are the program code involved in this step. The library ESP8266WiFi is called and some constants are defined.


#include <ESP8266WiFi.h>
// Credentials for WiFi
const char* ssid = "Your_WiFI_SSID";
const char* password = "Your_WiFi_Password";

In the wifiConfig() function we connect to the local WiFi network and print out information about the status of the connection


// We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected, NodeMCU IP address: ");
  Serial.println(WiFi.localIP());
  

The above codes are executed when the wifiConfig() is executed.


wifiConfig();

c. Setting up WiFi client and publishing message via WiFi

The next step is to create a WiFi client and then sending DHT11 humidity and temperature data to the MQTT server. The client is created using the PubSubClient library. The following are the code involved in the program.

Setup the library, initialize wifi client object and define some constants .

#include <PubSubClient.h>

// MQTT Server(eg 192.168.1.4)
const char* mqtt_server = "Your MQTT IP address";

// WiFi Client
WiFiClient nodeClient;
PubSubClient client(nodeClient);

The reconnect() function is used to repeatly establish connection to the MQTT server.

// Function to reconnect NodeMCU with MQTT broker
void reconnect(){
    while (!client.connected()) {
      Serial.print("Attempting MQTT connection...");
  
      if (client.connect("MQTTClient")){
        Serial.println("connected");  
      } 
      else{
        Serial.print("failed, State: ");
        Serial.print(client.state());
        Serial.println("try again in 5 seconds...");
        delay(5000);
      }
    }
}

In the setup() function the MQTT server is setup with port address.

client.setServer(mqtt_server, 1883);

In the loop() function we check the client connection regularly.

 if (!client.connected()) {
    reconnect();
  }
  if(!client.loop())
    client.connect("MQTTClient");

Also in the loop() function we check if data read is valid and if they are valid convert the float data into string, save in array and then publish the data over the wifi.

// Check if any reads failed and exit early (to try again).
    if (isnan(H) || isnan(T)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    } 

    //Convert float to string and store them in arrays
    static char humidity[7];
    dtostrf(H, 6, 2, humidity);
    static char temperature[7];
    dtostrf(T, 6, 2, temperature);

    // Publishes Temperature and Humidity values
    client.publish("dht11/temperature", temperature);
    client.publish("dht11/humidity", humidity);
    delay(5000);

3. Set up and run MQTT server

Here Mosquitto MQTT server/client application is used in windows. One can download Mosquitto for free and install it from the following link.

https://mosquitto.org

Once downloaded, in the folder where you downloaded the mosquitto application, you should see the mosquitto.exe application. 

mosquitto server

 In the same folder or if you made enviromental variable, start the mosquitto MQTT server(also called MQTT broker) using CLI command:

>mosquitto -v

as shown below.

Mosquitto MQTT broker

Now the MQTT broker is listening on localhost port 1883.

4. Set up Node-Red for MQTT service

The next step is to setup Node Red so that we can publish via MQTT broker. Start a new flow and in that flow drag in two mqtt_in nodes and two gauge nodes from the dashboard library. Create the flow as shown below.

Node Red Mosquitto MQTT

The two mqtt in nodes which are labelled dht11/humidity and dht11/temperature in the above flow can be found under the network library.

Node Red Mosquitto MQTT

Double click each mqtt in nodes and setup the following for each of them.


In the above pictures, setup the Server field as localhost:1883, set up the Action field to Subscribe to single topic and setup the Topic filed as dht11/humidity and dht11/temperature respectively. Use quality of service QoS for both as 1.

The nodes labelled Humidity and Temperature which are gauge node can found under the dashboard library. The Node Red IoT with Arduino DHT11 tutorial explains how to install the dashboard library.

The dashboard nodes requires tab and group name. To create a tab and group names, go to dashboard as shown below and from there create a new tab. Name the tab DHT11. Then from the newly created DHT11 tab, create a new group and name it NodeMCU as shown below.


 Now click on edit button from the group and set the width to 10 and uncheck the display group name as shown in the pictures below.


Once tab and group names have been created, click the Humidity and Temperature gauge nodes assign the newly created tab/group that is set to [DHT11]NodeMCU. Also set the size for both gauge nodes as 5x5. Use Humidity and Temperature in the label field. Then add % symbol in the value format for humidity add add ℃ in temperature value format.

5. Publish MQTT service 

At this point, the mosquitto MQTT service is ready to be published. The ESP8266 sends humidity and temperature data to the MQTT broker, we read in these data using mqtt in nodes in Node-Red and publish it on the internet via the Node-Red IoT framework.

 To start the publishing of humidity and temperature data using MQTT, click on the deploy button and then start button in Node Red.

 

Open a browser type in the url https://localhost:1880/ui to see the humidity and temperature data displayed on the dashboard as shown below.

NodeMCU Node Red Industrial Iot platform

As shown above, the data is displayed on the url used is http://app.ee-diary.ga/ui. This is because the Node Red application is hosted on home server using cloudflare. So the published MQTT data using ESP8266 is publicly available on the internet. This was done so here to illustrate an example of simple IoT application development with MQTT, ESP8266 and NodeRed. It can be easily extended to make industrial IoT applications

To learn how to setup home server see the tutorial How to host website from home. To learn how to host and display application on custom domain name see the tutorial Deploy Arduino Red Node App on Web with Cloudflare Tunnel.

The following is the node red flow code.


[
    {
        "id": "6e8e647f55f19c65",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "5afcb2f70fb4032f",
        "type": "mqtt in",
        "z": "6e8e647f55f19c65",
        "name": "",
        "topic": "dht11/humidity",
        "qos": "1",
        "datatype": "auto-detect",
        "broker": "62942e11fc49d33e",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 320,
        "y": 180,
        "wires": [
            [
                "f0c5c71cb90a0d4b"
            ]
        ]
    },
    {
        "id": "f0c5c71cb90a0d4b",
        "type": "ui_gauge",
        "z": "6e8e647f55f19c65",
        "name": "",
        "group": "fecb1abb8b6d2678",
        "order": 1,
        "width": "5",
        "height": "5",
        "gtype": "gage",
        "title": "Humidity",
        "label": "",
        "format": "{{value}}%",
        "min": 0,
        "max": "100",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "className": "",
        "x": 540,
        "y": 180,
        "wires": []
    },
    {
        "id": "bf3fce1725291ee7",
        "type": "mqtt in",
        "z": "6e8e647f55f19c65",
        "name": "",
        "topic": "dht11/temperature",
        "qos": "1",
        "datatype": "auto-detect",
        "broker": "62942e11fc49d33e",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 330,
        "y": 260,
        "wires": [
            [
                "6f2e240f9a0c13c8"
            ]
        ]
    },
    {
        "id": "6f2e240f9a0c13c8",
        "type": "ui_gauge",
        "z": "6e8e647f55f19c65",
        "name": "",
        "group": "fecb1abb8b6d2678",
        "order": 1,
        "width": "5",
        "height": "5",
        "gtype": "gage",
        "title": "Temperature",
        "label": "",
        "format": "{{value}}℃",
        "min": 0,
        "max": "100",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "className": "",
        "x": 550,
        "y": 260,
        "wires": []
    },
    {
        "id": "62942e11fc49d33e",
        "type": "mqtt-broker",
        "name": "",
        "broker": "localhost",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    },
    {
        "id": "fecb1abb8b6d2678",
        "type": "ui_group",
        "name": "NodeMCU",
        "tab": "886288b874f81978",
        "order": 1,
        "disp": false,
        "width": "10",
        "collapse": false,
        "className": ""
    },
    {
        "id": "886288b874f81978",
        "type": "ui_tab",
        "name": "DHT11",
        "icon": "dashboard",
        "order": 8,
        "disabled": false,
        "hidden": false
    }
]

So in this way we can create simple IoT application using Node Red as IoT platform. We can add to this MySQL database to store the humidity and temperature data and thus create a IoT monitoring system. To use MySQLdatabase in node red see the tutorial Read and Store Sensor Data into Database with Node Red.

Post a Comment

Previous Post Next Post