What is an MQTT?
The MQTT (MQ Telemetry Transport or previously known as the Message Queuing Telemetry Transport) is a light weight publish/subscribe protocol designed for M2M (Machine to Machine) telemetry in low bandwidth environments.
Initially MQTT was designed by IBM and Arcon in 1999 for Oil Pipeline Telemetry Systems over the satellites. Nowadays MQTT is one of the main messaging protocols of the Internet of Things.
MQTT is suitable for the transport of telemetry data ie., data from the sensors and actuators.
MQTT vs HTTP
HTTP is the most popular used messaging protocol but in recent years, HTTP has been slowly replaced by MQTT by the IoT developers. The reason is that MQTT is data-centric whereas HTTP is document centric. HTTP is a request-response protocol for client-server computing and does not go along with mobile devices.
Besides, in comparison to HTTP, MQTT Protocol ensures high delivery guarantees. There are 3 levels of Quality of Services:
– at most once: guarantees a best effort delivery.
– at least once: guaranteed that a message will be delivered at least once. But the message can also be delivered more than once.
– exactly once: guarantees that each message is received only once by the counterpart
MQTT is designed for TCP/IP networks. MQTT-SN which was specified in around 2013, and designed to work over UDP, ZigBee, and other transports.
MQTT Client
You need to assign addresses to the client you like to work with the messaging systems. For MQTTv3.1.1 there is client software available in almost all programming languages and for the main operating systems Linux, Windows, Mac from the Eclipse Paho project. Here is a link to the client comparison chart and download page.
MQTT Publish/Subscribe
In a publish/subscribe scheme, the client publisher publishes the data to the client subscriber which has subscribed to the publisher under a topic. For example, a client subscriber receives the data (sensor data) from the client publisher which contains the sensor data.
MQTT Broker
The MQTT broker is the heart of the publish/subscribe protocol. It acts as the hub for the protocol as it handles up to thousands of connected MQTT clients. The responsibility of the broker is to authenticate and authorize the client. It receives all the messages and filters them and sends the message to the corresponding subscriber. The broker also consists of session details and missed messages.
MQTT Connection
The MQTT client always connects and communicates with the broker. It is based on TCP/IP and both the client and the broker need to have this stack.
Basically, the client connects with the broker and communicates, so the client never connects with another client directly. To start the communication, the client sends a signal to the broker and the broker responds by sending the receiver signal.
Example Code for an IoT project
Let us take an example of NodeMCU and a piezoelectric sensor. The real-time sensor data is viewed using Adafruit.io by MQTT connection establishment.
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#define WLAN_SSID "xxxxx"
#define WLAN_PASS "xxxxxxxxx"
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883
#define AIO_USERNAME "xxxxxxxx"
#define AIO_KEY "5xxxxxxx"
int ledpin=D1;
int sensor =A0;
int analogvalue=0; // Current reading for analog pin
int threshold= 20;
int led= LOW;
WiFiClient client;
// or... use WiFiFlientSecure for SSL
//WiFiClientSecure client;
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
/****************************** Feeds ***************************************/
// i am going to publish my data alone. no need of subscription, so feed is enough
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
Adafruit_MQTT_Publish Piezo_voltage = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Piezo_voltage");
Adafruit_MQTT_Publish piezo_graph= Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/piezo_graph");
/*************************** Sketch Code ************************************/
void setup()
{
Serial.begin(9600);
pinMode (ledpin, OUTPUT);
// Connect to WiFi access point.
Serial.print("\n\n\nConnecting to ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(">>");
delay(5000);
}
Serial.println("WiFi connected");
//Serial.println("IP address: "); Serial.println(WiFi.localIP());
}
void loop()
{
MQTT_connect();
// Ensure the connection to the MQTT server is alive (this will make the first
// connection and automatically reconnect when disconnected). See the MQTT_connect
// function definition further below.
analogvalue = analogRead(sensor);
if (analogvalue>=threshold)
{
led=!led;
digitalWrite (ledpin, led);
float piezovoltage = analogvalue *(3.3 / 1024.0);
Serial.println(piezovoltage);
// Now we can publish stuff
Serial.print(F("\nSending piezo val "));
Serial.print(piezovoltage);
Serial.print("...");
if (! Piezo_voltage.publish(piezovoltage++)) {
Serial.println(F("\nFailed"));
} else {
Serial.println(F("\nOK!"));
}
if (! piezo_graph.publish(piezovoltage++)) {
Serial.println(F("\nFailed"));
} else {
Serial.println(F("\nOK!"));
delay (3000);
}
}
}
// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect()
{
int8_t ret;
// Stop if already connected.
if (mqtt.connected())
{
return;
}
Serial.print("Connecting to MQTT... ");
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(3000); // wait 3 seconds
retries--;
if (retries == 0) {
// basically die and wait for WDT to reset me
while (1);
}
}
Serial.println("MQTT Connected!");
}
The above code is compiled in Arduino IDE since NodeMCU is used here. The analog sensor detects the vibration and provides real-time data in Adafruit.io. In this project, the data is published from the client side, there is no necessity for the subscription. The information such as Authentication code, username, password, port number, and server port are needed. The real-time data is displayed in the form of graphs, text, slide and so on.
Useful Links: https://www.hivemq.com/blog/mqtt-essentials-part-3-client-broker-connection-establishment/