ESP32 e MQTT DASH: controle e monitoramento através de um dashboard MQTT para Android 5

O ESP32 é a evolução do já popular e consagrado ESP8266. Com muito mais recursos computacionais, com conectividade Bluetooth e com a mesma facilidade de se utilizar (na Arduino IDE) de sempre, o ESP32 é uma ótima escolha para aqueles que querem fazer projetos no contexto de Internet das Coisas (IoT).  E, assim como acontece nos ESP8266, é possível utilizar MQTT nos ESP32, tornando assim praticamente infinitas as possibilidades de aplicação desta placa. Mas e quanto a parte de visualização / atuação para fazer o monitoramento e controle via MQTT? É exatamente disso que este artigo se trata: como utilizar MQTT na ESP32 para monitorar e controlar periféricos (no caso: um LED e um sensor de temperatura e umidade DHT22) e, além disso, como utilizar o MQTT DASH, um aplicativo Android que permite você construir no seu smartphone um dashboard MQTT.

Material necessário

Para fazer o projeto mostrado neste artigo, você precisará de:

Além disso, você precisará de uma conectividade wi-fi à Internet e de um smartphone Android capaz de ter instalado o aplicativo MQTT DASH.

MQTT DASH – overview

O MQTT DASH é um aplicativo para smartphones Android capaz de montar um Dashboard baseado em informações vindas (ou a serem enviadas) por MQTT. Dessa forma, o controle e monitoramento de entradas e saídas em um ESP32, por exemplo, pode ser feito do seu smartphone Android através desse app, com visual bacana e com ótima performance. Este aplicativo é gratuito e está disponível para download no Google Play através deste link. Veja um exemplo de dashboard rodando em um smartphone.

Figura 1 - exemplo de dashboard rodando em um smartphone com MQTT DASH

O MQTT DASH funciona atribuindo cada item do dashboard (indicador/LED, botão, campo de texto, etc.) a um tópico MQTT diferente. Logo, cada item do dashboard exige um tópico MQTT distinto, sendo publicado/subescrito em um mesmo broker MQTT. Em outras palavras, tanto o MQTT DASH quanto sua placa, como por exemplo o ESP32, precisam estar no mesmo broker MQTT e publicarem as informações em tópicos de conhecimento de ambas as partes.

Como construir um dashboard no MQTT DASH?

Aqui, será mostrado como construir um exemplo de um dashboard com o app MQTT DASH, a fim de te dar base e conhecimentos para a construção do dashboard do projeto deste post.
Siga o procedimento abaixo:

  1. Primeiramente, faça a instalação do aplicativo em seu smartphone Android. Para isso, entre neste link e siga as instruções na tela.
  2. Uma vez instalado, abra o aplicativo. Uma tela como a mostrada na figura abaixo deverá aparecer. Nesta tela, clique no símbolo “+” no canto superior direito para adicionar um novo dashboard.Figura 2 - tela inicial do aplicativo (sem nenhum dashboard cadastrado)
  3. Uma tela de cadastro deste novo dashboard irá aparecer.
    Preencha seus campos conforme mostrado na figura  abaixo e clique no ícone de um disquete (canto superior direito) para salvar o dashboard.Figura 3 - cadastro de um novo dashboard
  4. Criado o novo dashboard, sua tela deverá parecer conforme mostra figura.
    Para adicionar um item a este dashboard, clique no símbolo “+” no canto superior direito.Figura 4 - novo dashboard criado (ainda vazio)
  5. Após clicar no símbolo “+” (canto superior direito), irão aparecer algumas opções de itens a serem adicionados no dashboard. Escolha o item “Switch/button”.Figura 5 - itens possíveis de serem adicionados ao dashboard
  6. Feito isso, uma tela para preencher as informações deste botão irão aparecer.
    Preencha as informações conforme mostra a figura a seguir e clique no ícone de um disquete (canto superior direito) para salvar o item no dashboard.Figura 6 - informações do botão a ser adicionado no dashboard
    Observe na imagem que, por default, o botão irá publicar no seu tópico correpondente (topico_mqt_do_botao1) a string “1” caso este for acionado e, consequentemente, a string “0” caso este for desacionado.
  7. De volta à tela do dashboard, agora ela contará com o botão que foi adicionado, conforme mostra a figura abaixo.
    Agora, vamos adicionar um campo de texto. Para isso, clique no símbolo “+” (canto superior direito) e selecione a opção “Text”.Figura 8 - dashboard com o botão recém-adicionado
  8. Na tela de informações do campo de texto (a ser adicionado em seu dashboard), preencha as informações. Feito isso, clique no ícone de um disquete (canto superior direito) para salvar o item no dashboard.
  9. Seu dashboard está concluído! Sua aparência final deve ser conforme mostrado na figura abaixo.
    Para visualizar o envio das strings “1” e “0” conforme se daciona e desaciona os botões, conecte-se ao broker e subescreva-se ao tópico “topico_mqtt_do_botao1”. Já para enviar um texto qualquer ao campo texto de seu dashboard, conecte-se ao brokerpublique qualquer string no tópico “topico_mqtt_do_campo_texto1”

Figura 10 - dashboard finalizado

Criando o dashboard para o projeto deste post

Para o projeto deste post, utilize o que foi ensinado no tópico anterior e crie um dashboard com as seguintes características:

  • Nome do dashboard: ESP32 e MQTT DASH
  • Endereço do broker: iot.eclipse.org
  • Porta: 1883
  • Botão: criar um botão de nome “LED”, com nome de tópico igual a “topico_liga_desliga_led”
  • Campo de texto: criar um campo de texto de nome “Temperatura”, com nome de tópico igual a “topico_sensor_temperatura”
  • Campo de texto: criar um campo de texto de nome “Umidade”, com nome de tópico igual a “topico_sensor_umidade”

IMPORTANTE: para evitar que você envie e/ou receba comandos de outras pessoas pelos menos tópicos no broker MQTT, sugiro fortemente alterar os nomes dos tópicos no dashboard e no código para algo mais particular seu.

Tal dashboard deverá se parecer conforme mostrado abaixo.

Figura 11 - dashboard do projeto deste post

Bibliotecas necessárias para o ESP32 e MQTT

As bibliotecas necessárias para o ESP32 utilizar MQTT e DHT22 são as mesmas utilizadas em qualquer outro Arduino, incluindo o NodeMCU (ESP8266). Portanto, instale-as da mesma forma que no caso de uso de um Ardino comum. Como referência, seguem alguns posts que contém instruções para instalação das bibliotecas utilizadas neste projeto:

Circuito esquemático do projeto

O circuito esquemático do projeto pode ser visto na figura a seguir.

 

Figura 12 - circuito esquemático

Código-fonte

O código-fonte do projeto está a seguir:

/* 
 *  Projeto: controle e monitoramento de periféricos no ESP32 
 *           via MQTT com app MQTT DASH
 *  Autores: Pedro Bertoleti e FilipeFlop
 *  Data: Fevereiro/2019
 */
#include <DHT.h>
#include <WiFi.h>
#include <PubSubClient.h>


/* Definições do LED */
#define PIN_LED     25

/* Definicoes do sensor DHT22 */
#define DHTPIN 26     //GPIO que está ligado o pino de dados do sensor

//#define DHTTYPE DHT11
#define DHTTYPE DHT22   //sensor em utilização: DHT22
//#define DHTTYPE DHT21

/* Defines do MQTT */
#define TOPICO_SUBSCRIBE_LED         "topico_liga_desliga_led"
#define TOPICO_PUBLISH_TEMPERATURA   "topico_sensor_temperatura" 
#define TOPICO_PUBLISH_DISTANCIA     "topico_sensor_distancia" 
#define TOPICO_PUBLISH_UMIDADE       "topico_sensor_umidade" 

#define ID_MQTT  "esp32_mqtt"     //id mqtt (para identificação de sessão)
                                  //IMPORTANTE: este deve ser único no broker (ou seja, 
                                  //            se um client MQTT tentar entrar com o mesmo 
                                  //            id de outro já conectado ao broker, o broker 
                                  //            irá fechar a conexão de um deles).

/* Variaveis, constantes e objetos globais */
DHT dht(DHTPIN, DHTTYPE);

const char* SSID = " "; // SSID / nome da rede WI-FI que deseja se conectar
const char* PASSWORD = " "; // Senha da rede WI-FI que deseja se conectar

const char* BROKER_MQTT = "iot.eclipse.org"; //URL do broker MQTT que se deseja utilizar
int BROKER_PORT = 1883; // Porta do Broker MQTT
  
//Variáveis e objetos globais
WiFiClient espClient; // Cria o objeto espClient
PubSubClient MQTT(espClient); // Instancia o Cliente MQTT passando o objeto espClient

/* Prototypes */
float faz_leitura_temperatura(void);
float faz_leitura_umidade(void);
void initWiFi(void);
void initMQTT(void);
void mqtt_callback(char* topic, byte* payload, unsigned int length);
void reconnectMQTT(void);
void reconnectWiFi(void);
void VerificaConexoesWiFIEMQTT(void);

/*
 * Implementações
 */

/* Função: faz a leitura de temperatura (sensor DHT22)
 * Parametros: nenhum
 * Retorno: temperatura (graus Celsius)
 */
float faz_leitura_temperatura(void)
{
    float t = dht.readTemperature();
    float result;
    
    if (! (isnan(t)) )
        result = t;
    else
        result = -99.99;

    return result;
}

/* Função: faz a leitura de umidade relativa do ar (sensor DHT22)
 * Parametros: nenhum
 * Retorno: umidade (0 - 100%)
 */
float faz_leitura_umidade(void)
{
    float h = dht.readHumidity();    
    float result;
    
    if (! (isnan(h)) )
        result = h;
    else
        result = -99.99;

    return result;
}

/* Função: inicializa e conecta-se na rede WI-FI desejada
*  Parâmetros: nenhum
*  Retorno: nenhum
*/
void initWiFi(void) 
{
    delay(10);
    Serial.println("------Conexao WI-FI------");
    Serial.print("Conectando-se na rede: ");
    Serial.println(SSID);
    Serial.println("Aguarde");
     
    reconnectWiFi();
}

/* Função: inicializa parâmetros de conexão MQTT(endereço do 
 *         broker, porta e seta função de callback)
 * Parâmetros: nenhum
 * Retorno: nenhum
 */
void initMQTT(void) 
{
    MQTT.setServer(BROKER_MQTT, BROKER_PORT);   //informa qual broker e porta deve ser conectado
    MQTT.setCallback(mqtt_callback);            //atribui função de callback (função chamada quando qualquer informação de um dos tópicos subescritos chega)
}

/* Função: função de callback 
 *         esta função é chamada toda vez que uma informação de 
 *         um dos tópicos subescritos chega)
 * Parâmetros: nenhum
 * Retorno: nenhum
 */
void mqtt_callback(char* topic, byte* payload, unsigned int length) 
{
    String msg;
 
    /* obtem a string do payload recebido */
    for(int i = 0; i < length; i++) 
    {
       char c = (char)payload[i];
       msg += c;
    }

    Serial.print("Chegou a seguinte string via MQTT: ");
    Serial.println(msg);
   
    /* toma ação dependendo da string recebida */
    if (msg.equals("1"))
    {
        digitalWrite(PIN_LED, HIGH);
        Serial.print("LED aceso mediante comando MQTT");
    }
 
    if (msg.equals("0"))
    {
        digitalWrite(PIN_LED, LOW);    
        Serial.print("LED apagado mediante comando MQTT"); 
    }
}

/* Função: reconecta-se ao broker MQTT (caso ainda não esteja conectado ou em caso de a conexão cair)
 *         em caso de sucesso na conexão ou reconexão, o subscribe dos tópicos é refeito.
 * Parâmetros: nenhum
 * Retorno: nenhum
 */
void reconnectMQTT(void) 
{
    while (!MQTT.connected()) 
    {
        Serial.print("* Tentando se conectar ao Broker MQTT: ");
        Serial.println(BROKER_MQTT);
        if (MQTT.connect(ID_MQTT)) 
        {
            Serial.println("Conectado com sucesso ao broker MQTT!");
            MQTT.subscribe(TOPICO_SUBSCRIBE_LED); 
        } 
        else
        {
            Serial.println("Falha ao reconectar no broker.");
            Serial.println("Havera nova tentatica de conexao em 2s");
            delay(2000);
        }
    }
}

/* Função: verifica o estado das conexões WiFI e ao broker MQTT. 
 *         Em caso de desconexão (qualquer uma das duas), a conexão
 *         é refeita.
 * Parâmetros: nenhum
 * Retorno: nenhum
 */
void VerificaConexoesWiFIEMQTT(void)
{
    if (!MQTT.connected()) 
        reconnectMQTT(); //se não há conexão com o Broker, a conexão é refeita
     
     reconnectWiFi(); //se não há conexão com o WiFI, a conexão é refeita
}

/* Função: reconecta-se ao WiFi
 * Parâmetros: nenhum
 * Retorno: nenhum
 */
void reconnectWiFi(void) 
{
    //se já está conectado a rede WI-FI, nada é feito. 
    //Caso contrário, são efetuadas tentativas de conexão
    if (WiFi.status() == WL_CONNECTED)
        return;
         
    WiFi.begin(SSID, PASSWORD); // Conecta na rede WI-FI
     
    while (WiFi.status() != WL_CONNECTED) 
    {
        delay(100);
        Serial.print(".");
    }
   
    Serial.println();
    Serial.print("Conectado com sucesso na rede ");
    Serial.print(SSID);
    Serial.println("IP obtido: ");
    Serial.println(WiFi.localIP());
}
 
/* Função de setup */
void setup() 
{
    Serial.begin(115200);  

    /* Configuração do pino ligado ao LED como output 
       e inicialização do mesmo em LOW */
    pinMode(PIN_LED, OUTPUT);
    digitalWrite(PIN_LED,LOW);

    /* Inicializacao do sensor de temperatura */
    dht.begin();  

    /* Inicializa a conexao wi-fi */
    initWiFi();

    /* Inicializa a conexao ao broker MQTT */
    initMQTT();
}

/* Loop principal */
void loop() 
{
    char temperatura_str[10] = {0};
    char umidade_str[10]     = {0};
    
    /* garante funcionamento das conexões WiFi e ao broker MQTT */
    VerificaConexoesWiFIEMQTT();

    /* Compoe as strings a serem enviadas pro dashboard (campos texto) */
    sprintf(temperatura_str,"%.2fC", faz_leitura_temperatura());
    sprintf(umidade_str,"%.2f", faz_leitura_umidade());

    /*  Envia as strings ao dashboard MQTT */
    MQTT.publish(TOPICO_PUBLISH_TEMPERATURA, temperatura_str);
    MQTT.publish(TOPICO_PUBLISH_UMIDADE, umidade_str);
  
    /* keep-alive da comunicação com broker MQTT */ 
    MQTT.loop();

    /* Refaz o ciclo após 2 segundos */
    delay(2000);
}

Projeto em ação!

Veja uma foto do dashboard em ação.

 

Figura 13 - dashboard do projeto em ação

Gostou deste post sobre como fazer controle e monitoramento de periféricos no ESP32 através de um dashboard MQTT (app MQTT DASH) para Android? Deixe seu comentário logo abaixo. Em caso de dúvidas, caso queira trocar uma ideia, ou até mesmo dividir seu projeto, acesse nosso Fórum!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

5 Comentários

  1. Olá, funciona em uma rede local?

    1. Se você tiver um broker MQTT na sua rede, sim.

  2. Boa Noite, em qual parte deste programa posso implementar o código de meu programa ? crio um void separado e coloco todos os meus voids ou posso tirar o delay do void loop e colocar os chamados do meu programa ?

    Obrigado.

  3. Boa noite, primeiramente parabéns pela publicação muito bom.

    Gostaria de saber se consigo usar esse código fonte para o app Blynk. Estou com dificuldade de montar um código para o blynk usando o MQTT.

    1. Rafael, boa tarde.

      Obrigado pela leitura e elogio.

      Quanto a sua pergunta, a forma de se conectar ao broker MQTT no Blynk será a mesma, porém o endereço do broker, tópicos e tudo mais será diferente.

      Atenciosamente,
      Pedro Bertoleti