//==============================
// Bibliotecas
//==============================
#include <OneWire.h>
#include <DallasTemperature.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <Arduino.h>
//==============================
// Mapeamento de Hardware
//==============================
#define flow_Sensor 4 //Define o pino 4 comoo sensor de Vazão
#define temperature_Sensor 18 //Define o Pino 18 como sensor de Temperatura
#define humidity_Sensor 34 //Define o Pino 23 como o sensor de Umidade
//==============================
// Váriaveis Globais
//==============================
//Vazão
double flowRate; //Este é o valor que pretende-se calcular
volatile int pulso; //Este número precisa ser setado como volátil para garantir que seja atualizado durante a interrupção
int pulso_por_l = 450; //Quantidade de pulso em 1 litro
//Tempo
unsigned long tempo_vazao = 0; //Setando o tempo da vazão para 0
unsigned long tempo_umidade_temperatura = 0; //Setando o tempo da umidade para 0
const int intervalo_vazao = 1000; //Deixando o tempo de vazão com contagem de 1 segundo
const int intervalo_umidade_temp = 5000; //Deixando o tempo de umidade e temperatura com contagem de 5 segundo
//Temperatura
OneWire oneWire(temperature_Sensor); //Juntado o fio de sinal dos sensores em uma lógica
DallasTemperature sensors(&oneWire); //Pegando o sensor que desejo e conctando ele a biblioteca e ao ESP32
//Váriavies de Armazenamento
float TemperatureC = 0.0;
int porcentagem_Umidade = 0;
String classificacao_Umidade = "";
//Váriaveis do MQTT
//const char* ssid = "TCC-Project";
//const char* password = "";
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqttServer = "broker.emqx.io"; //"test.mosquitto.org";"broker.mqtt.project";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
//==============================
// Protótipos de Funções
//==============================
void Flow();
void calculoVazao();
void sensorTemperaturaC();
void sensorUmidade();
int dadosPorcentagemUmidade(int valor);
String dadosClassificacaoUmidade(int porcentagem);
void dashboard();
void setup_wifi();
void callback(char* topico, byte* mensagem, unsigned int largura);
void reconnect();
void publicarDados();
//==============================
// Configuração Principal
//==============================
void setup() {
//Comunicação Serial
Serial.begin(115200); //Inicia o Serial
delay(1000);
// Inciando comunicação de Setup do MQTT
setup_wifi();
client.setServer(mqttServer, 1883);
client.setCallback(callback);
// Sensor de Vazão
pinMode(flow_Sensor, INPUT_PULLDOWN); //Seta o pino de entrada
attachInterrupt(digitalPinToInterrupt(flow_Sensor), Flow, RISING); //Configura o interruptor 0 (pino 2 no Arduino Uno) para rodar a função flowRate
//Sensor de Temperatura
pinMode(temperature_Sensor, INPUT_PULLUP); //Definindo o pino como entrada de dado
sensors.begin(); //Iniciando a leitura do sensor
// Sensor de Umidade
//ADC não precisa definir o tipo de entrada do pino
//Imprimindo Serial
Serial.println("\n╔══════════════════════════════════════╗");
Serial.println("║ SISTEMA DE MONITORAMENTO INICIADO ║");
Serial.println("╚══════════════════════════════════════╝\n");
}
//==============================
// Configuração Loop
//==============================
void loop() {
//Chamando função para reconectar o cliente
if (!client.connected()) {
reconnect();
}
client.loop();
//Configuração da função millis()
unsigned long tempo_Atual = millis();
//Setando o tempo de leitura para 1 segundo no sensor de vazão
if((tempo_Atual - tempo_vazao) >=intervalo_vazao ){
tempo_vazao = tempo_Atual;
calculoVazao();
publicarDados();
}
if((tempo_Atual - lastMsg) > 5000){
lastMsg = tempo_Atual;
}
//Setando o tempo de leitura para 5 segundos nos sensores de temperatura e umidade
if((tempo_Atual - tempo_umidade_temperatura) >= intervalo_umidade_temp){
tempo_umidade_temperatura = tempo_Atual;
sensorTemperaturaC();
sensorUmidade();
dashboard();
}
}
//==============================
// Funções Auxiliares
//==============================
void ARDUINO_ISR_ATTR Flow(){
pulso++; //Quando essa função é chamada, soma-se 1 a variável no pulso
}
//Vazão [YF-S201]
void calculoVazao(){
//Cálculos matemáticos
float ml_p_pulso = 1000 / pulso_por_l; // Calculando milimetros por pulos
flowRate = (pulso * ml_p_pulso); //Conta os pulsos no último segundo e multiplica por 2,25mL, que é a vazão de cada pulso
flowRate = flowRate * 60; //Converte segundos em minutos, tornando a unidade de medida mL/min
flowRate = flowRate / 1000; //Converte mL em litros, tornando a unidade de medida L/min
//Código do pulso do Sensor de Vazão
noInterrupts();
int pulso_atual = pulso;
pulso = 0;
interrupts();
}
//Temperatura [DS18B20]
void sensorTemperaturaC(){
sensors.requestTemperatures();
TemperatureC = sensors.getTempCByIndex(0);
//Condição de Erro
if(TemperatureC == -127 || TemperatureC == 85){
Serial.println("ERRO: Leitura da Temperatura inválida!");
return;
}
}
//Umidade [DH-38]
void sensorUmidade(){
int valor = analogRead(humidity_Sensor);
Serial.println(valor);
//Condição de Erro
if(valor > 4000 || valor < 100){
Serial.println("AVISO: Leitura de Umidade suspeita!");
return;
}
else{
//Cálculo de Porcentagem e classificação
porcentagem_Umidade = dadosPorcentagemUmidade(valor);
classificacao_Umidade = dadosClassificacaoUmidade(porcentagem_Umidade);
}
}
//Convertendo os dados analógicos do sensor em números entre 0 e 100 de acordo com o ajuste do sensor de Umidade.
int dadosPorcentagemUmidade(int valor){
int porcentagem = map(valor, 4095, 0, 0, 100);
porcentagem = constrain(porcentagem, 0, 100);
return porcentagem;
}
//Classificando o estado da superfície
String dadosClassificacaoUmidade(int porcentagem){
if(porcentagem <= 20){
return "Muito Seco";
}
else if(porcentagem <= 40){
return "Seco";
}
else if(porcentagem <= 60){
return "Ideal";
}
else if(porcentagem <= 80){
return "Úmido";
}
else{
return "Encharcado";
}
}
void dashboard(){
Serial.println("\n╔══════════════════════════════════════╗");
Serial.println("║ LEITURA DOS SENSORES ║");
Serial.println("╠══════════════════════════════════════╣");
Serial.print("║ Vazão: ");
Serial.print(flowRate, 2);
Serial.println(" L/min");
Serial.print("║ Temperatura: ");
Serial.print(TemperatureC);
Serial.println("°C");
Serial.print("║ Umidade: ");
Serial.print(porcentagem_Umidade);
Serial.print("% (");
Serial.print(classificacao_Umidade);
Serial.println(")");
Serial.println("╚══════════════════════════════════════╝");
}
//Configuração Principal da Rede
void setup_wifi(){
delay(10);
//Começando comunicação com a rede WiFi
Serial.println("");
Serial.print("Conectando ao ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("WiFi Conectado ");
Serial.println("Endereço de IP: ");
Serial.println(WiFi.localIP());
}
//Configurando a chegada da Mensagem
void callback(char* topico, byte* mensagem, unsigned int largura){
Serial.print("Mensagem chegou no tópico: ");
Serial.print(topico);
Serial.print(". Mensagem: ");
String mensagemTemp = "";
for (int i = 0; i < largura; i++){
Serial.print((char)mensagem[i]);
mensagemTemp += (char)mensagem[i];
}
Serial.println();
//Configurando a chegada dos dados da mensagem dos sensores
if (String(topico) == "tcc371/apresentacao/temperatura") {
if(mensagemTemp == "ler"){
Serial.println("Comando Recebido: Ler Temperatura");
sensorTemperaturaC();
publicarDados();
}
else if(mensagemTemp == "false"){
Serial.println("false");
sensorTemperaturaC();
publicarDados();
}
}
}
// Função para reconectar
void reconnect() {
// Loop até reconectar
while (!client.connected()) {
// Criar ID único
String clientId = "TCC371_ESP32_";
clientId += String(random(0xffff), HEX);
//Comunicando com o MQTT
Serial.print("Tentando conectar com o MQTT...");
// Tentativa de Reconectar
if (client.connect(clientId.c_str())) {
Serial.println("conectado");
// Inscrição
client.subscribe("tcc371/comando/#");
} else {
Serial.print("falha, rc=");
Serial.print(client.state());
Serial.println(" Tente novamente em 5 segundos");
// Espera de 5 segundos antes de tentar novamente
delay(5000);
}
}
}
// Função Publicar Dados
void publicarDados(){
// Publicar Temperatura
/*
snprintf(msg, 50, "%.2f", TemperatureC);
client.publish("tcc371/sensores/temperatura", msg);
Serial.print("Publicado temperatura: ");
Serial.println(msg);
*/
char tempString[8];
dtostrf(TemperatureC, 1, 2, tempString);
Serial.print("Temperature: ");
Serial.println(tempString);
client.publish("tcc371/sensores/temperatura", tempString);
// Publicar Umidade
/*
snprintf(msg, 50, "%d", porcentagem_Umidade);
client.publish("tcc371/sensores/umidade", msg);
Serial.print("Publicado umidade: ");
Serial.println(msg);
*/
// Publicar Vazão
/*
snprintf(msg, 50, "%.2f", flowRate);
client.publish("tcc371/sensores/vazao", msg);
Serial.print("Publicado vazão: ");
Serial.println(msg);
*/
char flowString[8];
dtostrf(flowRate, 1, 2, flowString);
Serial.print("Temperature: ");
Serial.println(flowString);
client.publish("tcc371/sensores/vazao", flowString);
}
/*
//Adaptado a partir de RandomNerdTutorials (Rui Santos) https://randomnerdtutorials.com/esp32-mqtt-publish-subscribe-arduino-ide/
#include "DHT.h"
#define DHTPIN 21 // Digital pin connected to the DHT sensor
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22
//#define DHTTYPE DHT21 // DHT 21
DHT dht(DHTPIN, DHTTYPE);
#include <WiFi.h>
#include <PubSubClient.h>
// Replace the next variables with your SSID/Password combination
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqtt_server = "broker.emqx.io"; //"test.mosquitto.org";
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
long scanSensores = 0;
char msg[50];
int value = 0;
float temperature;
float humidity;
// LED Pin
const int ledRedPin = 4;
const int ledRedChave = 5;
const int ledBlueMqttPin = 18;
bool statusChaveLedRed;
float voltage34;
void setup() {
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
pinMode(ledRedPin, OUTPUT);
pinMode(ledRedChave, INPUT);
pinMode(ledBlueMqttPin, OUTPUT);
Serial.println(F("DHTxx test!"));
dht.begin();
delay(500);
}
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
if (String(topic) == "sematec25/ledBlue") {
Serial.print("Changing output to ");
if(messageTemp == "true"){
Serial.println("true");
digitalWrite(ledBlueMqttPin, HIGH);
}
else if(messageTemp == "false"){
Serial.println("false");
digitalWrite(ledBlueMqttPin, LOW);
}
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("sematec25Client_go2")) {
Serial.println("connected");
// Subscribe
client.subscribe("sematec25/ledBlue");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void leSensores(){
if(digitalRead(ledRedChave) == HIGH){
statusChaveLedRed=1;
digitalWrite(ledRedPin,HIGH);
} else{
statusChaveLedRed=0;
digitalWrite(ledRedPin,LOW);
}
int v34 = analogRead(34);
voltage34 = map(v34,0,4095,0,100)/1.0;
Serial.println(voltage34);
humidity = dht.readHumidity();
// Read temperature as Celsius (the default)
temperature = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(humidity) || isnan(temperature) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
if(now - scanSensores > 450){
scanSensores = now;
leSensores();
}
if (now - lastMsg > 1000) {
lastMsg = now;
// Convert the value to a char array
char tempString[8];
dtostrf(temperature, 1, 2, tempString);
Serial.print("Temperature: ");
Serial.println(tempString);
client.publish("sematec25/temp", tempString);
// Convert the value to a char array
char humString[8];
dtostrf(humidity, 1, 2, humString);
Serial.print("Humidity: ");
Serial.println(humString);
client.publish("sematec25/umid", humString);
// Convert the value to a char array
char cvoltage[8];
dtostrf(voltage34, 1, 2, cvoltage);
Serial.print("voltage34: ");
Serial.println(cvoltage);
client.publish("sematec25/voltage34", cvoltage);
//myString.toCharArray(buf, len)
char s_temp[]={};
unsigned int len = 10;
String s_Chave="";
if(statusChaveLedRed){
s_Chave = "true";
} else {
s_Chave = "false";
}
s_Chave.toCharArray(s_temp,len);
client.publish("sematec25/chave",s_temp);
Serial.print("Status_chave: ");
Serial.println(s_temp);
}
}
*/