/*
Forum: https://forum.arduino.cc/t/hilfe-zum-automatischen-bewasserungscode/1426822
Wokwi: https://wokwi.com/projects/454040248062179329
Angepasster Sketch zur Bewässerungsanlage
Statt der Pumpe -> Blaue Led
Statt des Feuchtesensors -> Schiebepotentiometer
Zusätzlich:
Rote Led: Zeigt den Zustand "zu trocken" an
Grüne Led: Zeigt den Zustand "ausreichend feucht" an
Beide Led blinken kurz, wenn eine Feuchtemessung erfolgt ist
Magenta Led: Wird regelmäßig ein/ausgeschaltet, um das Nicht-Blockieren der loop() zu demonstrieren
Die Parameter für das Mapping des Sensorwertes sowie der Schwellwert für "zu trocken" sind als Konstanten
im Header deklariert. Ebenso die Werte für den Messzyklus und die Dauer des Pumpens. Die Ausschaltzeit der
Anzeige-Led ist ebenfalls dort zu finden.
Bei Einsatz der Pumpe wird die folgende Messung um die Pumpdauer nach hinten verschoben, um so das im
Originalsketch durch delay() erzeugte Timing nachzubilden. Dazu wird die Variable letzteMessung mit dem
Ausschalten der Pumpe neu gesetzt.
2026/01/24
ec2021
*/
constexpr uint8_t sensorPin {A0}; // Bodenfeuchtesensor
constexpr uint8_t relayPin {4}; // Relais / Pumpe
constexpr uint8_t greenPin {5}; // Anzeige "ausreichend feucht"
constexpr uint8_t redPin {6}; // Anzeige "zu trocken/Pumpeneinsatz"
constexpr uint16_t sensorDry {550}; // Schwellwert Analogsensor für "zu trocken"
constexpr uint16_t sensorWet { 10}; // Schwellwert Analogsensor für "ausreichend feucht"
constexpr int16_t dryThreshold {60}; // Schwellwert der umgerechneten Feuchte für "zu trocken"
constexpr unsigned long measureInterval {3000}; // Messintervall in ms
constexpr unsigned long pumpDuration {1000}; // Pumpdauer in ms
constexpr unsigned long blinkDuration {250}; // Dauer der Aus-Zeit der Led-Anzeige in ms
enum class STATUS {MESSEN, PUMPEAN, PUMPEN};
STATUS Status = STATUS::MESSEN;
unsigned long startZeit;
unsigned long letzteMessung;
boolean istZuTrocken = false;
boolean messungErfolgt = false;
void setup() {
Serial.begin(115200);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, HIGH); // Pumpe aus (LOW-aktives Relais)
Serial.println("Bewässerungsanlage gestartet ...");
}
void loop() {
ledAnzeige();
bewaesserungsMaschine();
flackern(); // Nur zur Demo: Für die Bewässerungsanlage nicht benötigt!
}
void bewaesserungsMaschine() {
switch (Status) {
case STATUS::MESSEN:
if (istTrocken()) {
Serial.println("Boden zu trocken -> Bewässerung AN");
Status = STATUS::PUMPEAN;
}
break;
case STATUS::PUMPEAN:
startZeit = millis();
startePumpe();
Status = STATUS::PUMPEN;
break;
case STATUS::PUMPEN:
if (millis() - startZeit >= pumpDuration) {
stoppePumpe();
letzteMessung = millis(); // Setzt die nächste Messung auf Jetztzeit + measureInterval
Status = STATUS::MESSEN;
}
break;
}
}
boolean istTrocken() {
if (millis() - letzteMessung >= measureInterval) {
letzteMessung = millis();
int sensorWert = constrain(analogRead(sensorPin), sensorWet, sensorDry);
int feuchtigkeit = map(sensorWert, sensorDry, sensorWet, 0, 100);
Serial.print("Feuchtigkeit: ");
Serial.print(feuchtigkeit);
Serial.println(" %");
istZuTrocken = (feuchtigkeit < dryThreshold);
messungErfolgt = true;
return istZuTrocken;
}
return false;
}
void startePumpe() {
Serial.println("Starte Pumpe");
digitalWrite(relayPin, LOW);
}
void stoppePumpe() {
Serial.println("Stoppe Pumpe");
digitalWrite(relayPin, HIGH);
}
void ledAnzeige() {
static unsigned long lastBlink;
if (messungErfolgt) {
messungErfolgt = false;
lastBlink = millis();
digitalWrite(greenPin, LOW);
digitalWrite(redPin, LOW);
}
if (millis() - lastBlink > blinkDuration) {
digitalWrite(greenPin, !istZuTrocken);
digitalWrite(redPin, istZuTrocken);
}
}
// Dient nur der Demo der nicht-blockierenden StateMachine
void flackern() {
constexpr uint8_t magentaPin {7};
constexpr unsigned long magentaBlink {150};
static boolean firstCall = true;
if (firstCall) {
pinMode(magentaPin, OUTPUT);
firstCall = false;
}
static unsigned long lastBlinking;
if (millis() - lastBlinking > magentaBlink) {
lastBlinking = millis();
byte state = !digitalRead(magentaPin);
digitalWrite(magentaPin, state);
}
}