MQTT and ESP8266

MQTT

In the previous tutorial you have learned how to set up and use the ESP8266 chip to collect data from your sensors, connect to the internet over Wi-Fi and send those values to Thingspeak over HTTP protocol. Also, you have seen how you can graph that data, and how you can extend your system with some features that Thingspeak offers.  

Let’s take a look at the program from the previous example. Our device connects to the server, sends POST request with the sensor value, disconnects from the server, waits for 15 seconds and repeats the same process over and over. Each time there is something to be sent, our device has to reestablish connection to the server – one connection per one data write. On the other hand, if we want to transfer data from the server to the device, the only way to achieve this is that our device constantly connects to the server and checks if there are any updates. It is clear that this is not the most efficient way of transferring data. HTTP protocol uses request – response method of communication. If you take a look at the requests we send and responses we get, you will see that there are a lot of additional headers that are transferred. All kind of information about statuses that we are not usually interested in. HTTP is good for large data transfers (websites for example) but it is clear that it is not the most efficient protocol when we want to send just a few bytes of data – our sensor values. Also, it is not that fast. This is why we use MQTT protocol.

 

MQTT is lightweight and fast. It takes very few bytes to connect to the server and connection can be kept open all the time. Communication consumes less data and time that the HTTP protocol – advantages are clear. How does the MQTT work? The whole system consists of many clients and one broker. Our devices act as clients. Clients can be our cellphones or lap tops too. Each client communicates to a broker only, clients don’t communicate among themselves. The whole system is based on publish – subscribe method of communication. Each client can be a publisher which publishes (sends) messages, subscriber which listens to incoming messages, or both at the same time. Broker is a kind of server whose task is to accept published messages from publishers and forward them to subscribers.

 

Publishers and subscribers

 

So, how does the broker know which messages it should forward to each subscriber? Obviously, it would be too messy that each subscriber receives each message, especially if there are many publishers in the system. The answer is topics. Each publisher publishes to a certain topic or multiple topics, and each subscriber subscribes to one or multiple topics. Topics have tree structure, separated with slashes. Let’s say I have temperature sensors at several places, and I am interested in temperature value in my garden. I use my cellphone and subscribe to a topic Sensors/Garden/Temperature. Device that measures temperature in the garden publishes the temperature value to the same topic and at that time my cellphone receives the message. Let’s say I also have sensors for humidity, alarm sensors and some others. What if I want to check all sensors in my garden with one subscription? I can use wildcards – I subscribe to a topic Sensors/Garden/#. What if I want to check temperature sensor at each place (garden, living room, basement…) – I also use a wild card and subscribe to a topic Sensors/+/Temperature. Wildcards are one more convenience that MQTT offers. MQTT has other features like Quality of Service (guaranteeing message delivery), Last Will, Retained Messages etc. Here is a good resource to learn more about MQTT protocol.

 

PubSubClient Library

How can we use the MQTT with the ESP8266? Fortunately, there is a library that gives us that possibility. We have to install that library. Go to https://github.com/knolleary/pubsubclient and download the zip file of PubSubClient library. To add a library to your Arduino IDE, go to Sketch > Include Library > Add .ZIP library and select the downloaded file. You are ready to use MQTT protocol with the ESP8266.

Let’s see how to use the MQTT protocol with the ESP8266 on a practical example. We will consider a simple and classic example of turning on and off an LED. By sending appropriate message from our PC or cellphone, we want to control our LED.

You already know that we need a broker in order to communicate over MQTT. The simplest way for the beginning is to use a public broker, such as http://broker.mqtt-dashboard.com. It is handy that you can go to the broker page and monitor all published messages in a dashboard. This is a good way to verify that everything works. Each time the ESP8266 connects to the broker, it will publish a notification message.

If you want to use your PC as a client, you can use MQTT lens. For the cellphone, search for an MQTT client app. I used this one for my Android cellphone. You have to configure the connection. Enter the broker domain name and port number (1883 by default). After you establish the connection, you are ready to publish and subscribe to topics. You can start publishing ‘on’ and ‘off’ messages to the ESP8266/LED status (the same the ESP8266 subscribes to) and you should see your LED (attached to the pin 4 in this example) turning on and off. Subscribe to the ESP8266/connection status (using spaces in topics like in this case is not a good practice!) to receive connection status message published by the ESP8266.

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

const char* ssid = "";
const char* password = "";

//const char* mqtt_server = "test.mosquitto.org";
//const char* mqtt_server = "iot.eclipse.org";
const char* mqtt_server = "broker.mqtt-dashboard.com";

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  
  pinMode(4,OUTPUT);
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  reconnect();
}

void setup_wifi(){

  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.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]);
  }
  
  if((char)payload[0] == 'o' && (char)payload[1] == 'n') //on
    digitalWrite(4,HIGH);
  else if((char)payload[0] == 'o' && (char)payload[1] == 'f' && (char)payload[2] == 'f') //off
    digitalWrite(4,LOW);
    
  Serial.println();
}

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("ESP8266/connection status", "Connected!");
      // ... and resubscribe
      client.subscribe("ESP8266/LED status");
    } 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();
}

 

MQTT lens

You will see some other public brokers under comments in the code. You must have noticed that when using the public broker connection is not stable. Moreover, data transfer is not secure. Although in some cases the public broker would work just fine for us, this option is not always acceptable. One solution is to install a broker on your machine locally. I installed open-source broker called Mosquito on my Windows machine. You can find instruction how to install it here. You have to use your IP address instead of a domain name. The problem with this is that your computer has to be constantly on. Using a smaller computer such as Raspberry Pi would be a better option for this purpose.

Now you know how you can implement the MQTT on the ESP8266 and exploit its features. In the next tutorial we will use the MQTT protocol to connect our devices to IBM’s powerful platform called Bluemix, which will allows us to quickly build interesting and useful IoT applications.

Lessons of this Series

Trending

Newsletter

Subscribe to our newsletter for good news, sent out every month.

Tags