MQTT on ESP32- Publish- Subscribe Beginners Guide

Description

MQTT is a lightweight publish-subscribe-based messaging protocol.

  • It is quicker (faster) than other request-response based APIs like HTTP.
  • It is developed on the base of the TCP/IP protocol.
  • It allows remote location devices to connect, subscribe, publish, etc. to a specific topic on the server with the help of a message broker.
  • MQTT Broker/Message broker is a module in between the sender and the receiver. It is an element for message validation, transformation, and routing.
  • The broker is responsible for distributing messages to the interested clients (subscribed clients) of their interested topic.

 

For example, if the temperature sensor publishes the temperature data (message) on the topic “temperature” then interested clients who have subscribed to the “temperature” topic get that published temperature data as shown in the above figure.

MQTT is widely used in IoT (Internet of Things) embedded applications, where every sensor is connected to a server, and we have access to control them over the internet.

ESP32 is an open-source IoT platform. It is a firmware which runs on ESP32 series of SoCs from Espressif Systems. It has onboard 2.4 GHz Wi-Fi, Bluetooth, and Bluetooth LE module available through which IoT applications become easy to build.

The MQTT Client module of ESP32 is according to version 3.1.1 of the MQTT protocol. Make sure that your broker supports and is correctly configured for version 3.1.1. let’s see the functions used for MQTT on ESP32.

MQTT Packet Formation

MQTT uses many packet formats that used to connect to the server and subscribe or publish to the topic on the server.

Refer below link for MQTT OASIS standard. It will help to understand MQTT packet formations.

http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718027

Example

Let’s write an Arduino program to configure ESp32 as MQTT Client to sending temperature and humidity using DHT11 sensor form to remote location from the Adafruit dashboard.

Here, we will be using a DHT11 library by Mark Ruys from GitHub.

Download this library from here.

Here we are using the Adafruit server for MQTT Client demo purpose.

In the IOT platform, Adafruit IO Dashboard allows us to visualize and provides control over the connected devices to the internet. Anyone can visualize and analyze live data from their sensor devices. To learn more and start with Adafruit IO Dashboard refer link https://learn.adafruit.com/adafruit-io-basics-dashboards/creating-a-dashboard

Just sign up and create a dashboard. After the successful creating of the dashboard, we will get the AIO key which is later used to access feed data.

Once we created a dashboard on Adafruit we can add various blocks that can be used to control devices as well as monitor the status of devices. To see more about blocks, refer link https://learn.adafruit.com/adafruit-io-basics-dashboards/adding-blocks

ESP32 interfaced with DHT11

 

Install required libraries

First, refer to Getting Started with ESP32 using Arduino IDE if you are not installed ESP32 board packages in Arduino IDE.

Here we are using Adafruit libraries for the above example. We will need to install the Adafruit IOAdafruit MQTT, and ArduinoHttpClient libraries using the Arduino Library Manager.

Open the Arduino IDE and navigate to Sketch -> Include Library -> Manage Libraries…

 

The library Manager window will pop up. Now enter Adafruit IO Arduino into the search box, and click Install on the Adafruit IO Arduino library option to install version 4.2.0 or higher.

Now enter Adafruit MQTT into the search box, and click Install on the Adafruit MQTT library option to install version 2.4.2 or higher.

Now open example of Adafruit mqtt io dashboard. To open it navigate to File -> Examples -> Adafruit MQTT Library -> adafruitio_secure_esp32

Now edit the Wi-Fi and Adafruit io credentials with correct information of example as shown in below image.

We have modified the mqtt_esp32 example as per our above example in below

Arduino Sketch for MQTT Client

/***********************************************************************
 Adafruit MQTT Library ESP32 Adafruit IO SSL/TLS example

 Use the latest version of the ESP32 Arduino Core:
   https://github.com/espressif/arduino-esp32

 Works great with Adafruit Huzzah32 Feather and Breakout Board:
   https://www.adafruit.com/product/3405
   https://www.adafruit.com/products/4172

 Adafruit invests time and resources providing this open source code,
 please support Adafruit and open-source hardware by purchasing
 products from Adafruit!

 Written by Tony DiCola for Adafruit Industries.
 Modified by Brent Rubell for Adafruit Industries
 MIT license, all text above must be included in any redistribution
 **********************************************************************/
#include <WiFi.h>
#include "WiFiClientSecure.h"
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include "DHT.h"
DHT dht;
/************************* WiFi Access Point *********************************/

#define WLAN_SSID "****ssid****"
#define WLAN_PASS "****pass****"

/************************* Adafruit.io Setup *********************************/

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  8883  // Using port 8883 for MQTTS
// Adafruit IO Account Configuration
// (to obtain these values, visit https://io.adafruit.com and click on Active Key)
#define AIO_USERNAME "aioname"
#define AIO_KEY      "724b81xxxxxxxxxxxxx61da2163bxxxx"

/************ Global State (you don't need to change this!) ******************/

WiFiClientSecure client;  // WiFiFlientSecure for SSL/TLS support

// 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);

// io.adafruit.com root CA
const char* adafruitio_root_ca = \
   "-----BEGIN CERTIFICATE-----\n" \
   "MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\n" \
   "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" \
   "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n" \
   "QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\n" \
   "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n" \
   "b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n" \
   "9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\n" \
   "CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\n" \
   "nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\n" \
   "43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\n" \
   "T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\n" \
   "gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\n" \
   "BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\n" \
   "TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\n" \
   "DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\n" \
   "hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\n" \
   "06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\n" \
   "PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\n" \
   "YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\n" \
   "CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n" \
   "-----END CERTIFICATE-----\n";

/****************************** Feeds ***************************************/

// Setup a feed called 'test' for publishing.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
Adafruit_MQTT_Publish humidity = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Humidity");
Adafruit_MQTT_Publish temperature = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Temperature");

/*************************** Sketch Code ************************************/
void setup() {
 Serial.begin(115200);
 delay(10);
 dht.setup(0); //Connect DHT11 Output to GPIO0 Pin of ESP32
 Serial.println(F("Adafruit IO MQTTS (SSL/TLS) Example"));

 // Connect to WiFi access point.
 Serial.println(); Serial.println();
 Serial.print("Connecting to ");
 Serial.println(WLAN_SSID);
 delay(1000);
 WiFi.begin(WLAN_SSID, WLAN_PASS);
 delay(2000);

 while (WiFi.status() != WL_CONNECTED) {
   delay(500);
   Serial.print(".");
 }
 Serial.println();
 Serial.println("WiFi connected");
 Serial.println("IP address: "); Serial.println(WiFi.localIP());
 client.setCACert(adafruitio_root_ca);
}

void loop() {
 // 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.
 MQTT_connect();
 delay(dht.getMinimumSamplingPeriod()); /* Delay of amount equal to sampling period */
 float Humidity_Value = dht.getHumidity();/* Get humidity value */
 float Temperature_Value = dht.getTemperature();/* Get temperature value */

 if (! humidity.publish(Humidity_Value)) //Publish Humidity Reading!
 { 
   Serial.println(F("Failed"));
 } 
 else {
   Serial.print("Humidity Value = ");
   Serial.println(Humidity_Value);
 }
 
 if (! temperature.publish(Temperature_Value)) //Publish Temperature Reading!
 {
   Serial.println(F("Failed"));
 } 
 else {
   Serial.print("Temperature Value = ");
   Serial.println(Temperature_Value);
 }
 delay(2000);
}

// 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(5000); // wait 5 seconds
      retries--;
      if (retries == 0) {
        while (1); // basically die and wait for WDT to reset me
      }
 }
 Serial.println("MQTT Connected!");
}

Output


Components Used

DHT11
DHT11 is a single wire digital humidity and temperature sensor, which gives relative humidity in percentage and temperature in degree Celsius.
1

Downloads

ESP32_MQTT Download
Ad