// Intelligentes Gewächshaus – Arduino UNO R4 WiFi
// Sensoren: DHT11 (Temparatur und Luftfeuchte), Bodenfeuchte, LDR (Licht), Wasserstand
// Übertragung: WiFi → PHP → MySQL
#include <DHT.h> // DHT11-Bibliothek (Adafruit)
#include <WiFiS3.h> // WiFi für Arduino UNO R4 WiFi
#include <LiquidCrystal_I2C.h>
#include <Adafruit_Sensor.h>
// WLAN-Zugangsdaten
const char* WLAN_SSID = "MagentaWLAN-52DA";
const char* WLAN_PASSWORT = "78412521809314206831";
// Server (XAMPP-Rechner im gleichen Netzwerk)
// IP-Adresse des PCs
const char* SERVER_IP = "192.168.2.36"; // !
const int SERVER_PORT = 80;
const char* SERVER_PFAD = "/gewaechshaus/dateneintrag.php";
// Pin-Definitionen
#define PIN_DHT 2 // DHT11 Signal
#define PIN_BODEN A0 // Bodenfeuchte analog
#define PIN_LICHT A1 // LDR analog
#define PIN_WASSER A2 // Wasserstand analog
#define PIN_KNOPF 4 // Manueller Override-Knopf
#define PIN_PUMPE 7 // Relais Pumpe
#define PIN_LED 8 // Growlight
// Schwellenwerte
const int BODEN_TROCKEN = 550; // oberhalb → Pumpe ein
const int BODEN_FEUCHT = 400; // unterhalb → Pumpe aus
const int LICHT_SCHWELLE = 200; // unterhalb → LED ein
const int WASSER_MINIMUM = 300; // unterhalb → Tank-Warnung
// Messintervall: X Minuten
const unsigned long INTERVALL_MS = 3UL * 60UL * 1000UL;
unsigned long letzteMessung = 0;
const unsigned long INTERVALL_LCD_MS = 4UL * 1000UL;
unsigned long letzteAnzeige = 0;
// Zustandsvariablen
bool pumpeAn = false;
bool ledAn = false;
// DHT11 initialisieren
#define DHT_TYP DHT11
DHT dht(PIN_DHT, DHT_TYP);
// WiFi-Client
WiFiClient client;
//LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// SETUP
void setup() {
Serial.begin(9600);
delay(2000);
lcd.init();
lcd.backlight();
// Pins konfigurieren
pinMode(PIN_PUMPE, OUTPUT);
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_KNOPF, INPUT_PULLUP);
// Aktoren beim Start ausschalten
digitalWrite(PIN_PUMPE, LOW);
digitalWrite(PIN_LED, LOW);
// DHT11 starten
dht.begin();
Serial.println("DHT11 gestartet.");
delay(2000);
// WLAN Verbidnung
Serial.print("Verbinde mit WLAN: ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASSWORT);
//int versuche = 0;
while (WiFi.status() != WL_CONNECTED){// && versuche < 20) {
delay(500);
Serial.print(".");
//versuche++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWLAN verbunden!");
Serial.print("IP-Adresse: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("\nWLAN-Verbindung fehlgeschlagen!");
}
}
// Immer jeweils Mittelwert aus 10 Messungen
// Bodenfeuchte auslesen
int leseBoden() {
long sum = 0;
for (int i = 0; i < 10; i++) {
sum += analogRead(PIN_BODEN);
delay(2);
}
return (int)(sum / 10);
}
// Lichtstärke auslesen
int leseLicht() {
long sum = 0;
for (int i = 0; i < 10; i++) {
sum += analogRead(PIN_LICHT);
delay(2);
}
return (int)(sum / 10);
}
// Wasserstand auslesen
int leseWasser() {
long sum = 0;
for (int i = 0; i < 10; i++) {
sum += analogRead(PIN_WASSER);
delay(2);
}
return (int)(sum / 10);
}
// Pumpe steuern
void steuerePumpe(bool einschalten) {
pumpeAn = einschalten;
digitalWrite(PIN_PUMPE, einschalten ? HIGH : LOW);
Serial.println(einschalten ? "Pumpe EIN" : "Pumpe AUS");
}
// LED steuern
void steuereLed(bool einschalten) {
ledAn = einschalten;
digitalWrite(PIN_LED, einschalten ? HIGH : LOW);
Serial.println(einschalten ? "LED EIN" : "LED AUS");
}
// Daten per HTTP GET an PHP senden
void sendeDaten(float temp, float luft, int boden, int licht, int wasser) {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("Kein WLAN – Daten nicht gesendet.");
return;
}
// Nutzt eine URL zusammengebaut mit Messwerten um diese zu senden
if (client.connect(SERVER_IP, SERVER_PORT)) {
String url = String(SERVER_PFAD)
+ "?temp=" + String(temp)
+ "&luft=" + String(luft)
+ "&boden=" + String(boden)
+ "&licht=" + String(licht)
+ "&wasser=" + String(wasser);
// HTTP GET senden
client.print("GET " + url + " HTTP/1.1\r\n");
client.print("Host: " + String(SERVER_IP) + "\r\n");
client.print("Connection: close\r\n\r\n");
delay(500);
client.stop();
Serial.println("Daten gesendet: " + url);
} else {
Serial.println("Verbindung zum Server fehlgeschlagen.");
}
}
// Hauptschleife
void loop() {
static float temperatur;
static float luftfeuchte;
static int boden;
static int licht;
static int wasser;
unsigned long jetzt = millis();
// Manueller Knopf: Growlight
if (digitalRead(PIN_KNOPF) == HIGH) {
delay(50);
if (digitalRead(PIN_KNOPF) == HIGH) {
steuereLed(!ledAn); // Toggle: ein/aus
delay(500);
}
}
static bool seite = false;
if (jetzt - letzteAnzeige >= INTERVALL_LCD_MS || letzteAnzeige == 0) {
letzteAnzeige = jetzt;
// Anzeige auf dem LCD
lcd.clear();
if(seite) {
// Seite 1
lcd.setCursor(0, 0);
lcd.print("Temp.:"); lcd.setCursor(10, 0); lcd.print(temperatur); lcd.print("C");
lcd.setCursor(0, 1);
lcd.print("Luftf.:"); lcd.setCursor(10, 1); lcd.print(luftfeuchte); lcd.print("%");
}
else{
// Seite 2
lcd.setCursor(0, 0);
lcd.print("Bodenf.:"); lcd.setCursor(12, 0); lcd.print(boden);
lcd.setCursor(0, 1);
lcd.print("Licht:"); lcd.setCursor(13, 1); lcd.print(licht);
}
seite = !seite;
}
// Alle X Minuten messen und senden
if (jetzt - letzteMessung >= INTERVALL_MS || letzteMessung == 0) {
letzteMessung = jetzt;
// Sensoren auslesen
temperatur = dht.readTemperature();
luftfeuchte = dht.readHumidity();
boden = leseBoden();
licht = leseLicht();
wasser = leseWasser();
// DHT11 Fehlerprüfung
if (isnan(temperatur) || isnan(luftfeuchte)) {
Serial.println("DHT11 Lesefehler.");
return;
}
// Seriell ausgeben
Serial.println("──────────────────────────");
Serial.print("Temperatur: "); Serial.print(temperatur); Serial.println(" °C");
Serial.print("Luftfeuchte: "); Serial.print(luftfeuchte); Serial.println(" %");
Serial.print("Bodenfeuchte: "); Serial.println(boden);
Serial.print("Licht: "); Serial.println(licht);
Serial.println("──────────────────────────");
Serial.print("Wasserstand: "); Serial.println(wasser);
// Automatik: Pumpe
if (wasser < WASSER_MINIMUM) {
// Tank zu leer → Pumpe nicht einschalten
steuerePumpe(false);
Serial.println("WARNUNG: Tank fast leer!");
} else {
if (!pumpeAn && boden >= BODEN_TROCKEN) {
steuerePumpe(true); // zu trocken → einschalten
} else if (pumpeAn && boden <= BODEN_FEUCHT) {
steuerePumpe(false); // feucht genug → ausschalten
}
}
// Automatik: LED-Growlight
if (licht < LICHT_SCHWELLE) {
steuereLed(true); // zu dunkel → einschalten
} else if (licht >= LICHT_SCHWELLE) {
steuereLed(false); // hell genug → ausschalten
}
// Daten an Server senden
sendeDaten(temperatur, luftfeuchte, boden, licht, wasser);
}
}