Nesse artigo, iremos fazer um projeto para praticarmos a construção de um ambiente IoT, principalmente para iniciantes na área, que pode vir a ser até mesmo um produto, o objetivo do projeto é realizar a leitura dos dados de temperatura e umidade fornecidos pelo sensor DHT11 através do microcontrolador ESP32 e com a ajuda do protocolo MQTT iremos transmitir estes dados para um servidor (que no caso, será nosso próprio computador) e mostraremos estes mesmos dados em uma aplicação de dashboards chamada Grafana.
Para o projeto iremos precisar:
- IDE / Plataforma — Arduino IDE para programar o código do microcontrolador.
- ESP32.
- MÓDULO SENSOR DHT11.
- PROTOBOARD.
- JUMPERS.
Além disso, por questões de preferência e praticidade, o S.O (Sistema Operacional) usado neste artigo foi o Linux Ubuntu 22.04, dito isso todo e qualquer software usado nesse projeto, sendo eles: broker MQTT, Grafana, Arduino IDE, bancos de dados e entre outros terão seus comandos de instalação e uso nos terminais voltados para o S.O escolhido. Contudo, todos eles estão disponíveis em outros Sistemas Operacionais, como por exemplo: Windows.
Circuito
Na imagem abaixo, vemos o esquemático da parte física do projeto que vai ser feito usando a protoboard. O esquemático vai nos auxiliar na construção do hardware envolvido no projeto.
Uma observação sobre o circuito acima é que nele temos apenas o DHT11 e não o módulo dele que será usado no projeto, o DHT11 contém quatros terminais, sendo eles: VCC, DATA, NC e GND. Porém o módulo do sensor, não expõe o terminal NC.
Ligações dos pinos do módulo do DHT11 ao ESP32:
- Terminal VCC → Vin (5V) ESP32
- Terminal GND → GND ESP32
- Terminal DATA → D23 (GPIO 23) ESP32
Durante o artigo vai ser usado o módulo do DHT11, usando ele não é necessário fazer o pull-up que está no circuito acima, ou seja, você não irá precisar colocar o resistor e fazer suas devidas ligações, somente irá ligar os terminais do DHT11 ao ESP32 assim como está no circuito acima. Porém, caso você queira usar o sensor direto, você deve então utilizar o pull-up.
Funcionamento básico e características do DHT11:
O sensor de temperatura DHT11 é um dos mais populares e baratos do mercado, o que o torna acessível e prático para projetos. Além disso, o seu uso não é complicado.
Outra informação importante de se ter são as medidas alcançadas pelo sensor, segundo o seu DataSheet (manual), a precisão da temperatura medida pelo sensor pode variar em ± 2°C e a umidade em ± 5%.
Caso queiram saber mais sobre o sensor, é possível encontrar o datasheet do DHT11 facilmente na internet.
Configuração do ambiente:
Para usarmos o sensor é preciso instalar a biblioteca do mesmo dentro da Arduino IDE, para isso você deve seguir os passos:
- Gerenciador de bibliotecas.
- Procurar por DHT sensor library by Adafruit.
- Instalar.
Ou caso queira, você também pode instalar o arquivo da biblioteca por meio do link: https://www.arduino.cc/reference/en/libraries/dht-sensor-library/, descompactar o arquivo e inseri-lo na pasta de libraries que se encontra dentro da pasta raiz do seu Arduino IDE.
Funcionamento e instalação básica do broker MQTT:
O broker funciona como um intermediador dos nossos dados que é capaz de recebê-los de inúmeros dispositivos ao mesmo tempo. No caso, trabalhamos com duas nomenclaturas ao lidar com um broker, temos a publicação e a inscrição, sendo assim quando realizamos a publicação estamos enviando os dados para o broker. Já a inscrição é a forma que outros dispositivos ou aplicações, como, por exemplo, o servidor, recebem ou “pegam” esses dados.
Nesse caso, usaremos o Broker Mosquitto que é o software que nos permite utilizar o protocolo de comunicação MQTT no lado do servidor.
Para instalação do broker no Linux, basta seguir os comandos abaixo:
- sudo apt-get update -y && sudo apt-get upgrade -y
- sudo apt-get install mosquitto
Após a instalação é recomendado usar o comando: systemctl status mosquitto.
Para verificar de fato se o broker, após instalado, já está ativo. Caso o mesmo apareça como STOPPED, use o comando abaixo para iniciar a sua aplicação: systemctl start mosquitto.
Outro fator importante é que por padrão quando se instala o broker MQTT, a porta atribuída para aplicação é a 1883, porém fique atento, pois você pode já ter alguma outra aplicação usando essa mesma porta na sua rede. Caso isso aconteça, você deve trocar a porta usada pelo broker ou pela outra aplicação.
Além disso, você pode também estar instalando uma aplicação no seu computador chamada MQTT explorer, essa aplicação nos permite enviar e ver os dados que estão trafegando no broker.
Lembrando que caso você use outro S.O, você deve procurar os devidos passos de como instalar o broker MQTT (Mosquitto) e o MQTT Explorer.
Código da conexão DHT11 + ESP32 e suas devidas explicações
Agora que já vimos como o sensor foi estruturado e como o broker funciona, vamos introduzir os passos que envolvem o código que será executado no ESP32, o mesmo vai fazer a comunicação com o sensor e será possível medirmos a temperatura e umidade do ambiente.
#include "DHT.h"
#include "WiFi.h"
#include "PubSubClient.h"
#include "esp_system.h"
#include "NTPClient.h"
#define DHTPIN 23
#define DHTTYPE DHT11
//Variaveis esp_random
uint64_t chipid = 0;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
DHT dht(DHTPIN, DHTTYPE);
WiFiUDP udp;
NTPClient ntp(udp, "a.st1.ntp.br", 0, 60000);
void setup()
{
Serial.begin(115200);
Serial.println("DHTxx test!");
//inicializa o sensor dht
dht.begin();
// Conectar WiFi
const char *SSID = ".....";
const char *PWD = ".....";
wifi_connect(SSID, PWD);
//servidor ntp
ntp.begin();
ntp.forceUpdate();
//MQTT
char *mqttServer = "192.168.1.10";
int mqttPort = 1883;
mqtt_connect(mqttServer, mqttPort);
//Mac Address ESP
chipid= ESP.getEfuseMac();
Serial.printf("%llu\n",chipid);
}
//Reconexao
void mqtt_reconnect ()
{
while (!mqttClient.connected())
{
Serial.printf("Reconnecting to Mqtt Broker ..\n");
if (mqttClient.connect("ESP32_DHT11"))
{
Serial.printf("Conecting \n");
mqttClient.subscribe("/commands");
}
}
Serial.printf("Connected to Mqtt Broker ...\n");
}
void wifi_connect (const char *SSID, const char *PWD)
{
WiFi.begin(SSID,PWD);
while (WiFi.status() != WL_CONNECTED)
{
Serial.printf("...");
delay(500);
}
Serial.print("Connected.\n");
Serial.println(WiFi.localIP());
}
void mqtt_connect (const char *server, int port)
{
mqttClient.setServer(server, port);
mqttClient.setCallback(mqtt_callback);
if (mqttClient.connect("ESP32_DHT11"))
{
Serial.printf("Connecting ...\n");
mqttClient.subscribe("/commands");
}
}
//CallBack
void mqtt_callback(char* topic, byte* payload, unsigned int length)
{
Serial.print("Callback - Message:");
for (uint i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
}
}
void loop()
{
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
if (isnan(humidity) || isnan(temperature))
{
Serial.println("Failed to read from DHT sensor!\n");
return;
}
Serial.printf("Umidade: %.2f \n", humidity, "%");
Serial.printf("Temperatura: %.2f °C \n", temperature);
// pega a hora via ntp
long time = ntp.getEpochTime();
// Verificando conexao
if (!mqttClient.connected())
{
mqtt_reconnect();
}
mqttClient.loop();
//variavel usada para receber o retorno da funcao millis
long now = millis();
//variavel estatica usada para receber o valor de now
static long last_time = 0;
//envio de 5 em 5 segundos os valores do sensor para o broker mqtt
if(now - last_time >5000)
{
//DHT11 Read
char data [128] = {0};
snprintf(data,128,"{\"Id\":%llu,\"Temperature\":%.2f,\"Date\":%ld,\"Humidity\":%.2f}", chipid, temperature, time, humidity);
mqttClient.publish("dht/data", data);
last_time=now;
}
delay(1000);
}
Explicando o código:
1 – Importando as bibliotecas e definição de algumas diretivas
Nessa etapa iremos importar as bibliotecas necessárias para o código executar, incluindo a biblioteca do DHT11 que instalamos no início do projeto e a biblioteca para a comunicação MQTT.
#include "DHT.h"
#include "WiFi.h"
#include "PubSubClient.h"
#include "esp_system.h"
#include "NTPClient.h"
#define DHTPIN 23
#define DHTTYPE DHT11
//Variaveis esp_random
uint64_t chipid = 0;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
DHT dht(DHTPIN, DHTTYPE);
WiFiUDP udp;
NTPClient ntp(udp, "a.st1.ntp.br", 0, 60000);
Além disso, é definido algumas variáveis e diretivas de compilação, como por exemplo: na linha 8 foi determinado que o pino ao qual ligamos o DHT11 no ESP32 é o 23 (lembrando que a escolha do pino fica ao seu critério).
Alguns objetos são criados:
- “WiFiClient” que se conecta em um endereço de IP e porta específico, esse objeto será usado como parâmetro para a criação do objeto MQTT que vai nos permitir configurar e publicar as informações no broker.
- Objeto DHT, que vai receber como parâmetro o tipo do sensor DHT e o pino ao qual ele vai se comunicar com o microcontrolador.
- Objeto WiFiUDP que tem como propósito enviar e receber mensagens UDP, esse objeto será usado como parâmetro para a criação do objeto NTP que é um protocolo que retorna em unix time a hora e data atualizada e usa o protocolo UDP para a comunicação.
2 – Função SETUP
void setup()
{
Serial.begin(115200);
Serial.println("DHTxx test!");
//inicializa o sensor dht
dht.begin();
// Conectar WiFi
const char *SSID = ".....";
const char *PWD = ".....";
wifi_connect(SSID, PWD);
//servidor ntp
ntp.begin();
ntp.forceUpdate();
//MQTT
char *mqttServer = "192.168.1.10";
int mqttPort = 1883;
mqtt_connect(mqttServer, mqttPort);
//Mac Address ESP
chipid= ESP.getEfuseMac();
Serial.printf("%llu\n",chipid);
}
A função de setup, é onde inicializamos algumas funções importantes e determinamos certos valores para variáveis, a fim de “configurar” o nosso sistema, segue uma explicação mais detalhada dessa função:
INICIALIZAÇÕES:
- É inicializado o objeto do DHT que foi criado no passo anterior.
- É inicializado o objeto do Wi-Fi, que recebe como parâmetro as variáveis SSID e PWD que são respectivamente: nome da sua rede Wi-Fi e a senha da mesma.
- É Inicializado o NTP que é o servidor que usamos para obter a data e hora atual em formato unix.
void wifi_connect (const char *SSID, const char *PWD)
{
WiFi.begin(SSID,PWD);
while (WiFi.status() != WL_CONNECTED)
{
Serial.printf("...");
delay(500);
}
Serial.print("Connected.\n");
Serial.println(WiFi.localIP());
}
Logo após, é executada a função wifi_connect() que tem como objetivo fazer a conexão do microcontrolador com a sua rede Wi-Fi.
void mqtt_connect (const char *server, int port)
{
mqttClient.setServer(server, port);
mqttClient.setCallback(callback);
if (mqttClient.connect("ESP32_DHT11"))
{
Serial.printf("Connecting ...\n");
mqttClient.subscribe("/commands");
}
}
Além disso, é executado também a função mqtt_connect() que tem como objetivo fazer a conexão com o servidor broker MQTT, a função recebe como parâmetros: IP da máquina onde o Broker MQTT está executando e a porta do broker, que por padrão é 1883. Meu computador, onde o broker foi instalado, tem o IP 192.168.0.10, mas o seu provavelmente será diferente e você deve alterá-lo, nesse caso, não se deve usar o localhost: 127.0.0.1, pois nesse caso será entendido que o broker está instalado no microcontrolador.
Explorando um pouco mais como foi construída a função mqtt_connect(), podemos ver que a mesma executa duas funções, sendo estas: mqttClient.setServer() e a mqttClient.setCallback().
A função setServer() aponta ao IP e a porta que a aplicação do broker MQTT utiliza para que possamos acessar a ferramenta. Já a função setCallback(), é a função de callback do MQTT, ou seja, uma função que vai sempre ser chamada quando um evento assíncrono acontece e dispara um gatilho que chama essa função, no caso o gatilho acontece quando uma nova mensagem é recebida.
void mqtt_callback(char* topic, byte* payload, unsigned int length)
{
Serial.print("Callback - Message:");
for (uint i = 0; i < length; i++) ]
{
Serial.print((char)payload[i]);
}
}
A função mqtt_callback() é criada seguindo o padrão apresentado na documentação da biblioteca PubSubClient que usamos para se comunicar com o broker.
E por fim na função setup, é feito a captura do MAC (valor único de cada dispositivo) do ESP32, pois usaremos este valor para identificar qual dispositivo está enviando os dados para o MQTT.
3 — Função LOOP
Na função loop o seu código irá rodar sem parar até que você o mande parar através de comandos ou o microcontrolador desligue.
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
if ( isnan(humidity) || isnan(temperature) )
{
Serial.println("Failed to read from DHT sensor!\n");
return;
}
Serial.printf("Umidade: %.2f \n", humidity, "%");
Serial.printf("Temperatura: %.2f °C \n", temperature);
// pega a hora via ntp
long time = ntp.getEpochTime();
// Verificando conexao
if ( !mqttClient.connected() )
{
mqtt_reconnect();
}
mqttClient.loop();
Inicialmente nessa função, é criado as variáveis responsáveis por armazenar os valores do sensor que se referem a umidade e a temperatura. Além disso, é feito uma verificação se os valores enviados pelo sensor são realmente números, por vezes pode ocorrer mal contato entre as ligações do hardware.
Logo após, é criado a variável time que recebe o retorno da função getEpochTime() da biblioteca NTP que é referente a hora atual de quando os dados do sensor foram capturados, que posteriormente será enviada junto com os outros dados para ser armazenado no banco de dados.
Em seguida, é feita a verificação da conexão do broker MQTT através da função mqtt_reconnect(), essa função tem como objetivo reconectar o ESP32 ao broker, caso o mesmo esteja desconectado.
Logo após é executada a função mqttClient.loop(), ela tem como propósito, executar mesmo que invisível aos nosso olhos, funções que: Verificam novamente se o mqtt continua ou não conectado e verificar se há mensagens recebidas no tópico, caso não exista ela irá chamar a função de callback que já vimos anteriormente.
void mqtt_reconnect ()
{
while (!mqttClient.connected())
{
Serial.printf("Reconnecting to Mqtt Broker ..\n");
if (mqttClient.connect("ESP32_DHT11"))
{
Serial.printf("Connecting \n");
mqttClient.subscribe("/commands");
}
}
Serial.printf("Conected to Mqtt Broker ...\n");
}
Explorando um pouco mais como foi construída a função mqtt_reconnect(), que irá se reconectar com o broker caso necessário através da função mqttClient.connect() sendo o parâmetro dessa função o clientID, ou seja, um identificador único que você vai dar para a sua placa para que possamos saber quando a mesma subscrever ou escrever algo no broker, nesse caso, você pode usar um nome que você queira ou o próprio MAC do seu microcontrolador como identificador.
//variavel usada para receber o retorno da funcao millis
long now = millis();
//variavel estatica usada para receber o valor de now
static long last_time = 0;
//envio de 5 em 5 segundos os valores do sensor para o broker mqtt
if(now - last_time >5000)
{
//DHT11 Read
char data [128] = {0};
snprintf(data,128,"{\"Id\":%llu,\"Temperature\":%d,\"Hora\":%ld,\"Humidity\":%d}",chipid, esp_random(), time, esp_random());
mqttClient.publish("dht/data", data);
last_time=now;
}
delay(1000);
Em seguida, é feita uma verificação para saber se a diferença de tempo entre as duas variáveis: now (que recebe o retorno da função millis() que é o valor em milissegundos que representa a quanto tempo a placa está ativa) e last_time são maiores que 5 segundos, ou seja, será enviado os dados somente de 5 em 5 segundos (o tempo de 5 segundos foi determinado somente por preferência, fique a vontade para determinar o tempo que mais lhe convém), caso o tempo seja maior que 5 segundos é montado então a string em formato JSON para ser enviado os valores, que contém os dados:
- Id — Identificador único de cada placa que está conectada no broker, podendo assim identificar a qual placa pertence os dados armazenados no banco de dados.
- Temperatura — valores da temperatura atual capturada pelo DHT11.
- Umidade — valores da umidade atual capturada pelo DHT11.
- Hora — hora local atualizada.
Por fim, os dados de fato são publicados e é dado um delay() no código para que o mesmo não trave nessa única tarefa e seja dado o intervalo de 1 segundo para que possamos pegar os valores de 1 em 1 segundo.
Instalação e configuração do Banco de Dados
Agora que já fizemos toda a comunicação do broker com o ESP32 e o sensor, podemos iniciar a terceira etapa do projeto, que consiste em:
- Instalar e criar o Banco de Dados
Etapas básicas para criação do banco de dados
Não irei me aprofundar nesse tema, pois esse assunto detalhado é muito extenso o que o faz virar assunto para outro artigo.
O banco de dados escolhido foi o PostgreSQL, considerado um dos melhores do mercado. Porém, fica ao seu critério escolher este ou outro banco de dados de sua preferência para utilizar.
1 — Instale o banco de dados no seu computador.
Para a instalação do mesmo no sistema é necessário seguir o conjunto de comando detalhados pela própria desenvolvedora do banco:
https://www.postgresql.org/download/linux/ubuntu
Já para outros sistemas operacionais, fica como aditivo para você pesquisar como fazer essa instalação.
2- Crie o seu banco de dados e configure o mesmo
Após a instalação, deve-se então acessar o seu postgresql e criar o seu banco de dados com suas devidas tabelas para uso no projeto, além de também criar usuários e configurar permissões.
Para o acesso ao postgres no linux ubuntu, vai ser usado o psql, porém fica ao seu critério qual aplicação usar para acessar o banco de dados, para acessar use os comando:
- sudo su postgres
- psql
Os comandos acima são para acessar o postgresql com o usuário postgres, o recomendado que se você usar esse usuário, você deve trocar a senha do mesmo, com o comando abaixo:
- ALTER USER postgres WITH PASSWORD ‘123456’;
Caso deseje criar outro usuário com as devidas permissões sejam elas de leitura e ou escrita para usar no banco, use o comando:
- CREATE USER nome WITH PASSWORD ‘123456’;
Para criar o seu banco de dados, use o comando:
- CREATE DATABASE name;
E por fim, para criar tabela do banco que vai receber os dados do sensor, use o comando:
- CREATE TABLE dht_11 (id BIGINT, temperature real, humidity real, date bigint);
Lembrando que o seu banco de dados deve ter no mínimo uma tabela para uso e essa tabela deve conter colunas que servem para armazenar os dados que serão recebidos, fique a vontade para criar quantas colunas quiserem, mas novamente deve se ter no mínimo 4 colunas obrigatórias, sendo estas para armazenar os dados: ID, Temperatura, Umidade e Hora, para isso atente-se para criar colunas que suportam esse tipo de dado, como no exemplo acima.
Como dito anteriormente, não irei me aprofundar no tema, mas todas essas questões e etapas da criação do banco são fáceis de achar a solução através de pesquisas. Além disso, a própria documentação do PostgreSQL conta com essas etapas e como executá-las.
Documentação do PostgreSQL: https://www.postgresql.org/docs/
A tabela já com os dados deve ficar parecido com a imagem abaixo:
Código da conexão do banco de dados + Grafana e suas devidas explicações
Agora chegamos na etapa de comunicarmos os dados que estão no MQTT com o nosso banco de dados que vai ficar hospedado no nosso servidor (próprio computador).
Resumidamente, ao mesmo tempo que o seu código embarcado no microcontrolador estiver sendo executado, teremos o código que vai subscrever os dados do broker também sendo executado no seu computador.
Para este código, como o mesmo não tem comunicação com o ESP32 e com nenhum outro dispositivo como sensores, outros microcontroladores e etc, foi escolhido NodeJs como a linguagem de programação, mas acredite se você desenvolveu até aqui em C / C++, você não terá grandes dificuldades com NodeJs.
Para compilar e executar esse código no seu computador, você precisa instalar o NodeJs, no linux ubuntu os comando para instalação são:
- sudo apt update
- sudo apt install nodejs npm
Após a instalação verifique a versão do Node instalada, o recomendando para que as bibliotecas usadas no código funcionem é que a versão seja da 16.0 para cima.
Caso, a instalada seja abaixo da recomendada, você deve atualizar essa instalação, podendo para isso usar os comandos:
- curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
- source ~/.bashrc
1 — Importando as bibliotecas e definição de algumas diretivas
const mqtt = require('mqtt');
const { Pool, Client } = require('pg');
//Conexao do Banco
const client_database = new Client(
{
user: '......',
password: '......',
host: '127.0.0.1',
database: '......',
})
client_database.connect();
Inicialmente, nas primeiras linhas deste código, iremos importar as bibliotecas necessárias no código, que serão: a biblioteca pg que é a biblioteca que usaremos para se comunicar com o banco de dados criado no passo anterior, lembrando que o uso dessa biblioteca acontece porque foi usado o banco postgresql e a biblioteca mqtt para que possamos conectar nosso servidor ao mqtt e capturar as informações para serem enviadas ao banco de dados.
Em seguida, é criado um cliente (denominamos cliente a aplicação que vai consumir e se comunicar com o banco de dados) e declaramos os parâmetros necessários para a conexão com o banco, sendo estes:
- user: Nome do usuário que você criou para acessar o seu banco de dados, lembrando que esse usuário deve ter permissão de escrita para que possamos salvar os dados no banco.
- password: Senha que você designou para esse usuário de acesso ao banco de dados.
- host: IP do servidor onde seu banco de dados está hospedado, no caso, usamos o nosso próprio computador, então pode usar o IP de localhost do computador.
- database: Nome do seu banco de dados criado na etapa acima.
Após criado o cliente, devemos fazer a conexão do banco de dados, no caso, essa conexão é feita com a função client_database.connect().
// Conexao MQTT
const port = "1883";
const host = `mqtt://127.0.0.1:${port}`;
var client = mqtt.connect(host);
let topic = '#';
client.on('connect', function success()
{
console.log("Connecting MQTT");
client.subscribe(topic, function mqtt_subscribe()
{
console.log("Subscribe to" + topic);
});
});
Logo após, é feita a conexão com o broker MQTT, nesse caso diferente do código embarcado no ESP32 que é um publicador dos dados, esse código faz o papel de subscrição dos dados.
A função mqtt.connect() tem como objetivo fazer a conexão com o broker MQTT, essa conexão não trava o código enquanto se espera a resposta de sucesso ou não, ou seja, é uma função assíncrona, caso a conexão seja um sucesso, será emitido um evento chamado “connect”, exatamente por este motivo a função client.on() é executada pois a mesma espera pela emissão do evento “connect” declarado como parâmetro. Essa função ao detectar a conexão, chama uma função de callback, sendo esta a mesma função criada diretamente como o segundo parâmetro da função client.on().
A função de callback, executa a função client.subscribe() do MQTT, essa função como o próprio nome diz faz uma subscrição no tópico (declarado na variável topics) capturando então os dados enviados pelo ESP ao MQTT.
Antes que você se pergunte sobre o que significa o “#” no MQTT, ele é um wildcard (símbolo coringa). Quando utilizado em uma assinatura de tópico, o # permite “escutar” todos os tópicos que surgirem no broker a partir do ponto onde ele é usado. Isso inclui, por exemplo, o tópico específico dht/data, que é o tópico no qual o ESP32 está publicando os dados do sensor.
Em outras palavras, se você assinar um tópico com “#”, como “dht/#”, você receberá todas as mensagens publicadas em qualquer subnível de “dht/”, incluindo “dht/data”.
client.on('message', mqtt_message);
function mqtt_message(topic, message)
{
var J = JSON.parse(message);
var T = J.Temperature;
var H = J.Humidity;
var D = J.Date;
var I = J.Id;
console.log('topic'+ topic + ' Message' + message);
// Insercao
const q="INSERT INTO dht11_data(id, temperature, humidity, date) VALUES($1,$2,$3,$4) RETURNING*";
const v =[I, T, H, D];
client_database.query(q,v, (err, res) => {
if (err)
{
console.log(err.stack)
}
else
{
console.log(res.rows[0])
}
});
}
Novamente a função client.on() é chamada, agora com o objetivo de esperar a emissão do evento “message”, esse evento é emitido quando uma nova mensagem chega ao broker nos tópicos que o seu cliente está inscrito, acionando então a função de callback declarada na função client.on(), chamada de mqtt_message().
A função mqtt_message() é a função que irá tratar a mensagem recebida via broker, no caso, será feito um parser das informações que chegaram em formato JSON, após a separação desses dados é criado uma query (instrução para o banco de dados) que irá fazer um insert do seus dados no banco. Por fim, é enviado ao banco de dados a query, gravando então as informações no banco.
Instalação e configuração do Grafana
Nessa etapa iremos instalar o Grafana, configurar o básico para o seu funcionamento, assim teremos então a possibilidade de criar as dashboards de acordo com as informações do banco de dados.
Etapas básicas da instalação e configuração do Grafana
1 — Instale o Grafana no seu computador.
Para a instalação do Grafana, é necessário seguir o conjunto de comando detalhados no site da aplicação, conforme o seu Sistema Operacional:
https://grafana.com/grafana/download?pg=oss-graf&plcmt=hero-btn-1.
Se atente na hora da escolha da versão do Grafana, é sempre indicado escolher a versão mais recente. Além disso, atente-se também em escolher a edição OSS (edição para uso livre e gratuito).
Após a instalação é recomendado novamente usar o comando systemctl status grafana para verificar se o Grafana, após instalado, já está ativo. Caso o mesmo apareça como STOPPED, use o comando abaixo para iniciar a sua aplicação: systemctl start grafana
Outro fator é que, por padrão, o Grafana usa a porta 3000 para executar a sua aplicação, porém fique atento caso alguma outra aplicação do seu computador já esteja usando essa porta, se isso acontecer você deve mudar a porta.
Nesse caso, o arquivo ao qual você deve acessar para mudar a porta, muda de localização conforme o Sistema Operacional que você está usando e instalou o Grafana, nesse caso usando Linux Ubuntu para acessar esse arquivo, siga o caminho:
- Acesse o diretório /etc/grafana
- Abra com permissão de sudo o arquivo grafana.init.
- Ache onde está a variável que guarda o valor da porta e mude.
- Salve o arquivo.
Conforme na imagem a seguir:
Para mais informações, acesse:
2- Acessando e configurando o Grafana
Após a instalação, para acessar o Grafana, vá para o seu navegador e use o localhost da sua máquina com a porta do Grafana para acessá-lo: 127.0.0.1:3000
Caso esteja tudo certo, você deve ver uma tela como essa aparecendo:
O usuário e senha para o primeiro acesso é padrão, sendo respectivamente: admin, admin.
Após o primeiro acesso, fica a seu critério trocar a senha do usuário admin, ou como iremos ver logo em seguida, criar um outro usuário para acesso.
O recomendando é que mesmo que você crie um novo usuário para uso, você deve trocar a senha do usuário admin.
3 — Criando um novo usuário
- Acesse a barra lateral e vá em Administração (Figura 1)
- Acesse a aba de usuários e acessos (Figura 1)
- Vá em usuários (Figura 1)
- Clique em novo usuário (Figura 1)
- Preencha as informações (Figura 1), sendo estas:
- Nome: nome da pessoa que será o novo usuário.
- Email: email que deseja atrelar a esse novo usuário (não obrigatório).
- Username: nome do usuário.
- Password: senha de acesso ao novo usuário.
- Após criar o usuário, irá aparecer uma tela para habilitar as permissões que você deseja dar a esse usuário. Por exemplo: você pode dar permissão de admin para o novo usuário ou você pode querer que esse novo usuário só tenha acesso a algumas dashboards e painéis específicos). (Figura 2)
4 — Conexão do banco de dados com o Grafana
Nessa etapa iremos conectar o banco de dados criado na etapa 2.
- Acesse a barra lateral e vá em Administração (Figura 3)
- Acesse a aba de conexões (Figura 3)
- Escolha o modelo de Banco de Dados que você usou para criar o banco no passo anterior(caso seja o postgresql, irá aparecer 2 quando procurar por nome, basta escolher qualquer opção) (Figura 3)
- Clique em Adicionar nova fonte de dados (Figura 3)
- Preencha as informações (Figura 4 e 5) referentes a conexão com a sua fonte de dados, sendo estas as principais:
- Nome: Você pode trocar o nome dado pelo Grafana a sua conexão de dados, fique a vontade!
- Host URL: IP do seu banco de dados, no caso, seguindo o mesmo IP que colocamos no código que envia as informações para o banco de dados, temos o IP: 127.0.0.1:5432.
- Nome do banco: nome que você deu ao seu banco quando criou o mesmo.
- Nome do usuário: nome do usuário criado para acessar o seu banco de dados quando você estava criando o mesmo. Lembre-se: o usuário deve ter a permissão de leitura desse banco.
- Senha: Senha do usuário do banco de dados.
- As informações envolvendo TLS/SSL e opções adicionais do seu banco de dados, fica ao seu critério alterar ou não. Atente-se no campo versão nas opções adicionais do banco de dados nessa mesma tela, pois ali você irá colocar a versão do seu banco de dados atualmente (Figura 5).
5 — Criando as Dashboards
- Acesse a barra lateral e vá em Dashboards (Figura 6).
- Clique em Novo -> Nova Dashboard OU Criar Dashboard (Figura 6).
- Clique em Adicionar Visualização (Figura 6).
- Escolha o banco de dados que você deseja visualizar os dados (Figura 7).
- Edite o seu primeiro gráfico do modo que achar melhor (há dois modos: usando o builder que “facilita” para quem não entende muito sobre query o uso das tabelas e como “pegar” e “transformar” esses dados e code que permite que você programe em SQL e crie sua query e com isso “pegue” e mostre os dados também) e clique em Aplicar (Figura 8).
- Para salvar a dashboard, clique no ícone de gravador na página.
Após as etapas acima, o mesmo irá liberar o uso dos gráficos para você, a partir daqui você está livre para explorar a infinidade de ferramentas dentro do Grafana e criar suas diversas dashboards com quantos dados e bancos de dados forem necessários.
Abaixo, segue um exemplo de gráficos simples com os dados do sensor armazenados no banco de dados:
Dessa forma finalizamos o projeto, porém caso você esteja buscando por desafios e queira deixar esse projeto com um maior nível de dificuldade, você pode implementá-lo usando o FreeRTOS que é um dos Sistema operacionais ao qual o ESP32 suporta.
Os códigos completos deste projeto está no link abaixo:
https://github.com/MariaLgA/Projeto_esp32
Espero que este artigo tenha contribuído de formas positivas no seu aprendizado! ????










Ótimo artigo
Fico feliz que tenha gostado Michael!