====== 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
}