#include <Arduino.h>
#include <DHT.h>
// =====================================
// CALIBRAÇÃO
// =====================================
const float OFFSET_TEMP = -1.0;
const float OFFSET_HUMI = 0.0;
// =====================================
// PINOS
// =====================================
#define DHTPIN 15
#define DHTTYPE DHT22
const int PIN_SOIL_1 = 34;
const int PIN_SOIL_2 = 35;
const int PIN_LEVEL_CRITIC = 13;
const int PIN_LEVEL_LOW = 12;
const int PIN_LEAK = 14; // sensor vazamento
const int PIN_MODE = 27; // AUTO / MANUTENÇÃO (botão)
const int PIN_PUMP = 4;
const int PIN_FAN = 5;
const int PIN_HUMID = 18;
const int PIN_DEHUMID= 19;
const int PIN_NOTIF = 2;
// =====================================
DHT dht(DHTPIN, DHTTYPE);
// ESTADOS
float temp = 0;
float humiAr = 0;
float soilHumid = 0;
bool pumpState = false;
bool fanState = false;
bool humidState = false;
bool dehumidState = false;
// DHT RESILIÊNCIA
float lastValidTemp = 0;
float lastValidHumi = 0;
int dhtFailCount = 0;
const int DHT_FAIL_LIMIT = 5;
// =====================================
// FUNÇÃO AUXILIAR
// =====================================
void allOutputsOff() {
digitalWrite(PIN_PUMP, LOW);
digitalWrite(PIN_FAN, LOW);
digitalWrite(PIN_HUMID, LOW);
digitalWrite(PIN_DEHUMID, LOW);
pumpState = fanState = humidState = dehumidState = false;
}
// =====================================
void setup() {
Serial.begin(115200);
pinMode(PIN_PUMP, OUTPUT);
pinMode(PIN_FAN, OUTPUT);
pinMode(PIN_HUMID, OUTPUT);
pinMode(PIN_DEHUMID, OUTPUT);
pinMode(PIN_NOTIF, OUTPUT);
pinMode(PIN_LEVEL_CRITIC, INPUT_PULLDOWN);
pinMode(PIN_LEVEL_LOW, INPUT_PULLDOWN);
pinMode(PIN_LEAK, INPUT_PULLDOWN);
pinMode(PIN_MODE, INPUT_PULLDOWN);
// Estado seguro no boot
allOutputsOff();
digitalWrite(PIN_NOTIF, LOW);
dht.begin();
// =====================================
// TASK PRINCIPAL
// =====================================
xTaskCreatePinnedToCore([](void*) {
for(;;){
bool autoMode = digitalRead(PIN_MODE);
bool isCrit = digitalRead(PIN_LEVEL_CRITIC);
bool isLow = digitalRead(PIN_LEVEL_LOW);
bool leakDetected = digitalRead(PIN_LEAK);
// =================================
// MODO MANUTENÇÃO
// =================================
if(!autoMode){
allOutputsOff();
// LED fixo = manutenção
digitalWrite(PIN_NOTIF, HIGH);
Serial.println("🟡 MODO MANUTENÇÃO - Automação bloqueada");
vTaskDelay(pdMS_TO_TICKS(1500));
continue;
}
// =================================
// LEITURA DHT RESILIENTE
// =================================
float rT = dht.readTemperature();
float rH = dht.readHumidity();
if(!isnan(rT) && !isnan(rH)) {
temp = rT + OFFSET_TEMP;
humiAr = rH + OFFSET_HUMI;
lastValidTemp = temp;
lastValidHumi = humiAr;
dhtFailCount = 0;
} else {
temp = lastValidTemp;
humiAr = lastValidHumi;
dhtFailCount++;
}
// =================================
// LEITURA REAL DOS SENSORES DE SOLO
// =================================
int s1 = analogRead(PIN_SOIL_1);
int s2 = analogRead(PIN_SOIL_2);
float soil1 = map(s1, 0, 4095, 0, 100);
float soil2 = map(s2, 0, 4095, 0, 100);
soilHumid = (soil1 + soil2) / 2.0;
// =================================
// SEGURANÇA MÁXIMA
// =================================
if(isCrit || leakDetected){
digitalWrite(PIN_PUMP, LOW);
pumpState = false;
digitalWrite(PIN_NOTIF, (millis()/200)%2);
if(leakDetected)
Serial.println("⚠️ VAZAMENTO DETECTADO - BOMBA BLOQUEADA");
else
Serial.println("⚠️ NIVEL CRITICO - BOMBA BLOQUEADA");
vTaskDelay(pdMS_TO_TICKS(1500));
continue;
}
// =================================
// CONTROLE CLIMÁTICO
// =================================
if(humiAr > 0.1){
if(humiAr < 40){
humidState = true;
digitalWrite(PIN_HUMID, HIGH);
}
if(humiAr > 60){
humidState = false;
digitalWrite(PIN_HUMID, LOW);
}
if(humiAr > 75){
dehumidState = true;
digitalWrite(PIN_DEHUMID, HIGH);
}
if(humiAr < 65){
dehumidState = false;
digitalWrite(PIN_DEHUMID, LOW);
}
}
// FAN
if(temp > 28){
fanState = true;
digitalWrite(PIN_FAN, HIGH);
} else {
fanState = false;
digitalWrite(PIN_FAN, LOW);
}
// =================================
// IRRIGAÇÃO AUTOMÁTICA
// =================================
if(soilHumid < 30 && !pumpState){
pumpState = true;
digitalWrite(PIN_PUMP, HIGH);
}
if(soilHumid > 70 && pumpState){
pumpState = false;
digitalWrite(PIN_PUMP, LOW);
}
// =================================
// ALERTAS
// =================================
if(dhtFailCount >= DHT_FAIL_LIMIT){
digitalWrite(PIN_NOTIF, (millis()/500)%2);
}
else if(isLow){
digitalWrite(PIN_NOTIF, HIGH);
}
else{
digitalWrite(PIN_NOTIF, LOW);
}
// =================================
// LOG SERIAL
// =================================
Serial.printf(
"Modo:AUTO | Solo:%.1f%% | Temp:%.1fC | Ar:%.1f%% | Leak:%d | P:%s F:%s H:%s D:%s\n",
soilHumid,
temp,
humiAr,
leakDetected,
pumpState?"ON":"OFF",
fanState?"ON":"OFF",
humidState?"ON":"OFF",
dehumidState?"ON":"OFF"
);
vTaskDelay(pdMS_TO_TICKS(1500));
}
}, "CEREBRO_TASK", 8192, NULL, 1, NULL, 1);
}
// =====================================
void loop() {
delay(10);
}