Introduction: Introduction to the MQTT Protocol With Ubidots - ESP32

About: Do you like technology? Follow my channel on Youtube and my Blog. In them I put videos every week of microcontrollers, arduinos, networks, among other subjects.

Today, we are going to introduce the Message Queue Telemetry Transport (MQTT), a very useful method for IoT (Internet of Things). The main use of the MQTT is to provide communication between machines, that is, Machine-to-Machine (M2M). Let us therefore take the first steps with the Ubidots IoT platform, exposing its use in an example with ESP32 LoRa. This also comes with a DHT22 sensor, allowing for the sending of information made with the MQTT protocol.

The MQTT protocol was created by IBM a long time ago and became widely used for IoT with cheap chips and easy access to the internet. In today’s specific example, we will use Ubidots. These are brokers, or rather, websites with a broker.

Step 1: Demonstration

Step 2: ​Resources Used

• ESP32 LoRa Display

• DHT22

• 4k7 ohm resistor

• Account (trial 30 days or paid) in Ubidots

• Protoboard

Step 3: MQTT Protocol

Publish and Subscribe

Step 4: Ubidots IoT Platform

Issues to be addressed

• Creating a new account

• Creating a new Dashboard

• Creating the ESP32-DHT Device

• Obtaining MQTT data - Device ID and Topic

• Obtaining MQTT data - Token

• Creation of variables in Ubidots

• Creating Humidity and Temperature Widgets

Step 5: Creating a New Account

To create an account, go to www.ubidots.com and click on SIGN UP

A. Company name

B. Project stage:

B - We chose the Discovery stage, indicating that it is a test project.

C. Create application

D. Your name

Your email

Create profile

E. Login

Password

Start Free Trial

Step 6: Creating New Dashboard

A. Click on create a new dashboard

B. Enter a name for the Dashboard and click

Step 7: Creating ESP32-DHT Device

A. Click Device Management and Devices

B. Click Create Device or +

C. A tab will open listing the tutorials on the help.ubidots site for the configuration and programming of microcontrollers according to their respective manufacturers. We'll create a blank device.

D. Fill in the fields

1. Device Name

2. Label (it will be part of the topic used by the MQTT Client)

3. Create

E. After the device is created, it will be listed on the device page as shown

1. Device Name

2. Last Updated

3. Device creation date / time

4. Organization relating to the device

5. Add organization and Delete device

Step 8: Obtaining MQTT Data - Device ID and Topic

A. Select the device

B. The Device ID values and the topic are written according to the images

The port used is 1883.

C. The token is obtained according to images 3.1 and 3.2

Step 9: Creating Variables

To create a widget that references a variable from a device, it must already be created on the device.

NOTE: Variables are created automatically by Ubidots after a Json upload, but for this, it is necessary to connect the ESP32 at least once. To reference the widgets without having to connect the ESP, we must follow these steps.

A. In Devices, select the device

B. Click Add Variable, and then click Raw.

Note: Define the same Source Code Labels (in the MQTT_Client.h file)

C. Enter the label (VARIABLE_LABEL_TEMPERATURE)

D. Repeat the steps for the humidity variable

(VARIABLE_LABEL_HUMIDITY)

Step 10: Creating Widgets

A. Go to the dashboards page

B. Click one of the buttons

Step 11: Creating Widgets - Temperature

A. Select the Thermometer option

B. Click Add Variables

C. Follow the steps to select the temperature variable

D. Click Confirm

Step 12: Creating Widgets - Humidity

A. Add another widget

B. Select the Tank option

C. Click Add Variables

D. Select ESP32-DHT, click on humidity, and then confirm

E. Finally, click on confirm

F. The Humidity Widget will appear below the temperature

G. You can arrange by dragging the windows

Step 13: Assembly

Declarations and variables

#include <Arduino.h>
#include <SimpleDHT.h> //Biblioteca referente ao DHT22 #include "displayESP32LoRa.h" //Arquivo com as funções referentes ao display lora #include "MQTT_Client.h" //Arquivo com as funções de mqtt float temperature; //Temperatura que será obtida pelo sensor DHT float humidity; //Umidade que será obtida pelo sensor DHT const int pinDHT = 22; //Pino que é ligado no sensor DHT SimpleDHT22 dht22(pinDHT); //Objeto que possui os métodos de leitura dos valores do sensor DHT

Setup

void setup()
{ //Para debug, iniciamos a comunicação serial com 115200 bps Serial.begin(115200); //Inicializa display lora if(!loraDisplayConfig()) ESP.restart(); //Exibe mensagem no display showDisplay(0, "Setting up mqtt...", true); Serial.println("Setting up mqtt..."); //Inicializa mqtt (conecta o esp com o wifi, configura e conecta com o servidor da ubidots) if(!mqttInit()) { delay(3000); showDisplay(0, "Failed!", false); Serial.println("Failed!"); ESP.restart(); } showDisplay(0, "OK", false); Serial.println("OK"); }

Loop

void loop()
{ //Se o esp foi desconectado do ubidots, tentamos reconectar if(!client.connected()) reconnect(); //Lê a temperatura e umidade e exibimos no display passando uma flag (que sinaliza sucesso na leitura) if(getClimate()) showClimate(true); else showClimate(false); //Esperamos 2.5s antes de exibir o status do envio para dar efeito de pisca no display delay(2500); if(sendValues(temperature, humidity)) { Serial.println("Successfully sent data"); showDisplay(4,"Successfully sent data", false); } else { Serial.println("Failed to send sensor data"); showDisplay(4,"Failed to send sensor data", false); } //Esperamos 2.5s para dar tempo de ler as mensagens acima delay(2500); }

Loop - Reading values from DHT22

//Obtém temperatura e umidade do sensor
bool getClimate() { int err = SimpleDHTErrSuccess; //Passamos as variáveis 'temperature' e 'humidity' por parâmetro na função chamada 'read2', elas serão retornadas por referência //Se não for retornado o código de SimpleDHTErrSuccess (sucesso), exibimos o valor de erro obtido if ((err = dht22.read2(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) { Serial.print("Read DHT22 failed, err="); Serial.println(err); //Zera valores temperature = humidity = 0; return false; } return true; }

Loop - Display values on the display

//Essa função exibe os valores com suas respectivas unidades de medida para caso a flag 'success' seja true
//Caso a flag 'success' seja false, exibimos apenas um traço '-' void showClimate(bool success) { if(success) { showDisplay(0, "Temperature: "+String(temperature)+" °C", true); showDisplay(1, "Humidity: "+String(humidity)+" %", false); Serial.println("Temperature: "+String(temperature)+" °C"); Serial.println("Humidity: "+String(humidity)+" %"); } else { showDisplay(0, "Temperature: -", true); showDisplay(1, "Humidity: -", false); Serial.println("Temperature: -"); Serial.println("Humidity: -"); } }

MQTT_Client - Declarations and Variables

#include <WiFi.h>
#include <PubSubClient.h> //Biblioteca para as publicações via mqtt #include "displayESP32LoRa.h" //Arquivo com as funções referentes ao display lora #define WIFISSID "MEU_SSID" //Coloque seu SSID de WiFi aqui #define PASSWORD "MEU_PASSWORD" //Coloque seu password de WiFi aqui #define TOKEN "xxxxxx" //Coloque seu TOKEN do Ubidots aqui #define VARIABLE_LABEL_TEMPERATURE "temperature" //Label referente a variável de temperatura criada no ubidots #define VARIABLE_LABEL_HUMIDITY "humidity" //Label referente a variável de umidade criada no ubidots #define DEVICE_ID "xxxxxx" //ID do dispositivo (Device id, também chamado de client name) #define SERVER "things.ubidots.com" //Servidor do Ubidots (broker) //Porta padrão #define PORT 1883 //Tópico aonde serão feitos os publish, "esp32-dht" é o DEVICE_LABEL #define TOPIC "/v1.6/devices/esp32-dht" //Objeto WiFiClient usado para a conexão wifi WiFiClient ubidots; //Objeto PubSubClient usado para publish–subscribe PubSubClient client(ubidots);

MQTT_Client - Boot

bool mqttInit()
{ //Inicia WiFi com o SSID e a senha WiFi.begin(WIFISSID, PASSWORD); //Loop até que o WiFi esteja conectado while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Establishing connection to WiFi.."); } //Exibe no monitor serial Serial.println("Connected to network"); //Seta servidor com o broker e a porta client.setServer(SERVER, PORT); //Conecta no ubidots com o Device id e o token, o password é informado como vazio while(!client.connect(DEVICE_ID, TOKEN, "")) { Serial.println("MQTT - Connect error"); return false; } Serial.println("MQTT - Connect ok"); return true; }

MQTT_Client - Reconnect

void reconnect()
{ //Loop até que o MQTT esteja conectado while (!client.connected()) { //sinaliza desconexão do mqtt no display showDisplay(0,"Disconnected", true); showDisplay(1, "Trying to reconnect mqtt...", false); Serial.println("Attempting MQTT connection..."); //Tenta conectar if (client.connect(DEVICE_ID, TOKEN,"")) Serial.println("connected"); else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 2 seconds"); //Aguarda 2 segundos antes de retomar delay(2000); } } //Sinaliza reconexão do mqtt no display showDisplay(4,"Reconnected", false); }

MQTT_Client - Submit (publish)

//Envia valores por mqtt
//Exemplo: {"temperature":{"value":24.50, "context":{"temperature":24.50, "humidity":57.20}}} bool sendValues(float temperature, float humidity) { char json[250]; //Atribui para a cadeia de caracteres "json" os valores referentes a temperatura e os envia para a variável do ubidots correspondente sprintf(json, "{\"%s\":{\"value\":%02.02f, \"context\":{\"temperature\":%02.02f, \"humidity\":%02.02f}}}", VARIABLE_LABEL_TEMPERATURE, temperature, temperature, humidity); if(!client.publish(TOPIC, json)) return false; //Atribui para a cadeia de caracteres "json" os valores referentes a umidade e os envia para a variável do ubidots correspondente sprintf(json, "{\"%s\":{\"value\":%02.02f, \"context\":{\"temperature\":%02.02f, \"humidity\":%02.02f}}}", VARIABLE_LABEL_HUMIDITY, humidity, temperature, humidity); if(!client.publish(TOPIC, json)) return false; //Se tudo der certo retorna true return true; }

Step 14: ESP32 Code

Json

(image)

Display LoRa

#ifndef _DISPLAY_LORA_
#define _DISPLAY_LORA_ #include "SSD1306.h" //Define os pinos que serão utilizados pelo display LoRa #define SCK 5 // GPIO5 -- SX127x's SCK #define MISO 19 // GPIO19 -- SX127x's MISO #define MOSI 27 // GPIO27 -- SX127x's MOSI #define SS 18 // GPIO18 -- SX127x's CS #define RST 14 // GPIO14 -- SX127x's RESET #define DI00 26 // GPIO26 -- SX127x's IRQ(Interrupt Request) SSD1306 display(0x3c, 4, 15); //Construtor do objeto do display LoRa

Display LoRa - loraDisplayConfig

//Configura Display LoRa
bool loraDisplayConfig() { //Configura RST do oled como saida pinMode(16,OUTPUT); //Reseta o OLED digitalWrite(16, LOW); //Aguarda 50ms delay(50); //Enquanto o OLED estiver ligado, GPIO16 deve estar HIGH digitalWrite(16, HIGH); //Inicializa display if(!display.init()) return false; //Inverte a tela verticalmente (de ponta cabeça) display.flipScreenVertically(); //Configura a fonte do display display.setFont(ArialMT_Plain_10); //Aguarda 200ms delay(200); //Limpa display display.clear(); return true; } #endif

Display LoRa - showDisplay

//Exibe mensagem recebida como parâmetro
void showDisplay(int line, String msg, bool clear) { //Limpa o display if(clear) { display.clear(); //Configura alinhamento de texto à esquerda display.setTextAlignment(TEXT_ALIGN_LEFT); //Configura fonte do texto display.setFont(ArialMT_Plain_10); } //Escreve na pos 0,25 a mensagem display.drawString(0 , line*10 , msg); //Exibe no display display.display(); }

Step 15: Installing Libraries

SimpleDHT

https://github.com/winlinvip/SimpleDHT

Pubsubclient

https://github.com/knolleary/pubsubclient

* Display LoRa attached to the project

Step 16: Files

Download the files:

INO

PDF