How to Building and Configuring MQTT Server with ESP8266

ESP8266 and MQTT

Today in this tutorial, we will see how ESP8266 modules can communicate with each other. through the  Message Queue Telemetry Transport (MQTT Server).


≡ Required Component :

  1. NodeMcu8266
  2. Breadboard
  3. Connecting wire
  4. Breadboard Power Supply Module

Software Required:


The latest version of the Arduino IDE, which you can get from:
http://www.arduino.cc/en/Main/Software

Follow this link to How to  Complet  Software Setup Installing the Arduino IDE for the ESP8266 | IoT Tutorial


≡ What is Message Queue Telemetry Transport (MQTT)?


The Message Queue Telemetry Transport (MQTT) is a simple and easy messaging protocol that provides resource-constrained network clients with a simple way to distribute telemetry information. This messaging protocol, which uses a publish/subscribe communication design, and is used for machine-to-machine (M2M) communication and assumes a significant job in the internet of things (IoT).

The features of MQTT :

Data agnostic: MQTT can transport all kind of sensor data,

Lightweight: and bandwidth-efficient: The Smallest frame is just 2 bytes lengthy.

Provide QoS: Three Quality of Service (QoS) levels Runs on top of the TCP/IP stack

Simple to develop: Clients exist for all operating systems and programming languages

Central broker: Can connect different devices without having to worry about compatibility

Session awareness: Gives identity-based access for subscriptions Soft subscription topics

Security:

Message Queue Telemetry Transport (MQTT) is a protocol that is working over the TCP/IP so you can use it to encrypt the data with TLS/SSL and to have a stable connection between clients.


≡ Basic specification of Message Queue Telemetry Transport (MQTT):


Broker: It is a software application that receives messages from clients, and routes the messages according to the subscriber’s demands.

Client: It is a tool that can publish a message or can receive a message or both.

Topic: It is a line that is used by the broker to clarify information for all connected clients. It is sent by clients to the broker in a subscription request to express the desire in receiving messages published by other clients. It is conducted by the clients when publishing messages to any other client that subscribed on the same topic.
Publish: Action of conveying a message to different clients on a particular topic.

Subscribe: Action of informing the broker about an interest in receiving future messages published by other clients on that topic. A client can subscribe to many topics.

Unsubscribe: Action of a client that is reporting the broker not to send messages to the designated point.


≡ Introducing Mosquitto broker:


Mosquitto is an open-source MQTT broker that executes the MQTT v3.1 also MQTT v.3.1.1 types and provides a lightweight way to carry messages, providing publish and subscription for low power sensors, mobile devices, embedded computers, and microcontrollers.


≡ ESP8266 and MQTT


To using the ESP8266 as a client for sending data to a broker you will require a library that gives MQTT support. Simply you can use the PubSubClient library, which can be installed like other libraries. Go to Sketch | Include Library | Manage Libraries And search for the PubSubClient library and click Install as in the following screenshot:

ESP8266 and MQTT


≡ Publishing data from the ESP8266  Code:


New in the Arduino IDE and paste in the following code

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

// Update these with values suitable for your network.

const char* ssid = "Mechatronics";
const char* password = "Password";
const char* mqtt_server = "broker.mqtt-dashboard.com";

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE	(50)
char msg[MSG_BUFFER_SIZE];
int value = 0;

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is active low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("Publishing data from the ESP8266", "hello world");
      // ... and resubscribe
      client.subscribe("Publishing data from the ESP8266");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {

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

  unsigned long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  }
}

≡ Publishing data from the ESP8266  Code Overview:


Add the ESP8266WiFi library and the PubSubClient one:

#include <ESP8266WiFi.h>

#include <PubSubClient.h>

Renew those with values proper for your network.. If your server has an FQDN name such as broker.mqtt-dashboard.com and  registered into the DNS, then alternatively of the IP address in mqtt_server you can use the FQDN name:

const char* ssid = "Mechatronics";
const char* password = "Password";
const char* mqtt_server = "broker.mqtt-dashboard.com";

add Instantiate a WiFiClient and give it to the PubSubClient:

WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE	(50)
char msg[MSG_BUFFER_SIZE];
int value = 0;

Now The setup() function will begin joining the ESP8266 to the Wi-Fi network by calling the setup_wifi() function ,set the MQTT server, and port utilizes via the client.Setserver() function:

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}
void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

If keep-alive packets from the MQTT server to the ESP8266 module  lost and the connection interrupted. the reconnect() function will try to join again to the MQTT server. This reconnect function is also utilized as a first connection to the server. connecting to the MQTT server the ESP8266 will publish a message “Hello world, I am ESP8266!” on the fromEsp8266 topic:

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "ESP8266Client-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("Publishing data from the ESP8266", "hello world");
      // ... and resubscribe
      client.subscribe("Publishing data from the ESP8266");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

The loop function will be checking for connectivity with the MQTT broker and reconnect to it if there is a problem with the connection. and every five  seconds will publish a message on the fromEsp8266 topic:

void loop() {

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

  unsigned long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  }
}

After compiling and uploading the code to the ESP8266 module. The messages sent by the ESP8266 module  shown in the serial monitor:

ESP8266 and MQTT


≡ Receiving MQTT messages in the ESP8266 Code:


#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* wifi_network = "YOUR_WIFI_SSID";

const char* wifi_pass = "YOUR_WIFI_PASSWORD";

const char* mqtt_serv_address = "192.168.1.116";

const int mqtt_port_number = 1883;

WiFiClient espClient;

PubSubClient client(espClient);

long lastMsg = 0;

char msg[50];

int value = 0;
void setup() {

Serial.begin(115200);

setup_wifi();

client.setServer(mqtt_serv_address, mqtt_port_number);

}

void setup_wifi() {

delay(10);

// We start by connecting to a WiFi network

Serial.println();

Serial.print("Connecting to ");

Serial.println(wifi_network);

WiFi.begin(wifi_network, wifi_pass);

while (WiFi.status() != WL_CONNECTED) {WiFi.begin(wifi_network, wifi_pass);

Serial.print(".");

delay(5000);

}

Serial.println("");

Serial.println("WiFi connected");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());

}

void reconnect() {

// Loop until we're reconnected

while (!client.connected()) {

Serial.print("Attempting MQTT connection...");

// Attempt to connect

if (client.connect("ESP8266Client"))

{

Serial.println("connected");

// Once connected, publish an announcement...

client.publish("fromEsp8266", "Hello world, I am ESP8266!");

} else {

Serial.print("failed, rc=");

Serial.print(client.state());

Serial.println(" try again in 5 seconds");

// Wait 5 seconds before retrying

delay(5000);

}

}

}

void loop() {

if (!client.connected()) {

reconnect();

}

client.loop();

long now = millis();

if (now - lastMsg> 2000) {

lastMsg = now;

++value;

snprintf (msg, 75, "Hello world #%ld", value);

Serial.print("Publish message: ");

Serial.println(msg);

client.publish("fromEsp8266", msg);

}

}


≡ Receiving MQTT messages in the ESP8266 Code Overview:


Now let’s publish a message using mosquitto_pub and get it in the ESP8266.  the ESP8266 needs to subscribe to the same topic on which mosquitto_pub will publish the information.  if call the head outdoor or light and it will print on 0 or 1 values. If the ESP8266 receives the value as 1, it will turn on a LED connected to GPIO 12 and if it will receive a 0, it will turn off that LED:

#include <ESP8266WiFi.h>

#include <PubSubClient.h>

Now Update these with values suitable for your network:

const char* wifi_network= "YOUR_WIFI_SSID";

const char* password = "YOUR_WIFI_PASSWORD";

const char* mqtt_serv_address = "YOUR_MQTT_SERVER_IP"; const int mqtt_port_number = 1883;

#define OUTDOOR_LIGHT 12

WiFiClient espClient;

PubsubClient client(espClient);

long lastMsg; = 0;

Now Begin the connection to the Wi-Fi network and fixed the title of the work that inquired when a message got from the MQTT broker, as follows:

void setup() {

pinMode(OUTDOOR_LIGHT, OUTPUT); // Initialize the BUILTIN_LED pin as an output

Serial.begin(115200);

setup_wifi();

client.setServer(mqtt_serv_address, mqtt_port_number);

client.setCallback(callback);

}

Connect to the Wi-Fi network:

void setup_wifi() {

delay(10);

// We start by connecting to a WiFi network

Serial.println();

Serial.print("Connecting to ");

Serial.println(wifi_network);

WiFi.begin(wifi_network, password);

while (WiFi.status() != WL_CONNECTED) {

WiFi.begin(wifi_network, password);

Serial.print(".");

delay(5000);

}

Serial.println("");

Serial.println("WiFi connected");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());

}

If a message will come in the ESP8266 MQTT client the function that will be asked is callback(), with parameters argument including the name of the topic on which topic the message came, If that module subscribed to multiple topics, the actual content of the message, and the length of the message:

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

Serial.print("Message arrived [");

Serial.print(topic);

Serial.print("] ");

for( int i = 0; i < msg_length; i++) {

Serial.print((char)payload[i]);

}

Serial.println();

// Switch on the LED if an 1 was received as first character

if ((char)payload[0] == '0') {

digitalWrite(OUTDOOR_LIGHT, LOW); // Turn the LED off

} else {

digitalWrite(OUTDOOR_LIGHT, HIGH); // Turn the LED on

}

}

Now you can see The reconnect() function. more oversubscribed to the outdoor or light topic from which it will take the messages. if the connection with the broker lost it will try to connect to it every five seconds.

void reconnect() {

// Loop until we're reconnected

while (!client.connected()) {

Serial.print("Attempting MQTT connection...");

// Attempt to connect

if (client.connect("ESP8266Client"))

{

Serial.println("connected");

client.subscribe("outdoor/light");

} else {

Serial.print("failed, rc=");

Serial.print(client.state());

Serial.println(" try again in 5 seconds");

// Wait 5 seconds before retrying

delay(5000);

}

}

}

The loop() function will publish the value of the GPIO 12, which is really the state of the outdoor light:

void loop() {

if (!client.connected()) {

reconnect();

}

client.loop();

long now = millis();

if (now - lastMsg> 2000) {

lastMsg = now;

String light_state;

if(digitalRead(OUTDOOR_LIGHT) == HIGH)

light_state = "ON";

else

light_state = "OFF";

Serial.print("Publish message: ");

Serial.println(light_state);

client.publish("outdoor/light/status", light_state.c_str());

}

}

Visit to get more tutorials on IoT project

INTERNET OF THINGS

 291 total views,  3 views today