Benutzer-Werkzeuge

Webseiten-Werkzeuge


bewaesserungsautomat:programmversion_0.5

Bewässerungsautomat Programmversion 0.5

Achtung!

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

Programmversion 0.5 eliminiert den delay()-Befehl am Ende der Programmversion 0.4. Diese Umstellung ist notwendig, um die Neopixel nicht nur an- und ausschalten zu können, sondern sie in der Helligkeit „pulsieren“ können zu lassen. Mit delay() wartet die Programmschleife nach jedem Durchlauf eine definierte Zeit, bevor sie nochmals durchlaufen wird. Mit dem millis()-Befehl kann man die Programmschleife so umbauen, dass einzelne if-Abfragen nach einer vorgegebenen Zeit ausgeführt werden. Auf diese Weise ist es möglich, verschiedene if-Abfragen mit unterschiedlichen Frequenzen ausführen zu können. Beispielsweise kann die if-Abfrage für die Steuerung der NeoPixel alle 10 ms durchlaufen werden, während die restliche Programmschleife weiterhin nur alle 1000 ms ausgeführt wird.

Hilfreiche Links:

Der folgende Code läuft, allerdings nicht ganz rund: Der Fading-Effekt hakelt etwas. Durch einige Optimierungen des Programms konnte das Hakeln gemildert werden, ganz verschwunden ist es aber noch nicht.

Was noch zu tun ist:

  • Der Fading-Effekt muss geschmeidiger laufen.
// 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 NeoPixel
#define neoPin1 36            // Neopixel an Blumenkastenensor 1
#define neoPin2 38            // Neopixel an Blumenkastenensor 2
#define neoPin3 40            // Neopixel an Blumenkastenensor 3
#define neoPin4 42             // Neopixel an Blumenkastenensor 4
#define neoPin5 44             // Neopixelring am Wasserstandssensor im Vorratsbehälter
#define neoPin6 48            // Neopixelring im Gehäusedeckel
//#define neoPin6 = 50           // Reserviert für Erweiterungen

// Definiert die NeoPixel
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
#define hallPin1 35        // Hall-Sensor 1
#define hallPin2 33        // Hall-Sensor 2
#define hallPin3 31        // Hall-Sensor 3
#define hallPin4 29        // Hall-Sensor 4

// Definiert die Pins für die Verfügbarkeitskontrolle
#define massePin1 47        // Masse an Blumenkastenensor 1
#define massePin2 49        // Masse an Blumenkastenensor 2
#define massePin3 51        // Masse an Blumenkastenensor 3
#define massePin4 53        // Masse an Blumenkastenensor 4


// Definiert die Pins des Wasserstandssensor für den Vorratsbehälter
#define refPin A0   // Rref
#define levelPin A1 // Rsense

// Definiert den Pin für den DHT22
#define dhtPin 28

// Definiert den angeschlossenen Sensor
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321)

// Initialisiert den DHT-Sensor
DHT dht(dhtPin, DHTTYPE);

// 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;
int rref;
int level;
float h;
float t;
float taupunkt;

uint16_t ir;
uint16_t full;
uint32_t lum;

float brightness = 127;

byte green;
byte red;
byte blue;

boolean  pumpe1 = false;
boolean  pumpe2 = false;
boolean  pumpe3 = false;
boolean  pumpe4 = false;

// Definiert die Tracking-Variablen für die IF-Abfragen
unsigned long previousMillisNeoPixel = 0;
unsigned long previousMillisWaterPumps = 0;
unsigned long previousMillisTankSensor = 0;
unsigned long previousMillisSerialWrite = 0;

// Definiert die Intervalle für die IF-Abfragen
int intervalNeoPixel = 10;
int intervalWaterPumps = 500;
int intervalTankSensor = 500;
int intervalSerialWrite = 2000;

byte counter = 0;
boolean sw = true;


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

  
// Initialisiere die serialle Schnittstelle
  Serial.begin(9600);

//Initiallisiere die Sensoren  
  dht.begin(); //Temperatur- und Feuchtigkeitssensor
  tsl.begin(); //Lichtsensor

  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() {
  // Aktuelle Zeit abfragen
  unsigned long currentMillis = millis();


  // Abfrage der analogen und digitalen Eingänge und Steuerung der Pumpen
  if ((unsigned long)(currentMillis - previousMillisWaterPumps) >= intervalWaterPumps) {
  
  
  // 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);

  //Auslesen des Helligkeitssensors
  lum = tsl.getFullLuminosity();
  ir = lum >> 16;
  full = lum & 0xFFFF;

  // Auslesen des DHT22
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  h = dht.readHumidity(); // Luftfeuchte auslesen
  t = dht.readTemperature(); //Temperatur in Grad Celsius auslesen

  // Berechnung des Wasserstands im Vorratsbehälter in Prozent
  int rlevelmin = 830; // Messwert bei minimalem Wasserstand
  int rlevelmax = 430; // Messwert bei maximalem Wasserstand
  level = 100 - (((rlevelmax - rlevel) / (rlevelmax - rlevelmin)) * 100);

  // Berechnung der Helligkeit der NeoPixel
  brightness = log(full) / 10;

  // Taupunkt berechnen
  float a = 17.271; 
  float b = 237.7; 
  float taupunktTmp = (a * t) / (b + t) + log(h/100); 
  taupunkt = (b * taupunktTmp) / (a - taupunktTmp); 


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


  //Speichere die aktuelle Zeit in die zughörige Variable
  previousMillisWaterPumps = currentMillis;
  }




  // Steuerung der NeoPixel
  if ((unsigned long)(currentMillis - previousMillisNeoPixel) >= intervalNeoPixel) {


  // Ansteuerung der NeoPixels in den Blumenkastensensoren
      if(sw)
        {
        counter++;
        if(counter==255) sw = !sw;
        }
        if(!sw)
        {
        counter--;
        if(counter==10) sw = !sw;
        }
        // fade led mit counter
        green = counter*brightness;
        red = counter*brightness;

           //NeoPixel an Blumenkastensensor 1
           
           if (hall1 == 0) {
           neopix1.setPixelColor(0, 0, red, 0);
           }
           else {
           neopix1.setPixelColor(0, green, 0, 0); 
           }
           neopix1.show();


           //NeoPixel an Blumenkastensensor 2
           
           if (hall2 == 0) {
           neopix2.setPixelColor(0, 0, red, 0);
           }
           else {
           neopix2.setPixelColor(0, green, 0, 0); 
           }
           neopix2.show();


           //NeoPixel an Blumenkastensensor 3
           
           if (hall3 == 0) {
           neopix3.setPixelColor(0, 0, red, 0);
           }
           else {
           neopix3.setPixelColor(0, green, 0, 0); 
           }
           neopix3.show();
           
           
           //NeoPixel an Blumenkastensensor 4
           
           if (hall4 == 0) {
           neopix4.setPixelColor(0, 0, red, 0);
           }
           else {
           neopix4.setPixelColor(0, green, 0, 0); 
           }
           neopix4.show();

   //Speichere die aktuelle Zeit in die zughörige Variable
   previousMillisNeoPixel = currentMillis;
   }

//Ansteuerung der NeoPixel in dem Messstab für den Vorratstank
  if ((unsigned long)(currentMillis - previousMillisTankSensor) >= intervalTankSensor) {
  //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();
    


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

   //Speichere die aktuelle Zeit in die zughörige Variable
   previousMillisTankSensor = currentMillis;
   }



  //Ausgabe an die serielle Schnittstelle
 if ((unsigned long)(currentMillis - previousMillisSerialWrite) >= intervalSerialWrite) {

  Serial.println("------------------------------------");
  
  //Ausgabe des Zeitstempels
   Serial.print("[ "); Serial.print(millis()); Serial.println(" ms ] ");

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

  // Ausgabe des Wasserstands im Vorratsbehälter in Prozent an die serielle Schnittstelle
  Serial.print("Wasserstand: "); Serial.print(level); Serial.println(" %");

  //Ausgabe verschiedener Helligkeitswerte an die serielle Schnittstelle
  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));

  //Ausgabe der Temperatur-, Luftfeuchte und des berechneten Taupunkts an die serielle Schnittstelle
  Serial.print("Luftfeuchte: "); Serial.print(h); Serial.print(" %\t");
  Serial.print("Temperatur: "); Serial.print(t); Serial.print(" *C\t");
  Serial.print("Taupunkt: "); Serial.print(taupunkt); Serial.println(" *C");

  //Ausgabe des berechneten Helligkeitswerts an die sereille Schnittstelle
  Serial.print("Helligkeit: "); Serial.println(brightness);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println("DHT22 konnte nicht ausgelesen werden!");
    return;
  }

  previousMillisSerialWrite = currentMillis;
  }
 
}

Tags: #Arduino #Bewässerungsautomat #Code

bewaesserungsautomat/programmversion_0.5.txt · Zuletzt geändert: 18.05.2023 12:15 von 127.0.0.1