O objetivo aqui é construir um sistema que coleta dados de temperatura e umidade usando o sensor DHT22 e os envia para um servidor InfluxDB para armazenamento e análise juntamente com um servidor Grafana. O ESP32 atua conectando o sensor ao Wi-Fi e gerenciando a comunicação com o InfluxDB.
Hardware Necessário
- ESP32: Microcontrolador com Wi-Fi e Bluetooth integrados, ideal para projetos IoT de baixo custo e baixo consumo de energia.
- DHT22: Sensor de temperatura e umidade conhecido por sua precisão adequada, baixo custo e facilidade de uso.
- Conexão Wi-Fi: Para conectar o ESP32 à internet e enviar dados para o InfluxDB.
Pinagem
Sensor DHT22:
- VCC: Conectado ao pino 3.3V do ESP32 para alimentação.
- GND: Conectado ao pino GND do ESP32 para aterramento.
- DHTPIN: Pino de dados conectado a um pino GPIO do ESP32
Observação: O pino específico do ESP32 usado para DHTPIN será definido no código como 18.
Configuração do Projeto no VSCode com PlatformIO
O arquivo platformio.ini
define as bibliotecas necessárias e a configuração do ambiente:
[env:upesy_wroom]
platform = espressif32
board = upesy_wroom
framework = arduino
lib_deps =
adafruit/DHT sensor library@^1.4.6
arduino-libraries/NTPClient@3.1.0
tobiasschuerg/ESP8266 Influxdb@^3.13.1
INIAnálise do Código Fonte
Neste projeto eu inclui uma biblioteca NTP por puro luxo de querer imprimir na porta Serial a data e hora da leitura, Não há utilizamos para escrever os datapoints no influxdb.
Declaração do DHT22
#include <Adafruit_Sensor.h>
#include <DHT.h>
#define DHTPIN 18
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
C++Conexão com WIFI
#include <WiFi.h>
#include <WiFiUdp.h>
const char* ssid = "MINHA_WIFI";
const char* password = "MINHA_SENHA";
void setup() {
// CÓDIGO
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(2500);
Serial.println("Conectando à rede WiFi...");
}
Serial.println("Conectado à rede WiFi");
// CÓDIGO
}
//CÓDIGO
C++Declaração do InfluxDB e Inicialização
Aqui iremos iniciar a conexão com o InfluxDB e criar uma váriavel de sensor que aponta para o Banco de dados clima do InfluxDB
#include <InfluxDbClient.h>
#define INFLUXDB_URL "http://influx.mfs.eng.br:8086"
// InfluxDB database name
#define INFLUXDB_DB_NAME "clima"
// InfluxDB user name
#define INFLUXDB_USER "esp32"
// InfluxDB password
#define INFLUXDB_PASSWORD "esp32_password"
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_DB_NAME);
Point sensor("clima");
void setup() {
//CODIGO
// Configuração do cliente InfluxDB
client.setConnectionParamsV1(INFLUXDB_URL, INFLUXDB_DB_NAME, INFLUXDB_USER, INFLUXDB_PASSWORD);
}
//CODIGO
C++Coletando Dados do DHT22
void setup() {
//CODIGO
dht.begin();
//CODIGO
}
void loop() {
//CODIGO
float tempValue = dht.readTemperature();
float humidityValue = dht.readHumidity();
//CODIGO
if (!isnan(tempValue) && !isnan(humidityValue)) {
//CODIGO
Serial.print(" - Temperatura: ");
Serial.print(tempValue);
Serial.print(" °C, Umidade: ");
Serial.print(humidityValue);
Serial.println(" %");
}
delay(60000); // Aguarda 60 segundos antes da próxima leitura
}
C++Envio de Dados para InfluxDB
//CODIGO
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_DB_NAME);
Point sensor("clima");
//CODIGO
void loop() {
float tempValue = dht.readTemperature();
float humidityValue = dht.readHumidity();
if (!isnan(tempValue) && !isnan(humidityValue)) {
// Limpa os campos do ponto de dados
sensor.clearFields();
// Adiciona os campos ao ponto de dados
sensor.addField("temperature", tempValue);
sensor.addField("humidity", humidityValue);
// Escreve o ponto de dados no InfluxDB
if (!client.writePoint(sensor)) {
Serial.print("InfluxDB write failed: ");
Serial.println(client.getLastErrorMessage());
}
}
delay(60000); // Aguarda 60 segundos antes da próxima leitura
}
C++Vantagens do InfluxDB
Num outro post no futuro, tentarei explicar as vantagens do InfluxDB. Por hora:
Banco de dados de séries temporais: Perfeito para armazenar e analisar dados que mudam ao longo do tempo.
Escalabilidade: Capacidade de lidar com grandes volumes de dados.
Integração com Grafana: Permite visualizar os dados de forma clara e intuitiva.
Visualização no Grafana
Abaixo o Gráfico criado com Grafana e InfluxDB baseado nos dados enviados pelo DHT22 e o ESP32
https://grafana.mfs.eng.br/dashboard/snapshot/QXbgVFpsYpZJnLCsvEIDQYYMvk0AUt5Z
Código Completo
Este projeto demonstra como o ESP32 e o InfluxDB podem ser usados para criar um sistema de monitoramento climático eficaz. Neste artigo não abordamos como configurar o InfluxDB e o Grafana, isso fica para uma próxima.
https://gitlab.com/mfs.eng.br/hardware-quirks/temperatura_esp32
main.cpp
#include <Arduino.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <InfluxDbClient.h>
#include "config.h"
const char* ssid = WIFI_SSID;
const char* password = WIFI_PASSWORD;
#define DHTPIN 18
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "time-a-g.nist.gov");
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_DB_NAME);
Point sensor("clima");
void setup() {
Serial.begin(9600);
dht.begin();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(2500);
Serial.println("Conectando à rede WiFi...");
}
Serial.println("Conectado à rede WiFi");
timeClient.begin();
timeClient.setTimeOffset(-3*60*60); // Ajuste para o fuso horário de -3 horas (Brasil)
// Configuração do cliente InfluxDB
client.setConnectionParamsV1(INFLUXDB_URL, INFLUXDB_DB_NAME, INFLUXDB_USER, INFLUXDB_PASSWORD);
}
void loop() {
timeClient.update();
float tempValue = dht.readTemperature();
float humidityValue = dht.readHumidity();
unsigned long timestamp = timeClient.getEpochTime();
time_t timeObj = timestamp;
struct tm* timeinfo = localtime(&timeObj);
char dataFormatada[20];
strftime(dataFormatada, sizeof(dataFormatada), "%d/%m/%Y", timeinfo);
if (!isnan(tempValue) && !isnan(humidityValue)) {
// Limpa os campos do ponto de dados
sensor.clearFields();
// Adiciona os campos ao ponto de dados
sensor.addField("temperature", tempValue);
sensor.addField("humidity", humidityValue);
// Adiciona a timestamp ao ponto de dados
//sensor.setTime(timestamp);
// Escreve o ponto de dados no InfluxDB
if (!client.writePoint(sensor)) {
Serial.print("InfluxDB write failed: ");
Serial.println(client.getLastErrorMessage());
}
// Escreve os dados no serial com o log de data
Serial.print(dataFormatada);
Serial.print(" ");
Serial.print(timeClient.getFormattedTime());
Serial.print(" - Temperatura: ");
Serial.print(tempValue);
Serial.print(" °C, Umidade: ");
Serial.print(humidityValue);
Serial.println(" %");
}
delay(60000); // Aguarda 60 segundos antes da próxima leitura
}
C++config.h
#define WIFI_SSID "seu_SSID_wifi"
#define WIFI_PASSWORD "sua_senha_wifi"
#define INFLUXDB_URL "http://seu_servidor_influxdb:8086"
#define INFLUXDB_DB_NAME "nome_do_banco_de_dados"
#define INFLUXDB_USER "usuario_influxdb"
#define INFLUXDB_PASSWORD "senha_influxdb"
C++[/et_pb_text][/et_pb_column]
[/et_pb_row]
[/et_pb_section]