#include <EspMQTTClient.h> // EspMQTTClient
#include <ArduinoJson.h> // ArduinoJson
#include <OneWire.h>
#include <DallasTemperature.h>
#define PINO_TRIG 4
#define PINO_ECHO 2
#define ONE_WIRE_BUS 23 // GPIO where the DS18B20 is connected to
#define PORTA_ANALOGICA 35 // Porta analógica para leitura do sensor de turbidez
float distanciaAnterior = 0.0;
float ntuAnterior = 0.0;
bool mudouValorSensores = false;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
// Conexões WI-FI e MQTT
EspMQTTClient client(
"TesteBruno", // Rede wi-fi
"123456789a", // Senha wi-fi
"mqtt.tago.io", // Broker
"Default", // Usuário (qq string)
"ab48b959-3f67-4222-9d09-3d8e27e13e94", // Token da plataforma Tago.io
"SA_IOT_2024" // Identificação única (qq string)
);
// Função para arredondar um número float para uma casa decimal específica
float arredondar(float numero, int casasDecimais) {
float multiplicador = pow(10, casasDecimais);
int parteInteira = (int)numero;
float parteDecimal = numero - parteInteira;
int parteDecimalArredondada = round(parteDecimal * multiplicador);
float valorArredondado = parteInteira + parteDecimalArredondada / multiplicador;
return valorArredondado;
}
// Função para calcular a média de 100 leituras analógicas
int leituraAnalogicaMedia() {
int somaAnalogValue = 0;
for (int i = 0; i < 100; i++) {
somaAnalogValue += analogRead(PORTA_ANALOGICA);
}
return somaAnalogValue / 100;
}
// Define a função de callback associada ao delay
void delayedFunction() {
DynamicJsonDocument dados(1024);
String dadosJson;
// Leitura da distância do sensor HC-SR04
mudouValorSensores = false;
digitalWrite(PINO_TRIG, LOW);
delayMicroseconds(2);
digitalWrite(PINO_TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(PINO_TRIG, LOW);
long duracao = pulseIn(PINO_ECHO, HIGH); // Mede o tempo de resposta do ECHO
float distanciaAtual = (duracao * 0.0343) / 2; // Calcula a distância usando a velocidade do som (aproximadamente 343 m/s)
// Leitura da temperatura do sensor DS18B20
sensors.requestTemperatures();
float temperatureC = sensors.getTempCByIndex(0);
// Leitura do sensor de turbidez
int analogValue = leituraAnalogicaMedia();
float NTU = -0.0047313 * analogValue * analogValue - 3.1029 * analogValue + 2983.5;
// Arredondamento dos valores para uma casa decimal
float distanciaArredondada = arredondar(distanciaAtual, 1);
float temperaturaArredondada = arredondar(temperatureC, 1);
float NTUArredondado = arredondar(NTU, 1);
// Verifica se algum dos sensores mudou valor, caso afirmativo (true), atualiza estrutura Json
if (distanciaArredondada != distanciaAnterior || NTUArredondado != ntuAnterior) {
mudouValorSensores = true;
distanciaAnterior = distanciaArredondada;
ntuAnterior = NTUArredondado;
}
// Verifica se algum dos sensores mudou valor, caso afirmativo, atualiza a estrutura Json
if (mudouValorSensores) {
// Insere os dados do sensor de distância na estrutura Json
JsonObject distancia = dados.createNestedObject();
distancia["variable"] = "valor_distancia";
distancia["unit"] = "cm";
distancia["value"] = distanciaArredondada;
// Insere os dados do sensor de temperatura na estrutura Json
JsonObject temperatura = dados.createNestedObject();
temperatura["variable"] = "temperatura";
temperatura["unit"] = "C";
temperatura["value"] = temperaturaArredondada;
// Insere os dados do sensor de turbidez na estrutura Json
JsonObject turbidez = dados.createNestedObject();
turbidez["variable"] = "turbidez";
turbidez["unit"] = "NTU";
turbidez["value"] = NTUArredondado;
// Conversão da estrutura de dados (JSON) para string
serializeJson(dados, dadosJson);
// MQTT (Publish) e controle (alteração de valores)
Serial.println("Publicando a leitura dos sensores de qualidade da água....");
Serial.println(dadosJson);
client.publish("le_dados_qualidade_agua", dadosJson);
}
// Chama novamente a função de callback após um intervalo de tempo
client.executeDelayed(5000, delayedFunction);
}
// Setup
void setup() {
// alteração dos parâmetros default por causa das desconexões frequentes
// do wifi dummy do wokwi
client.enableMQTTPersistence();
client.setMqttReconnectionAttemptDelay(2000);
client.setWifiReconnectionAttemptDelay(3000);
client.setKeepAlive(20);
// habilita msgs de debug
client.enableDebuggingMessages(true);
client.setMaxPacketSize(256);
// delay com callback, não posso usar delay(x ms)
// devido a conexão wifi
client.executeDelayed(5000, delayedFunction);
// configura pinos do sensor HC-SR04
pinMode(PINO_TRIG, OUTPUT); // Configura o pino TRIG como saída
pinMode(PINO_ECHO, INPUT); // Configura o pino ECHO como entrada
// Start the Serial Monitor
Serial.begin(115200);
// Set resolution for analog read
analogReadResolution(10);
// Start the DS18B20 sensor
sensors.begin();
}
// Loop
void loop() {
client.loop();
}
// MQTT (Subscribe)
void onConnectionEstablished() {
Serial.println("Conexao com tago.io estabelecida, assinando topicos...");
Serial.println("Assinando o topico que atualiza os dados de qualidade da água.....");
client.subscribe("le_dados_qualidade_agua", [] (const String &payload) {
// Add code here if you want to process the subscribed messages
});
}