Recents in Beach


Receba o meu conteúdo GRATUITAMENTE


Introdução ao protocolo MQTT com Ubidots – ESP32



Hoje vamos fazer uma introdução ao protocolo MQTT (Message Queue Telemetry Transport), método bastante útil para IOT (Internet das Coisas), cujo principal uso é proporcionar comunicação entre máquinas, ou seja, Machine-to-Machine (M2M). Vamos, portanto, dar os primeiros passos com Ubidots IOT platform, expondo sua utilização em um exemplo com ESP32 LoRa. Isso também com um sensor DHT22, sendo o envio de informações feito com o protocolo MQTT.


O protocolo MQTT foi criado pela IBM há muito tempo atrás e passou a ser bastante utilizado para IOT com o barateamento dos chips e a facilidade de acesso a internet. No exemplo específico que vamos fazer aqui vamos usar o Ubidots, que é um broker, ou melhor, um site com um broker.


Demonstração




Recursos usados

·         ESP32 Display LoRa
·         DHT22
·         Resistor 4k7 ohm
·         Conta (trial 30 dias ou paga) no Ubidots
·         Protoboard




Protocolo MQTT

Publish e Subscribe




Ubidots IoT Platform

Assuntos que serão abordados
·         Criando uma nova conta
·         Criando um novo Dashboard
·         Criando o ESP32-DHT Device
·         Obtendo dados MQTT – Device ID e Topic
·         Obtendo dados MQTT – Token
·         Criação de variáveis no Ubidots
·         Criando Widgets de umidade e temperatura



Criando nova conta

Para criar uma conta acesse www.ubidots.com e clique em SIGN UP



1. Nome da empresa

2. Estágio do projeto:


Escolhemos o estágio Discovery, indicando que é um projeto de testes.

3. Criar aplicação



1.  Seu nome
2.  Seu email
3.  Criar perfil



1.  Login
2.  Senha
3.  Iniciar teste grátis







Criando novo Dashboard

1. Clique em create a new dashboard



2. Digite um nome para o Dashboard e clique no botão





Criando ESP32-DHT Device

1. Clique em Device Management e em Devices



2. Clique em Create Device ou em +



3. Uma aba será aberta listando os tutoriais existentes no site help.ubidots para a configuração e programação  de microcontroladores de acordo com os seus respectivos fabricantes. Criaremos um dispositivo em branco.



4. Preencha os campos


A. Nome do dispositivo
B. Rótulo (Será parte do tópico usado pelo MQTT Client)
C. Criar


5. Após o dispositivo ser criado ele será listado na página de dispositivos conforme a figura


A. Nome do dispositivo
B. Última atualização
C. Data/hora de criação do dispositivo
D. Organização referente ao dispositivo
E. Adicionar organização e Deletar dispositivo


Obtendo dados MQTT – Device ID e Topic

1. Selecione o dispositivo



2. Os valores de Device ID e o tópico são escritos conforme as imagens
A porta utilizada é 1883.



3. O token é obtido conforme as imagens 3.1 e 3.2





Criando Variáveis

Para criarmos um widget que referencia uma variável de um device, a mesma já deve estar criada no device.
OBS: As variáveis são criadas automaticamente pelo Ubidots após um envio de Json, mas para isso é necessário ligar o ESP32 ao menos uma vez. Para referenciarmos os widgets sem que seja necessário ligar o ESP, devemos seguir estes passos.

1. Em Devices selecione o dispositivo



2. Clique em Add Variable e depois em Raw


Obs: Defina as mesmas Labels do código fonte (no arquivo MQTT_Client.h)


3. Digite o label (VARIABLE_LABEL_TEMPERATURE )



4. Repita os passos para a variável de umidade
(VARIABLE_LABEL_HUMIDITY)





Criando Widgets


1. Vá para a página de dashboards.



2. Clique em um dos botões





Criando Widgets – Temperatura


3. Selecionamos a opção Thermometer



4. Clique em Add Variables



5. Siga os passos para selecionar a variável de temperatura





6. Clique em confirmar






Criando Widgets – Umidade

1. Adicione outro widget



2. Selecione a opção Tank



3. Clique em Add Variables




4. Selecione ESP32-DHT ,clique em humidity e depois em confirmar



5. Por fim, clique em confirmar



6. O Widget de umidade aparecerá abaixo do de temperatura



7. Você pode organizar arrastando as janelas




Montagem





Código

Declarações e variáveis

#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 – Leitura de valores do 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 – Exibição de valores no 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 – Declarações e variáveis

#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 – Inicialização

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 – Reconexão

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 – Envio (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;
}



Código ESP32

Json



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();  
}



Instalação de bibliotecas


Pubsubclient

*Display LoRa anexado junto ao projeto




Faça o download dos arquivos:





Postar um comentário

3 Comentários

  1. O link para o pdf não esta funcionando.

    ResponderExcluir
  2. Olá Fernando, primeiramente muito fã do seu trabalho. Simplesmente sensacional. Gostei muito desse projeto. Como seria se implementar dois ESP? Um lendo o sensor, transmitindo em lota para outro escrever no mqqt. Novamente parabéns!

    ResponderExcluir
  3. Gostaria muito de estudar contigo, Fernando. Confesso, também que estou ansioso pelo seu livro!!! Parabéns pelos conteúdos publicados. Tenho aprendido muito com seus videos!

    ResponderExcluir