bewaesserungsautomat:programmversion_0.4
Bewässerungsautomat Programmversion 0.4
Achtung!
Diese Programmversion wird nicht mehr weiter entwickelt. Weiter geht es mit Programmversion 0.5
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:
// Bibliotheken einbinden
#include <Wire.h>
#include <Adafruit_NeoPixel.h>
#include <Adafruit_Sensor.h>
#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
}
bewaesserungsautomat/programmversion_0.4.txt · Zuletzt geändert: 18.05.2023 12:15 von 127.0.0.1