Sistema inteligente de rega automática que combina luminosidade (LDR), temperatura e humidade do ar (DHT11) e humidade do solo simulada para decidir quando regar. A bomba de rega é controlada por um relé. Todos os dados são registados no Raspberry Pi para análise e otimização da rega ao longo do tempo.
| Módulo | Pino do módulo | Pino Arduino | Função |
|---|---|---|---|
| DHT11 (#19) | VCC / GND / S | 5V / GND / D2 | Temperatura e humidade do ar |
| LDR (#22) | VCC / GND / AO | 5V / GND / A0 | Luminosidade — não regar de noite |
| Solo (simulado) | — / — / Sinal | — / — / A1 | Potenciómetro: 0=seco, 1023=húmido |
| Módulo Relé (#29) | VCC / GND / IN | 5V / GND / D7 | Liga/desliga bomba de rega |
| LED 2 Cores (#10) | VCC / GND / R / G | 5V / GND / D12 / D11 | Verde = OK, Vermelho = a regar |
Liga DHT11 (S→D2) e LDR (AO→A0). Confirma no Serial Monitor que as leituras são coerentes: temperatura ambiente, humidade ~40–60%, LDR alto com luz, baixo no escuro.
Liga um potenciómetro: terminal esquerdo → 5V, direito → GND, centro → A1. Girar o botão simula solo de seco (0) a húmido (1023).
Liga o relé (IN→D7) — lógica invertida: LOW ativa. Liga o LED 2 cores (R→D12, G→D11). Testa: digitalWrite(7,LOW) deve ativar o relé (bomba ligada simulada).
Carrega o sketch completo. Ajusta os limiares observando os valores reais no Serial Monitor. Varia o potenciómetro do solo para verificar que a rega actua correctamente.
#include <DHT.h>
#define DHT_PIN 2
#define LDR_PIN A0
#define SOLO_PIN A1 // Potenciómetro ou sensor de solo real
#define RELE_PIN 7
#define LED_R 12
#define LED_G 11
// ── Limiares (ajusta ao teu ambiente) ───────────────
#define SOLO_SECO 300 // raw < 300 → solo seco → regar
#define SOLO_HUMIDO 600 // raw > 600 → parar rega
#define TEMP_MIN 10.0 // °C — não regar se muito frio
#define LUZ_MIN 150 // raw — só regar de dia
#define REGA_MAX_MS 30000 // Máx 30s de rega contínua
#define CICLO_MS 5000 // Verificar a cada 5s
DHT dht(DHT_PIN, DHT11);
bool regando = false;
unsigned long inicioRega = 0;
void ligarRega() {
digitalWrite(RELE_PIN, LOW); // Lógica invertida — LOW ativa
digitalWrite(LED_R, HIGH); digitalWrite(LED_G, LOW);
regando = true; inicioRega = millis();
Serial.println("REGA: LIGADA");
}
void desligarRega(const char* motivo) {
digitalWrite(RELE_PIN, HIGH);
digitalWrite(LED_G, HIGH); digitalWrite(LED_R, LOW);
regando = false;
Serial.print("REGA: DESLIGADA ("); Serial.print(motivo); Serial.println(")");
}
void setup() {
dht.begin();
pinMode(RELE_PIN, OUTPUT); digitalWrite(RELE_PIN, HIGH);
pinMode(LED_R, OUTPUT); pinMode(LED_G, OUTPUT);
digitalWrite(LED_G, HIGH);
Serial.begin(9600);
Serial.println("ms,temp,hum,solo,luz,estado"); // CSV
}
void loop() {
delay(CICLO_MS);
float t = dht.readTemperature();
float h = dht.readHumidity();
int sol = analogRead(SOLO_PIN);
int luz = analogRead(LDR_PIN);
if (isnan(t)) { Serial.println("ERRO DHT"); return; }
// Condições de paragem (prioritárias)
if (regando) {
if (sol > SOLO_HUMIDO)
desligarRega("solo_humido");
else if (millis() - inicioRega > REGA_MAX_MS)
desligarRega("timeout");
else if (luz < LUZ_MIN)
desligarRega("noite");
}
// Condições de início
else if (sol < SOLO_SECO && t > TEMP_MIN && luz > LUZ_MIN) {
ligarRega();
}
// Log CSV
Serial.print(millis()); Serial.print(",");
Serial.print(t,1); Serial.print(",");
Serial.print(h,1); Serial.print(",");
Serial.print(sol); Serial.print(",");
Serial.print(luz); Serial.print(",");
Serial.println(regando ? "REGA" : "OK");
}#!/usr/bin/env python3
# Lê dados do Arduino e gera relatório diário de rega
import serial, csv, time
from datetime import datetime
PORTA = "/dev/ttyACM0"
BAUD = 9600
ficheiro = f"plantas_{datetime.now().strftime('%Y%m%d')}.csv"
eventos_rega = []
with serial.Serial(PORTA, BAUD, timeout=10) as ser:
with open(ficheiro, "w", newline="") as f:
w = csv.writer(f)
ser.readline() # ignorar cabeçalho Arduino
w.writerow(["hora","temp","hum","solo","luz","estado"])
print(f"A registar em {ficheiro} ...")
while True:
linha = ser.readline().decode("utf-8", errors="ignore").strip()
if not linha or linha.startswith("ERRO"): continue
campos = linha.split(",")
if len(campos) < 6: continue
agora = datetime.now().strftime("%H:%M:%S")
w.writerow([agora] + campos[1:])
f.flush()
estado = campos[5]
if estado == "REGA": eventos_rega.append(agora)
print(f"{agora} T:{campos[1]} Solo:{campos[3]} [{estado}]")