====== Bewässerungsautomat Programmversion 0.4 ====== Diese Programmversion wird nicht mehr weiter entwickelt. Weiter geht es mit [[programmversion_0.5|Programmversion 0.5]] [[bewaesserungsautomat:programmversion_0.3|Programmversion 0.3]] läuft zwar im Großen und Ganzen, allerdings hat sich gezeigt, dass die Pumpen nicht wir vorgesehen mit Relais geschaltet werden können: Der Anlaufstrom ist derart hoch, dass der Spannungsregler abschaltet. Der Ausbau des Spannungsreglers hat auch nicht geholfen: Irgendwie gerät der Arduino durcheinander, sobald eine Pumpe anläuft. Die einzige Veränderung der Programmversion 0.4 zur Version 0.3 ist daher, dass die Pumpen per PWM angesteuert werden. ACHTUNG: Im Sketch unten ist das PWM-Signal mit "20" so niedrig eingestellt, dass die Pumpen nicht anlaufen, sondern nur "pfeifen", damit sie bei Tests nicht zu lange trocken laufen. Hilfreiche Links: * https://www.arduino.cc/en/Tutorial/PWM // Bibliotheken einbinden #include #include #include #include "Adafruit_TSL2591.h" #include "DHT.h" // Definiert die Pins für die NeoPixels int neoPin1 = 36; // Neopixel an Blumenkastenensor 1 int neoPin2 = 38; // Neopixel an Blumenkastenensor 2 int neoPin3 = 40; // Neopixel an Blumenkastenensor 3 int neoPin4 = 42; // Neopixel an Blumenkastenensor 4 int neoPin5 = 44; // Neopixelring am Wasserstandssensor im Vorratsbehälter int neoPin6 = 48; // Neopixelring im Gehäusedeckel //int neoPin6 = 50; // Reserviert für Erweiterungen // Definiert die NeoPixels Adafruit_NeoPixel neopix1 = Adafruit_NeoPixel(1, neoPin1, NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel neopix2 = Adafruit_NeoPixel(1, neoPin2, NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel neopix3 = Adafruit_NeoPixel(1, neoPin3, NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel neopix4 = Adafruit_NeoPixel(1, neoPin4, NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel neopix5 = Adafruit_NeoPixel(12, neoPin5, NEO_RGBW + NEO_KHZ800); Adafruit_NeoPixel neopix6 = Adafruit_NeoPixel(24, neoPin6, NEO_RGBW + NEO_KHZ800); // pass in a number for the sensor identifier (for your use later) Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // Definiert die Pins für die Hall-Sensoren int hallPin1 = 35; // Hall-Sensor 1 int hallPin2 = 33; // Hall-Sensor 2 int hallPin3 = 31; // Hall-Sensor 3 int hallPin4 = 29; // Hall-Sensor 4 // Definiert die Pins für die Verfügbarkeitskontrolle int massePin1 = 47; // Masse an Blumenkastenensor 1 int massePin2 = 49; // Masse an Blumenkastenensor 2 int massePin3 = 51; // Masse an Blumenkastenensor 3 int massePin4 = 53; // Masse an Blumenkastenensor 4 // Definiert die Pins des Wasserstandssensor für den Vorratsbehälter int refPin = A0; // Rref int levelPin = A1; // Rsense // Definiert den Pin für den DHT22 int dhtPin = 28; // Definiert den angeschlossenen Sensor #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321) // Initialisiert den DHT-Sensor DHT dht(dhtPin, DHTTYPE); // Definiert die Pins für die Pumpenrelais //int relPin1 = 36; // Pumpe 1 //int relPin2 = 38; // Pumpe 2 //int relPin3 = 40; // Pumpe 3 //int relPin4 = 42; // Pumpe 4 // Auskommentiert, da die Pumpen in diesem Sketch an den PWM-Pins 2,3,4 und 5 angeschlossen sind. // Definiert die Variablen int hall1 = LOW; int hall2 = LOW; int hall3 = LOW; int hall4 = LOW; int masse1 = LOW; int masse2 = LOW; int masse3 = LOW; int masse4 = LOW; int rlevel = 0; int rref = 0; int brightness = 0; boolean pumpe1 = false; boolean pumpe2 = false; boolean pumpe3 = false; boolean pumpe4 = false; void setup() { // Initialisiere die NeoPixel-Pins pinMode(neoPin1, OUTPUT); pinMode(neoPin2, OUTPUT); pinMode(neoPin3, OUTPUT); pinMode(neoPin4, OUTPUT); pinMode(neoPin5, OUTPUT); pinMode(neoPin6, OUTPUT); // Initialisiere die Hall-Pins als Inputs mit Pullup. Außerdem werden die internen Pullup-Widerstände aktiviert. // Liegt an dem Hall-Sensor ein Magnetfeld an, ist der Input LOW, ansonsten ist der Input HIGH. pinMode(hallPin1, INPUT_PULLUP); pinMode(hallPin2, INPUT_PULLUP); pinMode(hallPin3, INPUT_PULLUP); pinMode(hallPin4, INPUT_PULLUP); pinMode(massePin1, INPUT_PULLUP); pinMode(massePin2, INPUT_PULLUP); pinMode(massePin3, INPUT_PULLUP); pinMode(massePin4, INPUT_PULLUP); //Initialisiert den Pin für den DHT22 als Input mit Pullup pinMode(dhtPin, INPUT_PULLUP); // Initialisiere die Relais-Pins //pinMode(relPin1, OUTPUT); //pinMode(relPin2, OUTPUT); //pinMode(relPin3, OUTPUT); //pinMode(relPin4, OUTPUT); // Initialisiere den Wasserstandssensor pinMode(rlevel, INPUT); pinMode(rref, INPUT); // Initialisiere alle NeoPixels neopix1.begin(); neopix1.show(); // Initialize all pixels to 'off' neopix2.begin(); neopix2.show(); // Initialize all pixels to 'off' neopix3.begin(); neopix3.show(); // Initialize all pixels to 'off' neopix4.begin(); neopix4.show(); // Initialize all pixels to 'off' neopix5.begin(); neopix5.show(); // Initialize all pixels to 'off' neopix6.begin(); neopix6.show(); // Initialize all pixels to 'off' // Konfiguration des TSL2591 // You can change the gain on the fly, to adapt to brighter/dimmer light situations //tsl.setGain(TSL2591_GAIN_LOW); // 1x gain (bright light) tsl.setGain(TSL2591_GAIN_MED); // 25x gain // tsl.setGain(TSL2591_GAIN_HIGH); // 428x gain // Changing the integration time gives you a longer time over which to sense light // longer timelines are slower, but are good in very low light situtations! tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS); // shortest integration time (bright light) // tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS); // tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS); // tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS); // tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS); // tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS); // longest integration time (dim light) // Debugging output Serial.begin(9600); dht.begin(); tsl.begin(); delay(2000); // Diese Pause benötigt der DHT22 um erste Messwerte zu lesen. // Perspektivisch könnte eine Startanimation des NeoPixel-Rings die Wartezeit verkürzen. } void loop() { // Auslesen der digitalen Eingänge hall1 = digitalRead(hallPin1); hall2 = digitalRead(hallPin2); hall3 = digitalRead(hallPin3); hall4 = digitalRead(hallPin4); masse1 = digitalRead(massePin1); masse2 = digitalRead(massePin2); masse3 = digitalRead(massePin3); masse4 = digitalRead(massePin4); // Auslesen der analogen Eingänge rlevel = analogRead(levelPin); rref = analogRead(refPin); // Ausgabe der Eingangssignale an den digitalen Masse-Pins an die serielle Schnittstelle // Der Ausgabewert "0" bedeutet, dass der entsprechende Blumenkastensensor angeschlossen ist Serial.print("Sensor Kasten 1: "); Serial.print(masse1); Serial.print(" \t"); Serial.print("Sensor Kasten 2: "); Serial.print(masse2); Serial.print(" \t"); Serial.print("Sensor Kasten 3: "); Serial.print(masse3); Serial.print(" \t"); Serial.print("Sensor Kasten 4: "); Serial.print(masse4); Serial.println(" \t"); // Ausgabe der Eingangssignale an den digitalen Hall-Pins an die serielle Schnittstelle // Der Ausgabewert "1" bedeutet, dass kein Magnetfeld gemessen wird Serial.print("Hallschalter 1: "); Serial.print(hall1); Serial.print(" \t"); Serial.print("Hallschalter 2: "); Serial.print(hall2); Serial.print(" \t"); Serial.print("Hallschalter 3: "); Serial.print(hall3); Serial.print(" \t"); Serial.print("Hallschalter 4: "); Serial.print(hall4); Serial.println(" \t"); //Ausgabe des Status der Pumpen Serial.print("Pumpe 1: "); Serial.print(pumpe1); Serial.print(" \t"); Serial.print("Pumpe 2: "); Serial.print(pumpe2); Serial.print(" \t"); Serial.print("Pumpe 3: "); Serial.print(pumpe3); Serial.print(" \t"); Serial.print("Pumpe 4: "); Serial.print(pumpe4); Serial.println(" \t"); // Ausgabe des Eingangssignals an den analogen Wasserstands-Pins an die serielle Schnittstelle Serial.print("Wert Sensorwiderstand: "); Serial.print(rlevel); Serial.print("\t"); Serial.print("Wert Referenzwiederstand: "); Serial.print(rref); Serial.println("\t"); // Berechnung des Wasserstands im Vorratsbehälter in Prozent float rlevelmin = 830; // Messwert bei minimalem Wasserstand float rlevelmax = 430; // Messwert bei maximalem Wasserstand float level = 100 - (((rlevelmax - rlevel) / (rlevelmax - rlevelmin)) * 100); // Ausgabe des Wasserstands im Vorratsbehälter in Prozent an die serielle Schnittstelle Serial.print("Wasserstand: "); Serial.print(level); Serial.println(" %"); // More advanced data read example. Read 32 bits with top 16 bits IR, bottom 16 bits full spectrum // That way you can do whatever math and comparisons you want! uint32_t lum = tsl.getFullLuminosity(); uint16_t ir, full; ir = lum >> 16; full = lum & 0xFFFF; Serial.print("[ "); Serial.print(millis()); Serial.print(" ms ] "); Serial.print("IR: "); Serial.print(ir); Serial.print(" "); Serial.print("Full: "); Serial.print(full); Serial.print(" "); Serial.print("Visible: "); Serial.print(full - ir); Serial.print(" "); Serial.print("Lux: "); Serial.println(tsl.calculateLux(full, ir)); // Berechnung der Helligkeit der NeoPixel float brightness = log(full) / 10; Serial.print(brightness); // Ansteuerung der Pumpen. // Ist der Wasserstand niedrig, liegt kein Magnetfeld am Hall-Sensor an (hall = 1). // Die entsprechende Pumpe wird aktiviert, bis der Soll-Wasserstand erreicht ist (hall = 0), // - sofern keine andere Pumpe läuft und // - sofern Wasser im Vorratsbehälter ist. // Pumpe 1 an PWM-Pin 2 if (masse1 == 0 && hall1 == 1 && level > 5 && pumpe2 == false && pumpe3 == false && pumpe4 == false) { analogWrite(11, 20); pumpe1 = true; } else { analogWrite(11, 0); pumpe1 = false; } // Pumpe 2 an PWM-Pin 3 if (masse2 == 0 && hall2 == 1 && level > 5 && pumpe1 == false && pumpe3 == false && pumpe4 == false) { analogWrite(10, 20); pumpe2 = true; } else { analogWrite(10, 0); pumpe2 = false; } // Pumpe 3 an PWM-Pin 4 if (masse3 == 0 && hall3 == 1 && level > 5 && pumpe1 == false && pumpe2 == false && pumpe4 == false) { analogWrite(9, 20); pumpe3 = true; } else { analogWrite(9, 0); pumpe3 = false; } // Pumpe 4 an PWM-Pin 5 if (masse4 == 0 && hall4 == 1 && level > 5 && pumpe1 == false && pumpe2 == false && pumpe3 == false) { analogWrite(8, 20); pumpe4 = true; } else { analogWrite(8, 0); pumpe4 = false; } // Ansteuerung der NeoPixels in den Blumenkastensensoren if (hall1 == 0) { neopix1.setPixelColor(0, 0, 255*brightness, 0); //grün-weiß, wenn Wasserstand ok } else { neopix1.setPixelColor(0, 255*brightness, 0, 0); //rot, wenn Wasserstand niedrig } neopix1.show(); if (hall2 == 0) { neopix2.setPixelColor(0, 0, 255*brightness, 0); //grün-weiß, wenn Wasserstand ok } else { neopix2.setPixelColor(0, 255*brightness, 0, 0); //rot, wenn Wasserstand niedrig } neopix1.show(); if (hall3 == 0) { neopix3.setPixelColor(0, 0, 255*brightness, 0); //grün-weiß, wenn Wasserstand ok } else { neopix3.setPixelColor(0, 255*brightness, 0, 0); //rot, wenn Wasserstand niedrig } neopix3.show(); if (hall4 == 0) { neopix4.setPixelColor(0, 0, 255*brightness, 0); //grün-weiß, wenn Wasserstand ok } else { neopix4.setPixelColor(0, 255*brightness, 0, 0); //rot, wenn Wasserstand niedrig } neopix4.show(); //Ansteuerung des NeoPixel-Rings im Wasserstandssensor für den Vorratsbehälter neopix5.setPixelColor(0, 0, 0, 0, 255*brightness); neopix5.setPixelColor(11, 0, 0, 0, 255*brightness); if (level >= 90) { neopix5.setPixelColor(10, 0, 255*brightness, 0, 0); } else if (level < 90) { neopix5.setPixelColor(10, 0, 0, 0, 0); } if (level >= 80) { neopix5.setPixelColor(9, 0, 255*brightness, 0, 0); } else if (level < 80) { neopix5.setPixelColor(9, 0, 0, 0, 0); } if (level >= 70) { neopix5.setPixelColor(8, 0, 255*brightness, 0, 0); } else if (level < 70) { neopix5.setPixelColor(8, 0, 0, 0, 0); } if (level >= 60) { neopix5.setPixelColor(7, 0, 255*brightness, 0, 0); } else if (level < 60) { neopix5.setPixelColor(7, 0, 0, 0, 0); } if (level >= 50) { neopix5.setPixelColor(6, 127*brightness, 127*brightness, 0, 0); } else if (level < 50) { neopix5.setPixelColor(6, 0, 0, 0, 0); } if (level >= 40) { neopix5.setPixelColor(5, 127*brightness, 127*brightness, 0, 0); } else if (level < 40) { neopix5.setPixelColor(5, 0, 0, 0, 0); } if (level >= 30) { neopix5.setPixelColor(4, 127*brightness, 127*brightness, 0, 0); } else if (level < 30) { neopix5.setPixelColor(4, 0, 0, 0, 0); } if (level >= 20) { neopix5.setPixelColor(3, 255*brightness, 0, 0, 0); } else if (level < 20) { neopix5.setPixelColor(3, 0, 0, 0, 0); } if (level >= 10) { neopix5.setPixelColor(2, 255*brightness, 0, 0, 0); } else if (level <10) { neopix5.setPixelColor(2, 0, 0, 0, 0); } neopix5.show(); // Auslesen des DHT22 und Ausgabe der Werte an serielle Schnittstelle // Reading temperature or humidity takes about 250 milliseconds! // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) float h = dht.readHumidity(); // Luftfeuchte auslesen float t = dht.readTemperature(); //Temperatur in Grad Celsius auslesen // Check if any reads failed and exit early (to try again). if (isnan(h) || isnan(t)) { Serial.println("DHT22 konnte nicht ausgelesen werden!"); return; } // Hitzeindex in Celsius berechnen (isFahreheit = false) float hic = dht.computeHeatIndex(t, h, false); // Taupunkt berechnen float a = 17.271; float b = 237.7; float taupunktTmp = (a * t) / (b + t) + log(h/100); float taupunkt = (b * taupunktTmp) / (a - taupunktTmp); Serial.print("Luftfeuchte: "); Serial.print(h); Serial.print(" %\t"); Serial.print("Temperatur: "); Serial.print(t); Serial.print(" *C\t"); Serial.print("Hitzeindex: "); Serial.print(hic); Serial.print(" *C\t"); Serial.print("Taupunkt: "); Serial.print(taupunkt); Serial.println(" *C"); // Warnung bei Unterschreiten der Gehäuseinnentemperatur unter den Taupunkt if (t <= taupunkt) { neopix5.setPixelColor(0, 255*brightness, 0, 0, 0); neopix5.setPixelColor(11, 255*brightness, 0, 0, 0); } else if (t > taupunkt) { neopix5.setPixelColor(0, 0, 0, 0, 255*brightness); neopix5.setPixelColor(11, 0, 0, 0, 255*brightness); } delay(1000); // 1 Sek Pause }