Benutzer-Werkzeuge

Webseiten-Werkzeuge


bewaesserungsautomat:programmversion_0.3

Dies ist eine alte Version des Dokuments!


Bewässerungsautomat Programmversion 0.3

Achtung!

Diese Programmversion wird nicht mehr weiter entwickelt. Weiter geht es mit Programmversion 0.5 alpha

Gegenüber Programmversion 0.2 alpha wurde verändert:

  • Der DHT22 wird ausgelesen und die Werte an die serielle Schnittstelle ausgegeben.
  • Auf Basis der gemessenen Temperatur und Luftfeuchte wird der Hitzeindex berechnet und an die serielle Schnittstelle ausgegeben.
  • Auf Basis der gemessenen Temperatur und Luftfeuchte wird der Taupunk berechnet und an die serielle Schnittstelle ausgegeben.
  • Wenn die Gehäuseinnentemperatur unter den Taupunkt fällt, leuchten am NeoPixel-Ring am Wasserstandssensor zwei LEDs rot statt weiß.
  • Der Wasserstandssensor für den Vorratsbehälter wird ausgelesen und in einen prozentualen Füllstand umgerechnet. Damit funktioniert jetzt auch die Ansteuerung des NeoPixel-Rings am Wasserstandssensor.
  • Der TSL2591 wird ausgelesen und die Werte an die serielle Schnittstelle ausgegeben.
  • Auf Basis der gemessenen Helligkeit wird eine Variable berechnet, mit der die Helligkeit der NeoPixel gesteuert wird.

Hilfreiche Links:

Was noch zu tun ist (in dieser oder einer späteren Programmversion):

  • Damit die Neopixel blinken oder pulsieren können, müsste das Programm ohne den delay-Befehl auskommen.
    • Wenn das Programm entsprechend umgestellt wurde, sollen die NeiPixel in den Blumenkastensensoren pulsieren.
    • Für die NeoPixel-Ringe sind Animationen denkbar.
  • Bluetooth
  • Der Wasserstandssensor könnte schneller ausgelesen und ein Mittelwert über die letzten X Messwerte gebildet werden, um schnelle Schwankungen, die auf Messfehler zurückgehen, zu vermeiden.
  • Es wäre zu überlegen, wie der gemessene Referenzwiederstand in die Berechnung des Wasserstands einbezogen werden kann.
// 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 = 12;            // Neopixel an Blumenkastenensor 1
int neoPin2 = 11;            // Neopixel an Blumenkastenensor 2
int neoPin3 = 10;            // Neopixel an Blumenkastenensor 3
int neoPin4 = 9;             // Neopixel an Blumenkastenensor 4
int neoPin5 = 8;             // Neopixelring am Wasserstandssensor im Vorratsbehälter
int neoPin6 = 7;             // Neopixelring im Gehäusedeckel
//int neoPin6 = 6;           // Reserviert für Erweiterungen
//int neoPin6 = 5;           // 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 = 32;        // Hall-Sensor 1
int hallPin2 = 30;        // Hall-Sensor 2
int hallPin3 = 28;        // Hall-Sensor 3
int hallPin4 = 26;        // Hall-Sensor 4

// Definiert die Pins für die Verfügbarkeitskontrolle
int massePin1 = 46;        // Masse an Blumenkastenensor 1
int massePin2 = 48;        // Masse an Blumenkastenensor 2
int massePin3 = 50;        // Masse an Blumenkastenensor 3
int massePin4 = 52;        // Masse an Blumenkastenensor 4


// Definiert die Pins des Wasserstandssensor für den Vorratsbehälter
int refPin = A1;   // Rref
int levelPin = A2; // Rsense

// Definiert den Pin für den DHT22
int dhtPin = 39;

// 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

// 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;

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 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
  if (masse1 == 0 && hall1 == 1 && level > 5 && digitalRead(relPin2) == HIGH && digitalRead(relPin3) == HIGH && digitalRead(relPin4) == HIGH) {
    digitalWrite(relPin1, LOW);
  }
  else {
    digitalWrite(relPin1, HIGH);
  }

  // Pumpe 2
  if (masse2 == 0 && hall2 == 1 && level > 5 && digitalRead(relPin1) == HIGH && digitalRead(relPin3) == HIGH && digitalRead(relPin4) == HIGH) {
    digitalWrite(relPin2, LOW);
  }
  else {
    digitalWrite(relPin2, HIGH);
  }

  // Pumpe 3
  if (masse3 == 0 && hall3 == 1 && level > 5 && digitalRead(relPin1) == HIGH && digitalRead(relPin2) == HIGH && digitalRead(relPin4) == HIGH) {
    digitalWrite(relPin3, LOW);
  }
  else {
    digitalWrite(relPin3, HIGH);
  }

  // Pumpe 4
  if (masse4 == 0 && hall4 == 1 && level > 5 && digitalRead(relPin1) == HIGH && digitalRead(relPin2) == HIGH && digitalRead(relPin3) == HIGH) {
    digitalWrite(relPin4, LOW);
  }
  else {
    digitalWrite(relPin4, HIGH);
  }


  // 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, 127);
  neopix5.setPixelColor(11, 0, 0, 0, 127);
 
    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, 127, 0, 0, 0);
      neopix5.setPixelColor(11, 127, 0, 0, 0);
    } else if (t > taupunkt) {
      neopix5.setPixelColor(0, 0, 0, 0, 127);
      neopix5.setPixelColor(11, 0, 0, 0, 127);
    }
    
  delay(1000);                    // 1 Sek Pause
}

Tags: #Arduino #Bewässerungsautomat #Code

bewaesserungsautomat/programmversion_0.3.1465654939.txt.gz · Zuletzt geändert: 18.05.2023 09:06 (Externe Bearbeitung)