/**
Arduino Electronic-Dreno (I2C) - v1.2
Correção do display "vazio" pós-drenagem e unidade NTU.
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define BUZZER_PIN 8
#define RELAY_PIN 9
#define TURBIDITY_PIN A0
const int pinoPot = A1;
const int pinoLED = 3;
#define DRAIN_DURATION 10000
unsigned long DRAIN_INTERVAL = 60000;
float TURBIDITY_THRESHOLD = 2.5;
unsigned long lastDrainTime = 0;
unsigned long lastInteractionTime = 0;
const unsigned long DISPLAY_TIMEOUT = 30000;
bool displayIsOn = true;
float lastTurbidityValue = -1.0;
LiquidCrystal_I2C lcd(0x27, 16, 2);
void wakeUpDisplay() {
lastInteractionTime = millis();
if (!displayIsOn) {
lcd.backlight();
displayIsOn = true;
lastTurbidityValue = -1.0;
}
}
void playTone(int freq, int duration) {
tone(BUZZER_PIN, freq, duration);
delay(duration);
}
float readTurbidity() {
int sensorValue = analogRead(TURBIDITY_PIN);
return (float)sensorValue / 1024.0 * 5.0;
}
void executeDrain(String motivo) {
wakeUpDisplay();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("DRENO ATIVADO!");
lcd.setCursor(0, 1);
lcd.print(motivo);
playTone(1500, 200);
playTone(1200, 200);
digitalWrite(RELAY_PIN, HIGH);
digitalWrite(pinoLED, HIGH);
for (int i = 0; i < 10; i++) {
delay(DRAIN_DURATION / 10);
lcd.setCursor(i + 3, 1);
lcd.print(">");
}
digitalWrite(RELAY_PIN, LOW);
playTone(1000, 500);
lastDrainTime = millis();
lastTurbidityValue = -1.0; // Força o loop() a redesenhar a tela de monitoramento
}
void setup() {
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(TURBIDITY_PIN, INPUT);
pinMode(pinoLED, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("ELETRONIC-DRENO");
delay(2000);
lcd.clear();
}
void loop() {
unsigned long currentTime = millis();
float currentTurbidity = readTurbidity();
// Controle de brilho do LED indicador
int valorPot = analogRead(pinoPot);
analogWrite(pinoLED, map(valorPot, 0, 1023, 0, 255));
// Cálculo NTU
float NTU = -1120.4 * (currentTurbidity * currentTurbidity) + 5742.3 * currentTurbidity - 4353.8;
if(NTU < 0) NTU = 0; // Evita valores negativos no display
// 1. Atualização do Display
if (displayIsOn) {
if (abs(currentTurbidity - lastTurbidityValue) > 0.05) {
lcd.setCursor(0, 0);
lcd.print("Turbidez:");
lcd.print((int)NTU); // Exibe como inteiro para facilitar leitura
lcd.print("NTU ");
lcd.setCursor(0, 1);
if (currentTurbidity >= TURBIDITY_THRESHOLD) {
lcd.print("Status: SUJA ");
} else {
lcd.print("Status: MONITOR ");
}
lastTurbidityValue = currentTurbidity;
}
}
// 2. Lógica de Acionamento
if (currentTurbidity > TURBIDITY_THRESHOLD) {
executeDrain("POR TURBIDEZ ");
}
else if (currentTime - lastDrainTime >= DRAIN_INTERVAL) {
executeDrain("POR TEMPO ");
}
// 3. Standby do Display
if (displayIsOn && (currentTime - lastInteractionTime > DISPLAY_TIMEOUT)) {
lcd.noBacklight();
displayIsOn = false;
}
delay(200);
}