owned this note
owned this note
Published
Linked with GitHub
---
tags: fabacademy, mdef, workshops
---
# MQTT
MQTT was developed by Andy Stanford-Clark (IBM) and Arlen Nipper (Eurotech; now Cirrus Link) in 1999 for the monitoring of an oil pipeline through the desert.
The goals were to have a protocol, which is bandwidth-efficient and uses little battery power, because the devices were connected via satellite link and this was extremely expensive at that time.
The protocol uses a publish/subscribe architecture wich is event-driven and enables messages to be pushed to clients. The central communication point is the MQTT broker, it is in charge of dispatching all messages between the senders and the rightful receivers. Each client that publishes a message to the broker, includes a topic into the message.
The topic is the routing information for the broker. Each client that wants to receive messages subscribes to a certain topic and the broker delivers all messages with the matching topic to the client. Therefore the clients don’t have to know each other, they only communicate over the topic.
This architecture enables highly scalable solutions without dependencies between the data producers and the data consumers.
[source](https://www.hivemq.com/blog/how-to-get-started-with-mqtt)
![](https://www.survivingwithandroid.com/wp-content/uploads/2016/10/mqtt_publisher_subscriber-1.png =500x)
A topic is a simple string defined by the user that can have more hierarchy levels, which are separated by a slash.
```
mdef/input/team1/temperature
mdef/ouput/team2/motor
```
Wilcards can also be used in sigle leves ej. `mdef/input/+/temperature` will return **temperatures of all teams**.
Or in multilevels: `mdef/output/#` will return **all** outputs from **all teams**.
## MQTT on Arduino IDE
* Install MQTT libray:
Open the **Library manager** in Arduino menu _Sketch -> Include Library -> Manage Libraries_ and search for the **PubSubClient** library, install it.
![](http://i.imgur.com/35uzfQo.png =600x)
You can find the full API documentation for the _PubSubClient_ library [here](https://pubsubclient.knolleary.net/api.html)
For the first test you can copy/paste the [code example](#Code-example) in this document.
### Setup WiFi
Change **WiFi settings** and mqtt_server address.
```=c
const char* ssid = "Sensors Network X";
const char* password = "sensors4ever";
const char* mqtt_server = "192.168.10.235";
```
### Receiving data
* If you are **suscribing to a topic** (for actuator nodes) change subscription topic name inside the reconnect function
```clike=
// SET THE TOPIC TO SUBSCRIBE HERE
client.subscribe("testing");
```
* And modify the callback function to control your actuator.
```clike=
// USE RECEIVED DATA HERE
if (strPayload.toInt() > 5) digitalWrite(LED_BUILTIN, LOW);
else digitalWrite(LED_BUILTIN, HIGH);
```
### Publishing data
* If you are publishing data (sensor nodes) change the topic, and modify the code in the loop function to get your sensor reading and publish it.
```clike=
// READ YOUR SENSOR DATA HERE
float value = analogRead(A0);
// Send value as characters
char msg[50];
snprintf (msg, 50, "%f", value);
Serial.print("Publish message: ");
Serial.println(msg);
// SET THE TOPIC TO PUBLISH HERE
client.publish("outTopic", msg);
```
## Code example
```clike
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// SETUP WIFI CREDENTIALS
const char* ssid = "Sensors Network X";
const char* password = "sensors4ever";
const char* mqtt_server = "192.168.10.235";
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
pinMode(BUILTIN_LED, OUTPUT);
Serial.begin(9600);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
// PUT THE CODE TO START YOUR SENSORS HERE
}
void loop() {
if (!client.connected()) reconnect();
client.loop();
// Publish every 1000 milliseconds
if (millis() % 1000 == 0) {
// READ YOUR SENSOR DATA HERE
float value = analogRead(A0);
// Send value as characters
char msg[50];
snprintf (msg, 50, "%f", value);
Serial.print("Publish message: ");
Serial.println(msg);
// SET THE TOPIC TO PUBLISH HERE
client.publish("outTopic", msg);
}
}
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();
String strPayload = String((char*)payload);
// Serial.println(strPayload.toFloat());
// Serial.println(strPayload.toInt());
// USE RECEIVED DATA HERE
if (strPayload.toInt() > 5) digitalWrite(LED_BUILTIN, LOW);
else digitalWrite(LED_BUILTIN, 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");
// SET THE TOPIC TO SUBSCRIBE HERE
client.subscribe("testing");
} 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_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());
}
```