06/06/2019

Connecting ESP8266 to MQTT broker

By snorlaxprime

So what is MQTT, according to mqtt.org, it is a connectivity protocol used to connect machine to machine, used for Internet of Things (IoT). It was designed as an extremely light weight publish/subscribe messaging transport. In short it is the messaging designed for Internet of Things devices to allow robust connectivity when faced with challenged bandwidth limitation, and power consumption. It stands for Message Queuing Telemetry Transport.

MQTT how it works

The concept of MQTT is a Publish/Subscribe system. This means that there is at least one system that publish a message on a topic and there is at least one system that subscribe to the “topic” to receive “messages”. The “Messages” are information that are being exchange between the devices. “Topic” are series of strings separated by a forward slash (/), each topic is separated by the forward slash.

MQTT Broker

MQTT Broker is responsible for receiving messages and forwarding the messages to the devices that are interested (Subscribed) to the topic. There are a few MQTT Broker that you can use. In this example we will use the one called https://shiftr.io/try.

You can also installed your own message broker (Mosquitto broker) into Raspberry Pi to relay all the messages for your home automation projects.

Getting Started with MQTT Broker

Start by getting a free account with shiftr.io, then follow the documentation to create the Namespace and Token. The Token is username and password pair that will be used to authenticate the client, the one that will publish or subscribe to the messages. The token will be used in the following section of the code:

const char* user = "tokenusername";
const char* user_password = "tokenpassword";

You will need to download the MQTT library to send the message to the MQTT broker. The initialisation is done using the following code:

#include <MQTT.h>
MQTTClient client;

During the setup you will need to connect the onMessage event to the function that be executed when the message is received, this is done with the following code:

void setup() {  
...
client.begin(thehostname, net);
client.onMessage(messageReceived);
...
}

In the loop section of the code, you will need to execute the client.loop() function and the following code will try to connect to the message broker and at the same it will publish “Alive” message to the “/hello” topic.

void loop() {
client.loop();
if (!client.connected()) {
connect();
}
// publish a message roughly every second.
if (millis() - lastMillis > 1000) {
lastMillis = millis();
client.publish("/hello", "Alive");
}

}

Here are the connect() function, which will attempt to connect to the WiFi and upon connection will subscribe to the “/hello” topic.

void connect() {
Serial.print("checking wifi…");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.print("\nconnecting…");
while (!client.connect(id, user, user_password)) {
Serial.print(".");
delay(1000);
}
Serial.println("\nconnected!");
client.subscribe("/hello");
// client.unsubscribe("/hello");
}

Here are the full source code from the example above:

// MQTT Test client
//
// 128x64 OLED pinout:
// GND goes to ground
// Vin goes to 3.3V
// Data to I2C SDA (GPIO 4)
// Clk to I2C SCL (GPIO 2)
// Add MQTT
#include <TimeLib.h>
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <SSD1306.h>
#include <SSD1306Wire.h>
#include <MQTT.h>

char ssid[] = "ssidname"; // your network SSID (name)
char pass[] = "ssidpassword"; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
WiFiClient net;
MQTTClient client;
unsigned long lastMillis = 0;
// MQTT info
const char* thehostname = "broker.shiftr.io";
const char* user = "tokenusername";
const char* user_password = "tokenpassword";
const char* id = "ESP8266";
SSD1306 display(0x3c, 4, 2); //0x3d for the Adafruit 1.3" OLED, 0x3C being the usual address of the OLED
void connect() {
Serial.print("checking wifi…");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(1000);
}
Serial.print("\nconnecting…");
while (!client.connect(id, user, user_password)) {
Serial.print(".");
delay(1000);
}
Serial.println("\nconnected!");
client.subscribe("/hello");
// client.unsubscribe("/hello");
}
void messageReceived(String &topic, String &payload) {
Serial.println("incoming: " + topic + " - " + payload);
}
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(115200);
//Setup Rest Client
WiFi.begin(ssid, pass);
Wire.pins(4, 2); // Start the OLED with GPIO 4 and 2 on ESP-01
Wire.begin(4, 2); // 4=sda, 2=scl
display.init();
display.flipScreenVertically();
display.drawString(0, 24, "Connected.");
display.display();
client.begin(thehostname, net);
client.onMessage(messageReceived);
connect();
delay(1000);
}
int timer =0;
void loop() {
client.loop();
if (!client.connected()) {
connect();
}
// publish a message roughly every second.
if (millis() - lastMillis > 1000) {
lastMillis = millis();
client.publish("/hello", "Alive");
}
//delay(1000);
}

If everything goes well, you should be able to see the message being published to the topic that you are monitoring. In the example above the message will go from the ESP8266 device to the /hello topic.

The message being published is “Alive” message, as shown at the top left hand corner. This will keep being published every seconds.

That’s all for now, I hope this post is useful as an introduction to the MQTT. Please share this if you like, or provide some comments. The next step from here is to modify the Temperature sensor to use the MQTT, stay tune if you would like to know about this.