banner

Ir para o Forum

IBM Watson com ESP32 como Endpoint



Hoje eu posto aqui o primeiro vídeo de uma série que estou fazendo sobre como montar um dispositivo Endpoint com ESP32 e enviá-lo para um serviço de nuvem. Especificamente neste episódio vou mostrar como você faz para mandar informações de um sensor DHT22 utilizando o protocolo MQTT para o IBM Watson.

esp32 endpoint

Vamos, então, fazer uma introdução ao MQTT, que é um protocolo máquina a máquina usado em IoT (Internet of Things). Vamos, ainda, enviar dados do sensor de temperatura e umidade utilizando esse protocolo e verificar o gráfico com esses dados em uma página web.

ESP32 Pinout

Deixo aqui o Pinout do ESP32, o qual usamos no nosso exemplo, mas quero deixar claro que o projeto também funciona com o ESP8266, inclusive com o mesmo código fonte.

Pinout ESP32


NodeMCU Pinout

NodeMCU Pinout

MQTT

MQTT é um protocolo máquina a máquina usado em IoT, portanto, foi criado para ser leve e rápido. Utiliza um sistema de subscribe/publish onde um dispositivo se “inscreve” em um tópico cujas informações lhe interessa e recebe as informações sempre que algum dispositivo publicar dados neste tópico.
Então, o MQTT precisa de um software, como se fosse um programa-servidor, chamado de Broker. Neste caso, nós vamos utilizar o Bluemix IoT Service da IBM. Este serviço é livre para testagem de Endpoint.
Precisamos ter, então, um celular ou tablet com o Application side, ou seja, como um MQTT client. Da mesma forma, temos o Device side, que é o lado do ESP com um termômetro. Este envia os dados de temperatura e umidade ao Bluemix, que manda tais informações para o Application Side.

Bluemix

Montagem

O nosso circuito é formado por um resistor de 4,7k Ohms entre o 3.3v e o pino de dados, além de um DHT22 ligado ao GPIO4 de um ESP32 ou NodeMCU. Este, portanto, se trata do nosso Endpoint.

Montagem

Diagrama

Aqui mostro que temos várias maneiras de se trabalhar com o MQTT Broker Local. Deixo, então, dois modelos de diagramas. No vídeo falo de um caso utilizando um Raspberry Pi para abrir um portão, por exemplo.

Diagrama com Broker Local

Nesta imagem acima temos uma primeira arquitetura que usa um Broker local com persistência e, abaixo, uma segunda arquitetura que apenas se comunica com o broker na nuvem.

Diagrama com Broker na nuvem

Temos, então, neste diagrama, o nosso sensor enviando os dados de temperatura e umidade para o IBM Watson. Lembro que, neste caso, os dados não estão sendo gravados pelo IBM Watson, mas, apenas, são exibidos em gráficos. Isso porque, neste exemplo de hoje, não vamos tratar de nenhuma operação de banco de dados, mas indicar apenas o acesso à página do Quickstart (https://quickstart.internetofthings.ibmcloud.com/), que vai exibir o status do seu Endpoint. O esquema é simples e usa o WiFi para o envio de dados.


Bibliotecas

Na ide do Arduino vá no menu Sketch -> Incluir Biblioteca -> Gerenciar Bibliotecas
Na tela que abrir digite na busca “DHT” e instale a lib “DHT sensor library”.
Depois digite “PubSubClient” e instale a lib “PubSubClient”.


Biblioteca para leitura de Temperatura e Umidade

Lib de leitura de temperatura e umidade


Biblioteca MQTT

Lib MQTT


MQTT.ino

Iniciamos o código fonte verificando qual ESP está sendo utilizado e importando a biblioteca de WiFi correspondente. Ainda incluímos as Libs do MQTT e do sensor de temperatura e umidade.

//Verifica qual ESP está sendo utilizado
//e importa a lib e wifi correspondente
#if defined(ESP8266)
#include <ESP8266WiFi.h>        
#else
#include <WiFi.h>
#endif

//Lib de MQTT
#include <PubSubClient.h>
//Lib do sensor de temperatura e umidade
#include <DHT.h>


Na sequência, definimos o intervalo entre os envios de dados, servidor MQTT a ser utilizado, informações de impressão no gráfico, bem como do ID. Também apontamos como deve permanecer a string QUICK_START.

//Intervalo entre os envios
#define INTERVAL 1000

//Substitua pelo SSID da sua rede
#define SSID "TesteESP"

//Substitua pela senha da sua rede
#define PASSWORD "87654321"

//Server MQTT que iremos utlizar
#define MQTT_SERVER "quickstart.messaging.internetofthings.ibmcloud.com"

//Nome do tópico que devemos enviar os dados
//para que eles apareçam nos gráficos
#define TOPIC_NAME "iot-2/evt/status/fmt/json"

//ID que usaremos para conectar 
//QUICK_START deve permanecer como está
const String QUICK_START = "d:quickstart:arduino:";


Nesta etapa, definimos um ID único. Neste exemplo, utilizamos o MAC Address do dispositivo que estamos utilizando. Este servirá como identificação no site QuickStart. Ainda aqui, conectamos o ID do Quickstart com o ID do nosso dispositivo.

//No DEVICE_ID você deve mudar para um id único
//Aqui nesse exemplo utilizamos o MAC Address
//do dispositivo que estamos utilizando
//Servirá como identificação no site
//https://quickstart.internetofthings.ibmcloud.com
const String DEVICE_ID = "240ac40e3fd0";

//Concatemos o id do quickstart com o id do nosso
//dispositivo
const String CLIENT_ID =  QUICK_START + DEVICE_ID;


Partimos para a configuração do MQTT e do WiFi, bem como dos objetos e variáveis envolvidos com os valores de temperatura e umidade.

//Cliente WiFi que o MQTT irá utilizar para se conectar
WiFiClient wifiClient;

//Cliente MQTT, passamos a url do server, a porta
//e o cliente WiFi
PubSubClient client(MQTT_SERVER, 1883, wifiClient);

//Tempo em que o último envio foi feito
long lastPublishTime = 0;

//Objeto que realiza a leitura da temperatura e da umidade
DHT dht(4, DHT22);

//Variável para guardarmos o valor da temperatura
float temperature = 0;

//Variável para guardarmos o valor da umidade
float humidity = 0;


MQTT.ino – setup

No Setup, vamos inicializar o DHT, conectar na rede WiFi e ao server MQTT.

void setup() {
  Serial.begin(115200);
  //Incializamos o dht
  dht.begin();
  //Conectamos à rede WiFi
  setupWiFi();
  //Conectamos ao server MQTT
  connectMQTTServer();
}


MQTT.ino – loop

Já no Loop, coletamos os dados dos sensores para criarmos o Json que será publicado no tópico que o IBM Watson eserar para gerar o gráfico.

void loop() {
  //Tempos agora em milisegundos
  long now = millis();

  //Se o tempo desde o último envio for maior que o intervalo de envio
  if (now - lastPublishTime > INTERVAL) {
    //Atualizamos o tempo em que ocorreu o último envio
    lastPublishTime = now;
    //Fazemos a leitura da temperatura e umidade
    readSensor();
    Serial.print("Publish message: ");
    //Criamos o json que enviaremos para o server mqtt
    String msg = createJsonString();
    Serial.println(msg);
    //Publicamos no tópico onde o servidor espera para receber 
    //e gerar o gráfico
    client.publish(TOPIC_NAME, msg.c_str());
  }
}


MQTT.ino – setupWiFi

Temos aqui a função responsável pela conexão à rede WiFi.

//Função responsável por conectar à rede WiFi
void setupWiFi() {
  Serial.println();
  Serial.print("Connecting to ");
  Serial.print(SSID);

  //Manda o esp se conectar à rede através
  //do ssid e senha
  WiFi.begin(SSID, PASSWORD);

  //Espera até que a conexão com a rede seja estabelecida
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  //Se chegou aqui é porque conectou
  Serial.println("");
  Serial.println("WiFi connected");
}


MQTT.ino - connectMQTTServer

Nesta etapa, utilizamos a função responsável pela conexão com o server MQTT.

//Função responsável por conectar ao server MQTT
void connectMQTTServer() {
  Serial.println("Connecting to MQTT Server...");
  //Se conecta ao id que definimos
  if (client.connect(CLIENT_ID.c_str())) {
    //Se a conexão foi bem sucedida
    Serial.println("connected");
  } else {
    //Se ocorreu algum erro
    Serial.print("error = ");
    Serial.println(client.state());
  }
}


MQTT.ino - readSensor

Já a leitura dos dados de temperatura e umidade é definida nesta função.

//Função responsável por realizar a leitura 
//da temperatura e umidade
void readSensor(){
  float value;
  //Faz a leitura da temperatura
  value = dht.readTemperature();
  //Se o valor lido é válido
  if(!isnan(value)){
    //Armazena o novo valor da temperatura
    temperature = value;
  }
  //Faz a leitura da umidade
  value = dht.readHumidity();
  //Se o valor for válido
  if(!isnan(value)){
    //Armazena o novo valor da umidade
    humidity = value;
  }
}


MQTT.ino - createJsonString

Aqui temos a função responsável por criar um Json com os dados lidos.

//Função responsável por criar
//um Json com os dados lidos
String createJsonString() {
  String data = "{";
    data+= "\"d\": {";
      data+="\"temperature\":";
      data+=String(temperature);
      data+=",";
      data+="\"humidity\":";
      data+=String(humidity);
    data+="}";
  data+="}";
  return data;
}


Gráfico

Para visualizar o gráfico do sensor vá até https://quickstart.internetofthings.ibmcloud.com
No campo Device ID digite o DEVICE_ID que você definiu no código.
- É importante mudar no código este Device ID para um ID único, utilizado somente por você, para não dar conflito com dados enviados por outra pessoa.
Por fim, aceite os termos e clique em Go.


QuickStart IBM Watson

Visualize seus dados:

QuickStar Gráfico

Neste projeto, portanto, nós testamos nosso Endpoint no servidor do IBM Watson. Isso garante que o nosso programa do Arduino está conversando corretamente com a plataforma e que, se criarmos uma conta, os dados que enviarmos serão recebidos sem problemas por um serviço de nuvem.
Em um próximo vídeo desta série, vou mostrar como você faz o login no IBM Watson, assim como a gravação de dados no banco deste ou outro serviço de nuvem, como, por exemplo, Google, Amazon, entre outros.



Faça o download dos arquivos:


4 comentários:

  1. Fernando K, obrigado pelo projeto, muito bom mesmo, comprei uma placa NodeMCU V3 ESP8266 ESP12, usei o endereço http://arduino.esp8266.com/versions/2.4.1/package_esp8266com_index.json, mas pelo que vi não tem a V3, acho que esta versão é mais atual, qual NodeMCU eu uso deste link, no ARDUINO IDE? obrigado.

    ResponderExcluir
  2. Olá Fernando K, Parabéns pela iniciativa e pelo trabalho.
    Gostaria de registrar para os colegas que baixaram recentemente a biblioteca do DHT versão 1.3.0 está dando erro de compilação.
    Eu voltei para a versão 1.2.3 e o compilador roda direitinho.

    Obs. Se aluguém souber como corrigir o problema já na biblioteca HDT 1.3.0 por favor me avise.

    Obrigado

    ResponderExcluir
  3. Fernando, não estou conseguindo encontrar o Mac do meu esp32 , poderia nos direcionar a alguma ajuda?

    ResponderExcluir

Tecnologia do Blogger.