Do It Yourself

Automatische Bewässerung für ein Hochbeet

Daimler TSS und Daimler IT Retail SocialDay 2016 – Prototyp

2016_Giessanlage

 

1 Vorbemerkungen

2016_GiessanlageDieses Dokument beschreibt eine Giessanlage, welche im Rahmen des SocialDays der beiden Daimler-Töchter Daimler TSS und Daimer ITR auf der Kulturinsel in Stuttgart entstanden ist. Das besondere dieser beiden Beete ist ihre vertikale Ausrichtung – gewährleistet durch jeweils 2 Europaletten, die stabil miteinander verschraubt wurden. Die Kulturinsel Stuttgart ist eine Plattform, auf der Menschen ihre Ideen verwirklichen können. Auf dem Gelände des ehemaligen Güterbahnhofs in Bad Cannstadt ist u.a. Raum für urbanes Gärtners gegeben – das Projekt Inselgrün, mit kunstvollen, kreativen Bepflanzungen. Ziel des Projektes war die Konzipierung und Umsetzung einer automatischen Giessanlage, die das Hochbeet mit der richtigen Menge an Giesswasser versorgt – und ganz nebenbei für coole Lichteffekte sorgt. Als technische Grundlage wurde ein Arduino verwendet – ein einfaches, günstiges Mikrocontroller Board mit eigener IDE.

2 Handwerkliches

2.1 Bau der Beete

2016_Giessanlage2016_GiessanlageGrundlage eines vertikalen Beetes waren jeweils 2 Europaletten, welche vertikal verschraubt wurden. An den Stirnseiten der Palletten wurde in mittlerer Höhe jeweils ein kleines Brett angebracht – sieht Abbildung 1 (dort wird es gerade verschraubt). Dieses Brett verhindert, dass die Erde später zu den Seiten heraus fällt. Die horizontale Palette auf dem Boden diente nur der Stabilisierung während der Bauphase und wurde im Anschluss entfernt. Etwas trickreich ist das Verschrauben der beiden Paletten: die Schrauben müssen diagonal gesetzte werden, sodass sie in beiden Paletten greifen (Abbildung 2). Wir haben die Schrauben alternierend aus beiden Richtungen eingeschraubt (also einmal in Palette 1 angesetzt Richtung Palette 2, bei der nächsten Schraube in Palette 2 angesetzt in Richtung Palette 1).

2016_GiessanlageIm Innern des vertikalen Beets wird auf mittlerer Höhe ein Brett verschraubt, welche später den Boden des Beetes bildet. Bis hierhin wird also Erde aufgefüllt (Abbildung 5 und 6). In die Paletten werden zu einer Seite oben rechts ein Loch gesägt. Dieses Loch dient später dazu, dort Technik zu „verstecken“.

2016_GiessanlageHier wird später Wasserpumpe, Temperatursensor und Arduino versteckt. Bevor das vertikale Beet mit Erde gefüllt wurde, wird der Innenraum bis zum horizontalen Brett mit einer festen Plane ausgeschlagen, die mit kleinen Holzschrauben an den Paletten befestigt wird. Sie dient dazu, die Erde zu halten. An der Oberseite der aufrecht stehenden Paletten wird ein Schlauch angebracht, welcher mittels Kabelbindern fixiert wurde. Achtung! Kabelbinder nicht so fest zubinden, dass der Schlauch zerdrückt wird. Durch diesen Schlauch wird später das Giesswasser geführt. Das eine Ende des Schlauches wird fest mit der Europalette verschraubt (sodass dort kein Wasser austreten kann).

2016_GiessanlageRechts und links werden kleine Löcher in den Schlauch gebohrt – hier kann später das Wasser austreten. Achtung! Löcher in Richtung der Erde bohren, andernfalls dient die Giessanlage eher als Springbrunnen bzw. spritzt vorbeigehende Passanten nass. Das andere Ende des Schlauches (also dass, das nicht an die Europalette genagelt wird) wird hinter dem Beet mit der Pumpe verbunden, von der Pumpe führt ein weiter Schlauch in einen hinter der Palette stehenden Eimer.

2016_Giessanlage

2.2 Bepflanzung

Durch das Verschrauben von 2 Europaletten entsteht ein vertikales Beet mit insgesamt 10 bepflanzbaren Hohlräumen (in der Abbildung unten mit 1 – 10 markiert). Die seitlichen Beete 1 und 10 können jeweils mit einer Pflanze bepflanzt werden, die breiteren Teilbeete 2 – 9 wurden mit jeweils 2 Planzen bestückt, sodass insgesamt 18 Pflanzen pro vertikalem Beet gepflanzt wurden. Zum Abdecken der Erde wurde ausserdem noch Moos benutzt, sodass ein schnelles Verdunsten des Giesswassers verhindert wird. Die hier beschriebenen Beete sind im Spätsommer entstanden, sodass die Bepflanzung vom Character her sehr herbstlich war.

2016_Giessanlage

2.3 Sensoren

Pro vertikalem Hochbeet wurden 2 Feuchtigkeitssensoren in das Beet eingebracht – ein Sensor jeweils an der Oberfläche des Beetes und ein Sensor im Inneren. Auf diese Weise kann festgestellt werden, ob sich im Inneren Staunässe gebildet hat, obwohl die Oberfläche sehr trocken ist (z.B. bei Sonneneinstrahlung). Ein intensiver Regen kann aber auch dazu führen, dass die Oberfläche des Beetes sehr nass ist, obwohl im inneren große Trockenheit herrscht – z.B. nach ein längeren intensiven Warmperiode. Ultraschallsensoren wurden an die Wassereimer angebracht und dienen hier der Messung des Wasserstandes. Ein Temperatursensor zu Messung der Lufttemperatur wurde an die Rückseite der Beete angebracht2016_Giessanlage

2.4 Aktoren

2.4.1 Wasserpumpe

Die Wasserpumpe versorgt den in Kapitel 1 beschriebenen „Giessschlauch“ und bezieht selber Wasser aus einem Eimer, der hinter dem Vertikalbeet steht. Der Wasserstand in diesem Eimer wird über einen Ultraschallsensor geprüft und mit dem im folgenden Kapitel beschriebenen Lichtband wird der Wasserstand „visualisiert“.

2.4.2 Lichtband

Aufgabe des Gärtners dieser Giessanlage ist es lediglich, den Wassereimer kontinuierlich gefüllt zu haben. Ein Lichtband signalisiert dem Gärtner ein erforderliches Eingreifen, d.h. die Notwendigkeit, denn Wassereimer mit Wasser aufzufüllen.

2016_Giessanlage

2.5 Schaltplan Anlage

Im Schaltplan sind alle Sensoren und Aktoren sowie deren PIN-Belegung im Arduino dargestellt.

2016_Giessanlage

3 Programmierung des Arduinos

3.1 Code

#include "SI114X.h"

#include "Adafruit_NeoPixel.h"

#include "DHT.h"

#include "Ultrasonic.h"




/*-----( Declare Constants )-----*/

#define RELAY_ON 1

#define RELAY_OFF 0




#define UPSIDE_MOISTURE_SENSOR A2

#define DOWNSIDE_MOISTURE_SENSOR A3

#define TEMPERATURE_SENSOR 2

#define PUMP_RELAY 5

#define LIGHT_PIN 8

#define DISTANCE_SENSOR 6




#define DAY 50 // Sensorwerte, ggf. anpassen XXX

#define WET 400

#define SUNNY 2000

#define WINTER 5// in Grad Celsius, bei kleineren Temp. Wird nicht

               //gegossen

#define WATER_DISTANCE 20

#define WATER_DISTANCE2 10

#define SLEEPTIME 60000 // in ms




SI114X light_sensor = SI114X();




#define DHTPIN 2

#define DHTTYPE DHT22   // DHT 22  (AM2302)

//#define DHTTYPE DHT21   // DHT 21 (AM2301)




Adafruit_NeoPixel strip = Adafruit_NeoPixel(30, LIGHT_PIN, NEO_GRB + NEO_KHZ800);




DHT dht(DHTPIN, DHTTYPE);

Ultrasonic ultrasonic(DISTANCE_SENSOR);




// wird einmalig beim Start ausgeführt

void setup() {

  // put your setup code here, to run once:

  pinMode(PUMP_RELAY, OUTPUT);

  Serial.begin(9600);          //  setup serial

  while (!light_sensor.Begin()) {

    Serial.println("light sensor not ready");

  }

  dht.begin();




#if defined (__AVR_ATtiny85__)

  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);

#endif

  // End of trinket special code




// Lichtband

  strip.begin();

  strip.show(); // Initialize all pixels to 'off'




  Serial.println("finished setup");

}




// läuft zur Laufzeit nach Setup ununterbrochen

void loop() {







// Beginn Auslesen Sensorwerte




// Feuchtigkeit

  showFluidLevel();




  //Licht: liest IR und UV Anteile separat und VIS (sichtbares Licht)

  Serial.print("VIS: ");

  Serial.println(light_sensor.ReadVisible());

  Serial.print("IR: ");

  Serial.println(light_sensor.ReadIR());

  Serial.print("UV: ");

  Serial.println((float)light_sensor.ReadUV() / 100);




  //Feuchtigkeit der Erde

  int val = analogRead(UPSIDE_MOISTURE_SENSOR);

  Serial.println(val);

  int val2 = analogRead(DOWNSIDE_MOISTURE_SENSOR);

  Serial.println(val2);




// Luftfeuchtigkeit und Temperatur

  float h = dht.readHumidity();

  float t = dht.readTemperature();




  Serial.print("Humidity: ");

  Serial.print(h);

  Serial.print(" %\t");

  Serial.print("Temperature: ");

  Serial.print(t);

  Serial.println(" *C");




// Ultraschallmessung zur Bestimmung der Wasserstandshöhe im Wasserbehälter

  long RangeInCentimeters;

  RangeInCentimeters = ultrasonic.MeasureInCentimeters();

  Serial.print("distance in cm: ");

  Serial.println(RangeInCentimeters);




// Kombination aller Sensorwerte




  if (shouldSpillWater()) { // Sollen wir viel gießen?

    Serial.println("Spilling water");

    turnPumpOn();

    delay(5000);

    turnPumpOff();

  } else if (shouldSpillSomeWater()) { // oder sollen wir wenig gießen?

    Serial.println("Spilling some water");

    turnPumpOn();

    delay(1000);

    turnPumpOff();

  } else {

    Serial.println("idle\n"); // oder sollen wir gar nicht gießen?

  }

  delay(SLEEPTIME); // Wartezeit in ms  




}




// Überwacht Wassertank und Anzeige des Lichtbandes

void showFluidLevel() {

  long RangeInCentimeters;

  RangeInCentimeters = ultrasonic.MeasureInCentimeters();




  if (notEnoughWater(RangeInCentimeters)) {

    Serial.print("Not enough distance: ");

    Serial.println(RangeInCentimeters);

    colorWipe(strip.Color(255, 0, 0), 50); // Red

  }

  else if (refillSomeWater(RangeInCentimeters)) {

    Serial.print("Some water distance: ");

    Serial.println(RangeInCentimeters);

    colorWipe(strip.Color(255, 140, 0), 50); // ORANGE

  }

  else {

    Serial.print("OK: ");

    Serial.println(RangeInCentimeters);

    colorWipe(strip.Color(0, 255, 0), 50); // Green

  }

}




bool shouldSpillWater() {

  if (!tooCold() && isDay() && !tooSunny() && !isDownsideWet()) {

    return true;

  }

  return false;

}




bool shouldSpillSomeWater() {

  if (!tooCold() && isDay() && !tooSunny() && isDownsideWet() && !isUpsideWet()) {

    return true;

  }

  return false;

}




void turnPumpOff() {

  digitalWrite(PUMP_RELAY, RELAY_OFF);

}




void turnPumpOn() {

  digitalWrite(PUMP_RELAY, RELAY_ON);

}




bool isDay() {

  return light_sensor.ReadVisible() > DAY;

}




bool tooSunny() {

  return light_sensor.ReadVisible() > SUNNY;

}




bool isDownsideWet() {

  return analogRead(DOWNSIDE_MOISTURE_SENSOR) > WET;

}




bool isUpsideWet() {

  return analogRead(UPSIDE_MOISTURE_SENSOR) > WET;

}




bool tooCold() {

  return dht.readTemperature() < WINTER;

}




bool notEnoughWater(long RangeInCentimeters) {

  return RangeInCentimeters > WATER_DISTANCE;

}




bool refillSomeWater(long RangeInCentimeters) {

  return RangeInCentimeters > WATER_DISTANCE2;

}




// Fill the dots one after the other with a color

void colorWipe(uint32_t c, uint8_t wait) {

  for (uint16_t i = 0; i < strip.numPixels(); i++) {

    strip.setPixelColor(i, c);

    strip.show();

    delay(wait);

  }

}

Anleitung als Download


Bei Fragen steht dir Raif zur Seite:
raif@kulturinsel-stuttgart.org

 

This is a unique website which will require a more modern browser to work!

Please upgrade today!