This tutorial covers how to develop an ESP8266 MQTT client to publish and subscribe to MQTT topics using Pubsubclient. Therefore, we will connect the ESP8266 to an MQTT broker, and later we will create a NodeRed dashboard that visualizes using a dashboard sensor readings. This is an interesting IoT project where we use Raspberry Pi with Mosquitto and ESP8266 MQTT client.
In this guide you will learn:
- how to publish data using MQTT from ESP8266
- how to subscribe to an MQTT channel using ESP8266
ESP8266 MQTT Client project overview
There are two different scenarios where we can use an ESP8266 MQTT client:
- to publish data
- to subscribe to an MQTT channel.
Publishing data via MQTT
In this scenario, the ESP8266 MQTT client connects to an MQTT broker (Mosquitto) running on a Raspberry Pi via MQTT protocol and publishes sensor readings.
Using this information we will build a NodeRed dashboard to visualize sensor readings using charts. You can use the same project to connect to other MQTT broker, for example, the ESP8266 can connect to an IoT platform that supports MQTT protocol (Google Cloud, Ubitods, AWS IoT and so on).
Subscribing to an MQTT channel
In the second scenario, we will build a Node-RED UI to control a remote LED connected to the ESP8266. In this case, the ESP8266 subscribes to an MQTT channel to receive data.
Prerequisites
To follow this guide you must be familiar with the MQTT protocol.
Recommended:
MQTT Protocol Tutorial: Technical description, MQTT security
ESP32 MQTT client: Publish and Subscribe. HiveMQ and BME280 example
Moreover, you need the following components:
- ESP8266
- DHT11/DHT22 sensor to read temperature and humidity
- one LED
Optional components:
- Raspberry Pi
- Node-RED installed on yuor Raspberry PI
- Mosquitto MQTT broker
How to publish data using ESP8266 via MQTT
To implement the first scenario where ESP8266 published data via MQTT, we can suppose that we want to publish DHT11 sensor readings to Mosquitto broker that runs on Raspberry Pi.
Considering that we publish temperature and humidity, the ESP8266 publishes these two pieces of information using two different MQTT channels.
The picture below clarifies it:

Next, using Node-RED we will build a Node-RED UI dashboard that visualizes the data acquired by the sensor. Node-RED runs on the Raspberry Pi. You can access the dashboard using a browser as we will see later.
Implementing the ESP8266 MQTT client using PubsubClient library
Once we have a big picture of the scenario where we want to use our ESP8266, we can start coding the MQTT client. To simplify the client development we will use the PubsubClient library. Therefore, you have to import it into your project.
The code is shown below:
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
IPAddress mqttServer(192,168,1,142);
const char *SSID = "your_ssid";
const char *PWD = "your_wifi_pwd";
long lastime = 0;
void callback(char* topic, byte* payload, unsigned int length) {
Serial.println("Callback");
Serial.println((char) payload[0]);
}
WiFiClient wifiClient = WiFiClient();
PubSubClient mqttClient(mqttServer, 1883, callback, wifiCliient);
void connectToWiFi() {
Serial.print("Connecting to ");
Serial.println(SSID);
WiFi.begin(SSID, PWD);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
// we can even make the ESP32 to sleep
}
Serial.print("Connected - ");
//Serial.println(WiFi.localIP);
}
void reconnect() {
Serial.println("Connecting to MQTT Broker...");
while (!mqttClient.connected()) {
Serial.println("Reconnecting to MQTT Broker..");
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
if (mqttClient.connect(clientId.c_str())) {
Serial.println("Connected.");
// subscribe to topic
}
}
}
void setup() {
Serial.begin(9600);
connectToWiFi();
}
void loop() {
if (!mqttClient.connected())
reconnect();
mqttClient.loop();
// Publishing data to MQTT
long now = millis();
if(now - lastime > 10000) {
Serial.println("Publishing data..");
// read temperature from sensor
mqttClient.publish("/esp8266/temperature", data);
// read humidity from sensor
mqttClient.publish("/esp8266/humidity", data);
lastime = now;
}
}
Code language: C# (cs)
Code description
- Line 3, we import the definitions to use the Pubsubclient.
- Line 4, we define the MQTT broker IP address where the ESP8266 connects to.
- Line 14, we create the PubSubClient MQTT client:
PubSubClient mqttClient(mqttServer, 1883, callback, wifiClient);
1883 is the MQTT broker port
The callback
is the function to call when the ESP8266 receives a message through the MQTT. By now we can skip it, we will use this option later when the ESP8266 will subscribe the to MQTT channel.
In the reconnect()
method, the code handles the connection to the MQTT and the disconnection event.
In line 63 and 65, we publish data acquired by the DHT11 sensor, using two different MQTT channels:
/esp8266/temperature
/esp8266/humidity
Connecting ESP8266 to DHT11 and publish data
Once, the ESP8266 MQTT client to publish data is ready, we can focus our attention on connecting the ESP8266 to the DHT11 sensor to acquire temperature and humidity.
#include <Adafruit_Sensor.h>
#include <DHT.h>
#define DHT_TYPE DHT11
#define DHT_PIN D5
DHT dht(DHT_PIN, DHT_TYPE);
char data[100];
void reconnect() {
Serial.println("Connecting to MQTT Broker...");
while (!mqttClient.connected()) {
Serial.println("Reconnecting to MQTT Broker..");
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
if (mqttClient.connect(clientId.c_str())) {
Serial.println("Connected.");
// subscribe to topic
mqttClient.subscribe("/esp8266/commands");
}
}
}
void setup() {
Serial.begin(9600);
connectToWiFi();
dht.begin();
Serial.println("DHT11 sensor....");
}
void loop() {
if (!mqttClient.connected())
reconnect();
mqttClient.loop();
// Publishing data to MQTT
long now = millis();
if(now - lastime > 10000) {
Serial.println("Publishing data..");
float temp = dht.readTemperature();
float hum = dht.readHumidity();
sprintf(data, "%f", temp);
Serial.println(data);
mqttClient.publish("/esp8266/temperature", data);
sprintf(data, "%f", hum);
Serial.println(hum);
mqttClient.publish("/esp8266/humidity", data);
lastime = now;
}
}
Code language: PHP (php)
The code above completes the development fo the ESP8266 client. This client publishes the DHT11 sensor readings using two different MQTT channels. Moreover, it sends data every 10 seconds.
How to develop the ESP8266 MQTT client to subscribe to MQTT channel
In this second part of this ESP8266 tutorial, we will analyze how to develop an ESP8266 MQTT client that subscribes to an MQTT channel so that the ESP8266 can receive data (such as commands).
In this scenario, we can suppose our device receives commands to control an LED turning it on or off. Later, we will develop the dashboard using Node-RED running on Raspberry Pi to command the LED. Therefore, the picture below shows the scenario we want to develop:

As described in the picture above, trough the dashboard built using Node-RED, we will send commands to the ESP8266 that subscribes to the command channel. In this case, the MQTT client receives data through the MQTT channel while in the first scenario the ESP8266 publishes data.
Now it should be clear the main difference between publishing data and subscribing to a channel.
The code is almost the same as shown in the previous scenario. Anyway, in this context, it is necessary to implement the callback function that is invoked when the ESP8266 receives data through the MQTT channel. Therefore, it is necessary to implement the function callback
.
In this method, we will implement the logic to turn on or off the LED connected to the ESP8266. The code is trivial:
void callback(char* topic, byte* payload, unsigned int length) {
Serial.println("Callback");
Serial.println((char) payload[0]);
// using payload[0] == 't' or 'f' turn or off the LED
}
Code language: JavaScript (javascript)
How to develop a Node-RED UI dashboard to publish and receive data through MQTT
Finally, in this last part of this project, we will implement a Node-RED UI dashboard.
This dashboard will receive data published by the ESP8266 MQTT client on the channels /esp8266/temperature
and /esp8266/humidity
. Conversely, the Node-red UI dashboard publishes data to the /esp8266/commands
channel where the ESP8266 MQTT client is subscribed.
Let us see how we can install and configure them.
Installing Mosquitto on Raspberry Pi using Docker
The Mosquitto installation is very simple. We will use Docker to install it:
sudo docker run -it -p 1883:1883 -p 9001:9001 eclipse-mosquitto
Code language: CSS (css)
It will run the Mosquitto MQTT broker that listens on port 1883.
Installing Node-RED on Raspberry Pi using Docker
Next, we have to install Node-RED. In the same way, we did before, we use Docker:
sudo docker run -p 1880:1880 nodered/node-red -v /home/pi/.node-red:/data
Node-RED runs on port 1880. Then, open your browser and connect to the Node-RED interface. Before connecting the Node-red to the MQTT broker, we have to import the dashboard UI nodes. You can do it using the Palette menu.
Creating Node-red UI
In this step, we create the Node-RED flow that should look like the one shown in the picture below:

Below the file json to import that creates the flow shown above:
{"id":"62754c3f.ea8df4","type":"ui_chart","z":"43827484.221c5c","name":"Temperature","group":"6ce5a9c7.9482d8","order":0,"width":0,"height":0,"label":"Temperature","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"40","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":630,"y":380,"wires":[[]]},{"id":"6ce5a9c7.9482d8","type":"ui_group","z":"","name":"Control","tab":"3f223f3f.02ae8","disp":true,"width":"6","collapse":false},{"id":"3f223f3f.02ae8","type":"ui_tab","name":"Tab 1","icon":"dashboard","order":1}]
Code language: JSON / JSON with Comments (json)
As you can see from the picture above there are three UI nodes:
- Switch that will use to command the LED
- A gauge that will show the humidity
- Chart that will show the temperature
Moreover, there are three different nodes:
- a node that publishes data (from the switch) to /esp8266/commands where the MQTT client is subscribed
- two MQTT channels where the ESP8266 MQTT client publishes data coming from DHT11 sensor.
Next, let us deploy the flow to the Node-red server and let us show the UI dashboard. The result is:

Wrapping up
In conclusion, at the end of this tutorial, you, hopefully, gained knowledge about how to develop the ESP8266 MQTT client. We saw how to connect the ESP8266 to the MQTT broker and how to use the ESP8266 to subscribe to MQTT channels. Moreover, we discovered that we can use the ESP8266 MQTT client to publish data coming from sensors. In the end, this tutorial covered how to build a Node-red UI dashboard that connects to the MQTT broker to visualize data.