/*********
By: Carlos Giovani Dutra
Projeto: SMART WEATHER
Versão final corrigida
*********/
// --- Bibliotecas ---
#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// --- Configurações do Display LCD ---
LiquidCrystal_I2C lcd(0x27, 16, 2);
// --- Credenciais de Rede ---
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// --- Configurações do MQTT ---
const char* mqtt_server = "broker.hivemq.com";
const int mqtt_port = 1883;
const char* mqtt_client_name = "NIVEL";
const char* mqtt_topic_publish = "smartlevel";
// --- Pinos do Sensor Ultrassônico HC-SR04 ---
#define TRIG_PIN 26
#define ECHO_PIN 25
// --- Pino do Relé --- (NOVA LINHA)
#define PINO_RELE 27 // Pino D15, conforme o seu esquema
// --- Constantes do Projeto ---
#define ALTURA_TANQUE 800.0 // Altura do tanque em mm
// --- Variáveis Globais ---
long duracao;
float distancia;
float nivelPercentual;
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
long interval = 2000; // Intervalo de 2 segundos
// --- Funções ---
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Conectando-se a ");
Serial.println(ssid);
lcd.clear();
lcd.print("Conectando WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
lcd.print(".");
}
Serial.println("\nWiFi conectado!");
Serial.print("Endereco IP: ");
Serial.println(WiFi.localIP());
lcd.clear();
lcd.print("WiFi Conectado!");
}
void reconnect() {
while (!client.connected()) {
Serial.print("Tentando conectar ao MQTT...");
lcd.clear();
lcd.print("Conectando MQTT");
if (client.connect(mqtt_client_name)) {
Serial.println("Conectado!");
lcd.clear();
lcd.print("MQTT Conectado!");
delay(1000);
} else {
Serial.print("Falhou, rc=");
Serial.print(client.state());
Serial.println(" Tentando novamente em 5 segundos");
lcd.clear();
lcd.print("Falha no MQTT");
delay(5000);
}
}
}
void medirNivel() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
duracao = pulseIn(ECHO_PIN, HIGH, 30000UL);
distancia = (duracao * 0.343) / 2.0;
if (duracao == 0) {
distancia = ALTURA_TANQUE;
}
if (distancia > ALTURA_TANQUE) {
distancia = ALTURA_TANQUE;
}
nivelPercentual = ((ALTURA_TANQUE - distancia) / ALTURA_TANQUE) * 100.0;
Serial.print("Distancia (mm): ");
Serial.print(distancia, 1);
Serial.print(" | Nivel: ");
Serial.print(nivelPercentual, 1);
Serial.println(" %");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Medidor de Nivel");
lcd.setCursor(0, 1); // Alterado para a linha 1 (a segunda linha)
lcd.print(" Enchimento: ");
lcd.print(nivelPercentual, 1);
lcd.print("%");
}
void setup() {
Serial.begin(115200); // Corrigido para uma velocidade mais comum
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
// --- Configuração do pino do Relé --- (NOVO BLOCO)
pinMode(PINO_RELE, OUTPUT);
digitalWrite(PINO_RELE, HIGH); // Garante que a bomba comece desligada
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Iniciando...");
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
delay(1500);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
long now = millis();
if (now - lastMsg > interval) {
lastMsg = now;
medirNivel();
// --- LÓGICA DE CONTROLE DA BOMBA --- (NOVO BLOCO)
if (nivelPercentual < 80.0) {
digitalWrite(PINO_RELE, HIGH); // Liga a bomba (relé ativo em nível baixo)
Serial.println("Nivel < 80%. BOMBA LIGADA.");
} else {
digitalWrite(PINO_RELE, LOW); // Desliga a bomba
Serial.println("Nivel >= 80%. BOMBA DESLIGADA.");
}
// --- FIM DO BLOCO DE CONTROLE ---
char nivelString[8];
dtostrf(nivelPercentual, 4, 1, nivelString);
client.publish(mqtt_topic_publish, nivelString);
}
}