IoT – Water My Plants

Motivation

Tomaten-Pflanzen benötigen jeden Menge Wasser, da die Frucht zu 95% aus Wasser besteht. Die Pflanze als solches mag jedoch kein Wasser von oben und schon gar nicht auf den Blättern. Das schließt eine natürliche Bewässerung durch Regen oder künstlich durch einen Gartensprenger aus. Bei warmen Temperaturen kann ruhig zwei Mal am Tag gewässert werden – und zwar jeden Tag. Da meine Leidenschaft allerdings nicht im Garten, sondern viel mehr aus dem Wasser beim Segeln zu finden ist, kommen die Tomaten an viele Wochenenden, besonders im Sommer, zu kurz. Eine Lösung muss her: IoT!

Die Idee

Die Idee ist eine kluge Bewässerung, die zugleich recht simpel ist: Wenn die Erde trocken ist, mach sie nass. Oder etwas IoT / IT-Lastiger:

Pflanze pflanze = new Pflanze();
if (pflanze.istTrocken()) {
  pflanze.getBlumentopf().machNass();
}

Tatsächliche Herausforderungen gibt es dabei nur wenige:

  • Messen der Erdfeuchtigkeit
  • Bewässern des Blumentopfes

Der Versuchsaufbau

Ich habe leider keinen permanenten Gartenschlauchanschluss. Also benötige ich ein Wasserreservoir und eine Pumpe (für jeden Blumentopf / jede Pflanze natürlich eine eigene Pumpe). Darüber hinaus benötige ich noch ein paar Kabel und Schläuche und etwas Fingerspitzengefühl. Lötkobel, Widerstände und elektrotechnisches Verständnis darf auch nicht fehlen.

ACHTUNG! Die Arbeit mit Strom sollte stets sehr sorgsam und fachgerecht durchgeführt werden. Bitte nehmt einen Elektriker eures Vertrauens mit ins Boot, der euch hilft oder zumindest über eure Anlage einen Blick wirft, bevor ihr sie in Betrieb nehmt!

Um mit geringen Schalt-Spannungen die benötigten 240 Volt schalten zu können, werden s.g. Relais benötigt. Die können abhängig von Vorhandensein / Fehlen der Schaltspannung den “echten Strom” ein- bzw. ausschalten. Für ein Arduino – der Bastel-Vertreter für IoT – habe ich mit folgendem Artikel gute Erfahrungen gemacht: SainSmart 4 Kanäle RelaisModul Brett 5V Für Arduino
Kleinere Pumpen bekommt ihr in dem lokalen Baumarkt um die Ecke. Die Gartenabteilung ist dein Freund. Als letztes benötigt ihr natürlich noch etwas zum Programmieren, etwas, dass die simple Logik übernimmt und möglichst kompatibel ist. Ich empfehle daher ein Arduino Uno. Um euer Board die Möglichkeit zu geben Feuchtigkeit zu “messen” braucht ihr nun Feuchtigkeitsmesser (auch Hygrometer genannt). Ich habe kurzer Hand und ohne langes Suche diese hier *** UPDATE SIEHE UNTEN *** genommen. Sie bieten die Möglichkeit sowohl digital als auch analog angeschlossen zu werden. Ich habe die analoge Variante genommen – haltet es, wie ihr wollt.

Die Implementierung

Der Code

Bitte seid nachsichtig mit dem Code – er ist eine reine Debugging-Version 😉

int in1 = A1;
int in2 = A2;
int in3 = A3;
int in4 = A4;
int out1 = 5;
int out2 = 2;
int out3 = 3;
int out4 = 4;
int pumpTime = 10; // 10 SEK
int sleepTimes = 30; // 300 SEK (5 min) in between
int dryVal1 = 280;
int dryVal2 = 280;
int dryVal3 = 280;
int dryVal4 = 280;

void setup() {
 Serial.begin(9600);
 
 Serial.println("----------------------------------------------------------");
 Serial.println("| Water my plants www.it-aw.com debugging starts |");
 Serial.println("----------------------------------------------------------");
 Serial.println();
 Serial.print("Dry value is 1=");
 Serial.print(dryVal1);
 Serial.print(", 2=");
 Serial.print(dryVal2);
 Serial.print(", 3=");
 Serial.print(dryVal3);
 Serial.print(", 4=");
 Serial.print(dryVal4);
 Serial.println(" (measure has to be greater)");
 
 pinMode(out1, OUTPUT); 
 pinMode(out2, OUTPUT);
 pinMode(out3, OUTPUT);
 pinMode(out4, OUTPUT);

 digitalWrite(out1, HIGH);
 digitalWrite(out2, HIGH);
 digitalWrite(out3, HIGH);
 digitalWrite(out4, HIGH);

 Serial.println();
 Serial.println(" --- test starts in 5 secs ---");
 delay(5000);

 Serial.print("Testing pump 1... ");
 digitalWrite(out1, LOW);
 delay(1000);
 digitalWrite(out1, HIGH);
 Serial.println("done.");
 delay(3000);
 
 Serial.print("Testing pump 2... ");
 digitalWrite(out2, LOW);
 delay(1000);
 digitalWrite(out2, HIGH);
 Serial.println("done.");
 delay(3000);

 Serial.print("Testing pump 3... ");
 digitalWrite(out3, LOW);
 delay(1000);
 digitalWrite(out3, HIGH);
 Serial.println("done.");
 delay(3000);

 Serial.print("Testing pump 4... ");
 digitalWrite(out4, LOW);
 delay(1000);
 digitalWrite(out4, HIGH);
 Serial.println("done.");
 
 Serial.println(" --- test finished ---");

 Serial.println("");
 Serial.println(" --- starting application in loop ---");
 Serial.println("");

}

void loop() {
 int sVal = 0;
 
 // Pump 1
 Serial.print("#1 -> ");
 sVal = analogRead(in1);
 if (sVal > dryVal1) {
 Serial.print(sVal);
 digitalWrite(out1, LOW);
 delay(pumpTime*1000);
 digitalWrite(out1, HIGH);
 Serial.print(" -> ");
 Serial.println(analogRead(in1));
 } else Serial.println(sVal);

 
 // Pump 2
 Serial.print("#2 -> ");
 sVal = analogRead(in2);
 if (sVal > dryVal2) {
 Serial.print(sVal);
 digitalWrite(out2, LOW);
 delay(pumpTime*1000);
 digitalWrite(out2, HIGH);
 Serial.print(" -> ");
 Serial.println(analogRead(in2));
 } else Serial.println(sVal);

 
 // Pump 3
 Serial.print("#3 -> ");
 sVal = analogRead(in3);
 if (sVal > dryVal3) {
 Serial.print(sVal);
 digitalWrite(out3, LOW);
 delay(pumpTime*1000);
 digitalWrite(out3, HIGH);
 Serial.print(" -> ");
 Serial.println(analogRead(in3));
 } else Serial.println(sVal);


 // Pump 4
 Serial.print("#4 -> ");
 sVal = analogRead(in4);
 if (sVal > dryVal4) {
 Serial.print(sVal);
 digitalWrite(out4, LOW);
 delay(pumpTime*1000);
 digitalWrite(out4, HIGH);
 Serial.print(" -> ");
 Serial.println(analogRead(in4));
 } else Serial.println(sVal);


 // sleeping
 Serial.println("... zZZ ...");
 Serial.print(sleepTimes);
 Serial.print(": "); 
 for (int x = 0; x < sleepTimes; x++) {
 Serial.print(" ");
 Serial.print(x);
 delay(10000);
 }
 Serial.println("");
 
}
Die Ausgabe
----------------------------------------------------------
| Water my plants www.it-aw.com debugging starts |
----------------------------------------------------------

Dry value is 1=280, 2=280, 3=280, 4=280 (measure has to be greater)

 --- test starts in 5 secs ---
Testing pump 1... done.
Testing pump 2... done.
Testing pump 3... done.
Testing pump 4... done.
 --- test finished ---

 --- starting application in loop ---

#1 -> 273
#2 -> 263
#3 -> 240
#4 -> 300 -> 173
... zZZ ...
30: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
#1 -> 282 -> 173
#2 -> 261
#3 -> 290 -> 190
#4 -> 226
... zZZ ...
30: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
#1 -> 249
#2 -> 262
#3 -> 268
#4 -> 231
... zZZ ...

Das Ergebnis

Wasserbehälter mit Schwimmer
Wasserbehälter mit Schwimmer
Arduino Uno in Aktion
Arduino Uno in Aktion
Verkabelung in wasserdichter Box
Verkabelung in wasserdichter Box

Update aus dem “Sommer”

Die Feuchtigkeitmesser

Leider haben sich die zuerst verwendeten Feuchtigkeitsmesser () als nicht besonders “tragfähig” erwiesen. Durch den anhaltenden Kontakt mit Wasser, der ‘dreckigen’ Erde und dem anliegenden Strom hat die Galvanisierung schneller und häftiger zugeschlagen als zunächst angenommen. Damit stieg der Widerstand immer weiter an, bis zuletzt ein realistisches Messen nicht mehr möglich war. Außerdem, so wurde mir zugetragen von Personen mit grünem Daumen, sind die sich ablösenden Metallbestandteile nicht die beste Idee für Pflanzen, die man essen möchte. Besonders empfindliche Pflanzen würden mir dies recht schnell übel nehmen, so der Experte…

Kurzer Hand, mit vielen Vergleichen im Internet, konnte ich hochwertige (s.g. Kapazitiver Bodenfeuchtesensor, Hochfrequenz-Bodenfeuchtesensoren) Bodenfeuchtemesser erstehen. Ich habe mich nach viel hin und her für das Modell
Vegetronix VH400
entschieden. Bislang (seit nun mehreren Monaten im Dauereinsatz) ein sehr zuverlässiges Gerät mit konstanten Messkurven und realistischen Ergebnissen.

Das Upgrade

Der Arduino hat einen sehr guten Dienst gemacht; keine Frage. Doch mit steigender Begeisterung für die voll-automatische Pflege meiner Pflanzen wollte ich natürlich irgendwann mehr. Mehr sehen, mehr machen, mehr protokollieren. Gerne wollte ich wissen

  • wann wurde gewässert
  • wie feucht sind die Pflanzen aktuell
  • Verlauf der Feuchtigkeit
  • Messung “Wasserstand” ausreichend
  • ggf. zusätzliche Verbräucher steuern (siehe “Der Style”)

Die Schlussfolgerung ist wohl schon jetzt klar: Update auf ein Raspberry (gern das 3er: es hat schon WLAN und Bluetooth an Board), alles neu verkabeln und Python-Skripte im Crontab. Die Logik ist natürlich gleich geblieben. Was dazu gekommen ist, ist ein Wasserstandswächter. Keine Bewässerung, wenn kein Wasser drin ist. Außerdem kann man dann ruhig mal eine Mail oder SMS bekommen…

Wasserstandswächter
Wasserstandwächter

Man sitzt ja nicht stundenlang vor einem Wassertrog um ihn zu beobachten… Zusätzlich einen kleine MySQL-Lösung mit ins Boot nehmen und schon kann man viele bunte Bilder malen lassen:

Grafik mit Liniendiagramm der den Verlauf der Messungen darstellt
Verlauf dank SQL-Datenbank

Ziemlich cool 🙂

Der Style

Und wo wir grad bei “cool” sind… Natürlich sind IT-/EDV-Lösungen immer ne super Sache, aber wenn es nicht “hübsch” aussieht, dann kann man damit auch nicht begeistern. Also alles einmal in hübsch: Brunnen als Wasserspeicher, Beleuchtung und bitte alles einmal schalten können. Direkt vom Smartphone natürlich…

Brunnen mit laufendem Wasser
Ein Brunnen
Brunnen mit eingeschaltetem Licht
Lichtspiele

Das Ergebnis:

Das Ergebnis nach den ersten richtigen Sonnenstrahlen
Die Pflanzen wachsen