ESP8266 as MQTT publisher and subscriber

Assuming you have Arduino IDE . Before you start using ESP8266 or NodeMCU as Publisher or Subscriber , You need a MQTT Broker. Broker can be install on Windows computer (Installing MQTT Broker on Windows) or Linux machine(Installing MQTT Broker on Linux) or Raspberry pi or VM instance of Google Cloud etc.

Install pubsubclient-master and ESP8266WiFi.h libraries

Steps for installing pubsubclient-master and ESP8266WiFi.h libraries are given below.
1)Download the pubsubclient-master and Extract in the following path.
Download pubsubclient-master (3293 downloads)

C:\Users\username\Documents\Arduino\libraries OR
This PC -> Documents\Arduino\libraries.

2)Download or install the ESP8266WiFi.h , To download or install please Follow the following steps. If ESP8266WiFi.h is already downloaded then skip this step.
I)Open Arduino IDE & click on the File -> Preferences.

II)In Aditional Boards Manager URLs , Enter the following URL.

http://arduino.esp8266.com/stable/package_esp8266com_index.json

If above URL is already added then direct start from the third step.

III)Now go to Tools -> Board -> Boards Manager, Search ESP8266 and Select highest Non beta Version and Click on install .

IV)Now go to Sketch -> Include Library -> Manage Libraries -> Search ESP8266WiFi.h -> Click on install.

ESP8266 AS PUBLISHER:
ESP8266 or NodeMCU can be use as MQTT client i.e MQTT publisher. To use ESP8266 as MQTT publisher, you need above mentioned two libraries. Assuming you have above mentioned two libraries . To use ESP8266 as MQTT Publisher, use the code given below. Download or copy paste the code and modify the following things.

1)Replace SSID  with your WiFi name
2)Replace password  with your WiFi password.
3)Replace host name IP with IP address of machine on which broker is installed.
4)If you want to change payload or data please modify void MQTTPOST() function
5)If you want to modify Publisher topic please see void MQTTPOST() function

Download ESP8266 Publisher code (2417 downloads)

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

const char* ssid ="bytesofgigabytes"; //replace this with your wifi  name
const char* password ="bytes1234"; //replace with your wifi password
char hostname[] ="192.168.43.220"; //replace this with IP address of machine 
//on which broker is installed
#define TOKEN "bytesofgigabytes"

WiFiClient wifiClient;
PubSubClient client(wifiClient);

int status = WL_IDLE_STATUS;

void setup()
{
Serial.begin(115200);
WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to WiFi");
Serial.println("ESP8266 AS PUBLISHER");
client.setServer(hostname, 1883 ); //default port for mqtt is 1883
}

void loop()
{
if ( !client.connected() )
{
reconnect();
}
MQTTPOST();
delay(5000);//delay 5 Sec
}

void MQTTPOST()
{
//payload formation begins here
String payload ="{";
payload +="\"Temp\":"; payload +=10; payload +=",";
payload +="\"Humi\":"; payload +=20;
payload +="}";

char attributes[1000];
payload.toCharArray( attributes, 1000 );
client.publish("test", attributes); //topic="test" MQTT data post command.
Serial.println( attributes );
}
//this function helps you reconnect wifi as well as broker if connection gets disconnected.
void reconnect() 
{
while (!client.connected()) {
status = WiFi.status();
if ( status != WL_CONNECTED) {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to AP");
}
Serial.print("Connecting to Broker …");
Serial.print("192.168.43.220");

if ( client.connect("ESP8266 Device", TOKEN, NULL) )
{
Serial.println("[DONE]" );
}
else {
Serial.println( " : retrying in 5 seconds]" );
delay( 5000 );
}
}
}

ESP8266 AS PUBLISHER OUTPUT:

ESP8266 AS Subscriber:
ESP8266 or NodeMCU can be use as MQTT client i.e MQTT subscriber. To use ESP8266 as MQTT subscriber, you need above mentioned two libraries. Assuming you have above mentioned two libraries . To use ESP8266 as MQTT subscriber, use the code given below. Download or copy paste the code and modify the following things.

1)Replace SSID value with your WiFi name
2)Replace password value with your WiFi password.
3)Replace broker IP with IP address of machine on which broker is installed.
4)If you want to modify Subscriber topic please see setup() function

Download ESP8266 Subscriber code (2145 downloads)

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

const char* ssid = "bytesofgigabytes";//replace this with your wifi access point 
//name
const char* password = "bytes1234"; //replace with your wifi password
const char* broker = "192.168.43.220"; //IP address of broker
const int port = 1883;
const char* mqttUser = "user";
const char* mqttPassword = "user";

WiFiClient espClient;
PubSubClient client(espClient);

void callback(char* topic, byte* payload, unsigned int length) {

  Serial.print("Message received in topic: ");
  Serial.print(topic);
  Serial.print("   length is:");
  Serial.println(length);

  Serial.print("Data Received From Broker:");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }

  Serial.println();
  Serial.println("-----------------------");
  Serial.println();

}

void setup() {

  Serial.begin(115200);

  WiFi.begin(ssid, password);
  Serial.println("Connecting to WiFi..");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(100);
    yield();
  }
  Serial.println("Connected to the WiFi network");

  client.setServer(broker, port);
  client.setCallback(callback);

  while (!client.connected()) {
    Serial.println("Connecting to MQTT...");

    if (client.connect("ESP32Client", mqttUser, mqttPassword ))
    {

      Serial.println("connected to MQTT broker");

    }
    else
    {

      Serial.print("failed with state ");
      Serial.print(client.state());
      delay(500);

    }
  }

  
  Serial.println("ESP8266 AS SUBSCRIBER");
  Serial.println("Subscribing topic test:");
  client.subscribe("test");//topic name="abc"

}

void loop() {
  client.loop();
}
ESP8266 AS SUBSCRIBER OUTPUT:

If your publisher is ESP8266 or NodeMCU, it doesn’t mean your Subscriber should be only ESP8266 or NodeMCU. Subscriber can be anything such as Python Script , Windows command prompt , Linux terminal , Raspberry PI terminal , Java Program etc .

Here Windows command prompt is used as subscriber to subscribe data from ESP8266 or NodeMCU .
WINDOWS PROMPT AS SUBSCRIBER:

COMMON DOUBTS OR PROBLEMS

1)Why am I able to send only 128 bytes?

This is because the default payload size in PUBSUB library is 128 bytes.

2)How to increase default payload size?

In pubsubclient-master library default Payload size is 128 bytes. If you want to transmit higher length payload then you need to modify PubSubClient.h . If Your payload size is higher than the Maximum Payload size mention in library, MQTT Packet won’t Publish. If you want to send Payload higher than 128 bytes , Please modify PubSubClient.h. To modify PubSubClient.h please navigate to following path

This PC -> Documents -> Arduino -> libraries -> pubsubclient-master -> src -> PubSubClient.h

Modify the following line in PubSubClient.h. Default is 128 bytes.
#define MQTT_MAX_PACKET_SIZE 128

Example: If you want to send maximum 1000 bytes payload or data, then you will modify as follows
#define MQTT_MAX_PACKET_SIZE 1000
After modification, please save the PubSubClient.h file and upload the code. Practical modification is shown below.

Please click on the below link to become master in MQTT.

Master MQTT Protocol

You may also like...

6 Responses

  1. John Smith says:

    This is probably the best tutorials about nodemcu and MQTT that I have seen. You give an excellent explanation that I have not seen in other tutorials. Great job!! I do have a question maybe you can help me with. I want to implement a solution using a nodemcu that goes to deep sleep for 30 minutes, wakes up and I checks for new mqtt messages that it’s subscribed to and then performs an action based on the value received. Have you done anything like this? I know that you have to specify the QoS
    When using deep sleep usually you don’t run the loop() method as the nodemcu goes to sleep at the end of the setup() Thanks again for this post.

    • admin says:

      First all John thanks for appreciating our work.

      Yes, whatever you are saying that can be done. In order to do that you need implement retain functionality of mqtt.

      Modify the following code in MQTTPOST() function in above above publisher code.

      client.publish(“test”,attributes,true);

      Once you modify this. MQTT broker will hold the last message sent by MQTT publisher wheather there is mqtt subscriber or not.

      As soon as MQTT subscriber is connected, MQTT broker Wii deliver last received message.

      So when you come out of sleep mode , connect to mqtt broker and you will automatically receive the last message published by mqtt publisher.

  2. Ahmed Abdelazim says:

    Really man this is the best tutorials about nodemcu and MQTT that I have found it tell now.thanks man really you have a great and simple method to explain any thing, i have a question for you, i want to connect more than 20 nodemcu to mosquitto, every nodemcu will subscribe one topic specially for it, so how i can do it on the same mosquito port”1883″, and how to set pass and user name to mosquitto . thanks again for this tutorials.

    • admin says:

      First of all thanks for reading this post and we are happy that you like this post.

      You have 20 subscribers right which all are listening or subscribing different topic right! Means you also have 20 publishers.

      It is simple, use above publisher and subscriber code only thing you have to change is the topic name.

      Give me some time I will let you know how to add user name and password to mqtt broker.

    • admin says:

      Please visit the below link to know how to add username and password to MQTT Broker
      mosquitto usrname password

  3. Jan Whilliam Tarigan says:

    what if i want to add the serial communication function to arduino.
    please provide an explanation of that.
    thank you

Leave a Reply