Go Down

Topic: Wieder bewässerung (Read 3427 times) previous topic - next topic

oldmann

Guten Tag
 
Das alles ist mir klar. Nur weil die Sensoren günstig sind habe die bestellt.

In erste Linie will wissen ob funktionieren so wie deklariert. Wenn ja mache ich mir Gedanken über Versieglung.
In meinem Fall sind die Verbindungen kurz, also das analoge Signal wird nicht so stark gestört. Für langen Verbindungen wurde ich, klar der Giesomat bevorzugen.
Nach meinen Erkenntnissen, arbeitet in diesen Sensoren der NE555, ein Schaltkreis der sehr zuverlässig ist. Will keine Verübung machen, mall sehen. Im schlimmsten fall habe ich ein paar € falsch investiert (verloren).
Der große Vorteil dieser Variante:
alle Arduino Bords verwendbar, und keine zusätzlichen Schaltungen notwendig.
Es sei denn man seeeehr Großen Balkon hat :D

MfG

agmue

#31
Nov 13, 2018, 02:20 pm Last Edit: Nov 13, 2018, 03:15 pm by agmue
Mal ein Vorschlag mit run():

Code: [Select]
#include <Streaming.h>
const unsigned long pausenIntervall = 1000;  // Pause während des Giessens
unsigned long jetzt;                         // Variable für den aktuellen Zeitpunkt

struct Blumen                            // Struktur mit Konstanten, Variablen und Methoden
{ Blumen(const byte messPin, const byte relaisPin, const unsigned int trockenWert, const unsigned long messIntervall, const unsigned long giessIntervall, const unsigned long nachgiessenIntervall):
    messPin(messPin), relaisPin(relaisPin), trockenWert(trockenWert), messIntervall(messIntervall), giessIntervall(giessIntervall), nachgiessenIntervall(nachgiessenIntervall), messwert(0), vorhin(0), intervall(0), zaehler(0), schritt(0) {}

  void init()
  { pinMode(relaisPin, INPUT_PULLUP);
    pinMode(relaisPin, OUTPUT);
  }

  void run()
  { if (jetzt - vorhin >= intervall)
    { vorhin = jetzt;
      switch (schritt)
      { case MESSEN:
          if (trockenWert > analogRead(messPin))
          { digitalWrite(relaisPin, LOW); // Pumpe einschalten
            zaehler = 0;
            intervall = giessIntervall;
            schritt = GIESSEN;
          } else {
            intervall = messIntervall;
          }
          break;
        case GIESSEN:
          digitalWrite(relaisPin, HIGH); // Pumpe ausschalten
          if (5 > ++zaehler)
          { intervall = pausenIntervall;
            schritt = PAUSE;
          } else {
            intervall = nachgiessenIntervall;
            schritt = MESSEN;
          }
          break;
        case PAUSE:
          digitalWrite(relaisPin, LOW);
          intervall = giessIntervall;
          schritt = GIESSEN;
          break;
      }
      if (messPin == 15) Serial << "messPin: " << messPin << "  \twert: " << analogRead(messPin) << "  \tintervall: " << intervall << "  \tschritt: " << schritt << "  \tzaehler: " << zaehler << endl;
    }
  }

  const byte messPin, relaisPin;
  const int trockenWert;
  const unsigned long messIntervall, giessIntervall, nachgiessenIntervall;
  unsigned int messwert;
  unsigned long vorhin, intervall;
  byte zaehler, schritt;
  enum {MESSEN, GIESSEN, PAUSE};
};

Blumen blumen[]  // Ein Feld der Struktur Blumen
{ // messPin, relaisPin, trockenWert, messIntervall, giessIntervall, nachgiessenIntervall
  {A1, 2, 200, 3000, 500, 5000},  // Werte für Blume und Pumpe 1
  {A2, 3, 250, 2500, 500, 5000}   // Werte für Blume und Pumpe 2
};

void setup()
{ Serial.begin(115200);
  Serial.println(F("Anfang"));
  for (Blumen &b : blumen) b.init();  // alle Feldelemente werden nacheinender mit der Methode init abgearbeitet
}

void loop()
{ jetzt = millis();
  for (Blumen &b : blumen) b.run();
}


EDIT: Kommenrar " // Pumpe einschalten" ergänzt.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

oldmann

Wow! :smiley-eek:

Hier mein aktueller Stand:
Code: [Select]
unsigned long jetzt;                      // Variable für den aktuellen Zeitpunkt
byte zyklenzahl = 0;                      // Die Pumpe soll 4-mal kurz laufen dafuer Variable zyklenzahl

struct Blumen                             // Struktur mit Konstanten, Variablen und Methoden
{ Blumen(const byte messPin, const byte relaisPin, const unsigned int trockenWert, const unsigned long messIntervall, const unsigned long giessIntervall, const unsigned long nachgiessenIntervall):
    messPin(messPin), relaisPin(relaisPin), trockenWert(trockenWert), messIntervall(messIntervall), giessIntervall(giessIntervall), nachgiessenIntervall(nachgiessenIntervall), messwert(0), vorhin(0), intervall(0), schritt(0) {}

  void init()
  { pinMode(relaisPin, OUTPUT);
  }

  void run() {
    messwert = analogRead(messPin);       // Sensorwert auslesen
    if ((jetzt - vorhin >= messIntervall) && (messwert <= trockenWert)) {  // Wenn Messinterval abgelaufen und Blume troken
vorhin = jetzt;                       // Aktuelle Messzeitwert legen
    intervall = millis();                 // Aktuelle Zeitwert fuer Pumpen legen
    }
        switch (schritt) {
      case 0:
        if ((millis() - intervall >= nachgiessenIntervall) && (zyklenzahl < 4)) {  // Wenn Pumpepause abgelaufen und wenige als 4 Zyklen
           intervall = millis();          // Aktuelle Zeitwert fuer Pumpen legen
           digitalWrite(relaisPin, HIGH); // Pumpe einschalten
           schritt = 1;                   // Weiter zu naechsten Schritt
        }
        break;
      case 1:
        if (millis() - intervall >= giessIntervall) {  // Pumpenzeit abgelaufen
           intervall = millis();          // Aktuelle Zeitwert fuer Pumpen legen
           digitalWrite(relaisPin, LOW);  // Pumpe auschalten
           zyklenzahl++;                  // Zyklenzahl +1
           schritt = 0;                   // Wieder zu ersten Schritt
        }
        break;
    }
  }

  const byte messPin, relaisPin;
  const int trockenWert;
  const unsigned long messIntervall, giessIntervall, nachgiessenIntervall;
  unsigned int messwert;
  unsigned long vorhin, intervall;
  byte schritt;
};

Blumen blumen[]  // Ein Feld der Struktur Blumen
{ // messPin, relaisPin, trockenWert, messIntervall, giessIntervall, nachgiessenIntervall
  {A0, 2, 200, 3000, 500, 5000},
  {A1, 3, 250, 2500, 500, 5000},
  {A2, 4, 250, 2000, 250, 3000}
};

void setup()
{ for (Blumen &b : blumen) b.init();  // alle Feldelemente werden nacheinender mit der Methode init abgearbeitet
}

void loop()
{ jetzt = millis();
  for (Blumen &b : blumen) b.run();  // alle Feldelemente werden nacheinender mit der Methode run abgearbeitet
}

Du hast mir den ganzen Spaß verdorben ;)
ein Paar unterschiede kann man sehen  8)

Eine Frage:
Code: [Select]
case GIESSEN:
          digitalWrite(relaisPin, HIGH);
          if (5 > ++zaehler)
          { intervall = pausenIntervall;
            schritt = PAUSE;
          } else {
            intervall = nachgiessenIntervall;
            schritt = MESSEN;

Was hast Du vor mit "nachgiessenIntervall"
Ich finde keine verwendung.

MfG

agmue

#33
Nov 13, 2018, 03:09 pm Last Edit: Nov 13, 2018, 03:16 pm by agmue
Du hast mir den ganzen Spaß verdorben ;)
...
Was hast Du vor mit "nachgiessenIntervall"
Ich finde keine verwendung.
Sorry, das wollte ich nicht, Du darfst meinen Beitrag gerne ignorieren :)

Ich dachte, nach dem Giessen müßte man eine längere Messpause einlegen, damit sich die Feuchtigkeit ausbreiten kann. Daher habe ich eine längere Pause eingeplant. Aber das ist nur so theoretisch in meiner Phantasie entstanden, ich habe keinen grünen Daumen und keine Erfahrung mit Topfpflanzen.

Ich habe den Zeitvergleich nur einmal drin und variiere dafür den Wert der Variablen intervall.

Code: [Select]
digitalWrite(relaisPin, HIGH); // Pumpe einschalten
Da die Relais meist mittels LOW aktiviert werden, ist die Logik bei mir umgekehrt.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

oldmann

Als gegen Leistung: :smiley-lol:

Kleine Töpfe - wenig Blumenerde - geringe Speicher Kapazitäten - oft gießen.
Zu viel Wasser schadet dem meisten pflanzen. Weil Wasser kann nicht sofort durch den Boden aufgenommen werden, wenn Zuviel lauft über.
Aus diesem Grunde - gießen, pause, gießen, pause…
10 min später prüft kaum jemand. In der Natur hat die Bodenfeuchtigkeit keinem konstantem wert.

Zu dem Sketch:

Das verstehe ich nicht.

case MESSEN - if Bedingung erfüllt, Pumpe ein, Zähler auf null, für variable „intervall" der Wert „giessIntervall" gesetzt und weiter in
case GIESSEN - und hier als erster Schritt: Pumpe aus.

Wie lange ist dann die Pumpe gelaufen?

agmue

#35
Nov 13, 2018, 04:57 pm Last Edit: Nov 13, 2018, 04:57 pm by agmue
Wie lange ist dann die Pumpe gelaufen?
intervall = giessIntervall; der fünfte Wert der Struktur, also 500 ms.

Auf dem seriellen Monitor kannst Du Dir das ansehen, habe ich extra dringelassen.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

oldmann

Danke

Ich habe die ganze zeit in der switch Ausführung die braek Anweisung für mich weggedrückt,
also die run Methode quasi als eine Schleife gesehen. Jetzt muss ich das richtig durchkauen.

Zwei Fragen habe ich noch: if (messPin == 15) Serial - warum 15?  und wie komm der andere Sensor
auf dem seriellen Monitor?

postmaster-ino

Hi
Zwei Fragen habe ich noch: if (messPin == 15) Serial - warum 15?  und wie komm der andere Sensor
auf dem seriellen Monitor?
So ganz ohne Punkt und Komma ist der Satz einfach nur eine Anreihung von mehr oder minder sinnlosen Buchstaben.
Immerhin auch Große dabei ...
Auch habe ich diesen Snipped in den Code-Tags hier nicht wirklich gefunden - was möchtest Du mir damit sagen, damit ich Dir darauf antworten kann?

MfG

oldmann

Code: [Select]
  if (messPin == 15) Serial << "messPin: " << messPin << "  \twert: " << analogRead(messPin) << "  \tintervall: " << intervall << "  \tschritt: " << schritt << "  \tzaehler: " << zaehler << endl;

In den Code im Feld Blumen blumen[] gibt nur zwei werte für messPin: A1 und A2, und hier messPin == 15. Was bedeutet Wert 15?
Auf dem seriellen Monitor wird gezeigt der Wert messPin A1. Wie bekomme ich auf dem seriellen Monitor den anderen Wert: messPin A2?

MfG

agmue

#39
Nov 14, 2018, 12:51 am Last Edit: Nov 14, 2018, 11:12 am by agmue
Was bedeutet Wert 15?
Die Arduino-Pins haben unterschiedliche Bezeichnungen, bei einem UNO kennst Du die Pins 0 bis 13, A0 ist 14, A1 ist auch 15, A2 ist auch 16 usw.

if (messPin == 16) ...

Bei switch/case hadere ich auch immer mit den Bezeichnungen, weil man vom Warten aus giesst und von Giessen aus wartet. Wenn Dich das stört, kann man das mit einem Merker besser lösen. Siehe #41.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

oldmann

Hallo

Stören - nein. In allen was habe ich bis jetzt über Arduino gelesen waren die analogen Eingänge mit A0,A1 usw. bezeichnet. Das man kann die auch so in den Code bezeichnen habe ich erst jetzt von Dir erfahren. Gut zu wissen.

Danke

agmue

#41
Nov 14, 2018, 11:11 am Last Edit: Nov 14, 2018, 11:14 am by agmue
Ich habe es Dir und mir leider schwerer gemacht, als nötig. Die hoffentlich bezogen auf die Schrittekette einfacher zu verstehende Variante:

Code: [Select]
#include <Streaming.h>
const unsigned long pausenIntervall = 1000;  // Pause während des Giessens
unsigned long jetzt;                         // Variable für den aktuellen Zeitpunkt

struct Blumen                            // Struktur mit Konstanten, Variablen und Methoden
{ Blumen(const byte messPin, const byte relaisPin, const unsigned int trockenWert, const unsigned long messIntervall, const unsigned long giessIntervall, const unsigned long nachgiessenIntervall):
    messPin(messPin), relaisPin(relaisPin), trockenWert(trockenWert), messIntervall(messIntervall), giessIntervall(giessIntervall), nachgiessenIntervall(nachgiessenIntervall), messwert(0), vorhin(0), intervall(0), zaehler(0), schritt(0) {}

  void init()
  { pinMode(relaisPin, INPUT_PULLUP);
    pinMode(relaisPin, OUTPUT);
  }

  void run()
  { if (jetzt - vorhin >= intervall)
    { vorhin = jetzt;
      switch (schritt)
      { case MESSEN:
          if (trockenWert > analogRead(messPin))
          { schritt = GIESSEN;
            zaehler = 0;
          } else {
            intervall = messIntervall;
          }
          break;
        case GIESSEN:
          digitalWrite(relaisPin, LOW);
          intervall = giessIntervall;
          schritt = PAUSE;
          break;
        case PAUSE:
          digitalWrite(relaisPin, HIGH);
          if (5 > ++zaehler)
          { intervall = pausenIntervall;
            schritt = GIESSEN;
          } else {
            intervall = nachgiessenIntervall;
            schritt = MESSEN;
          }
          break;
      }
      if (messPin == 15) Serial << "messPin: " << messPin << "  \twert: " << analogRead(messPin) << "  \tintervall: " << intervall << "  \tschritt: " << schritt << "  \tzaehler: " << zaehler << endl;
    }
  }

  const byte messPin, relaisPin;
  const int trockenWert;
  const unsigned long messIntervall, giessIntervall, nachgiessenIntervall;
  unsigned int messwert;
  unsigned long vorhin, intervall;
  byte zaehler, schritt;
  enum {MESSEN, GIESSEN, PAUSE};
};

Blumen blumen[]  // Ein Feld der Struktur Blumen
{ // messPin, relaisPin, trockenWert, messIntervall, giessIntervall, nachgiessenIntervall
  {A1, 2, 200, 3000, 500, 5000},  // Werte für Blume und Pumpe 1
  {A2, 3, 250, 2500, 500, 5000}   // Werte für Blume und Pumpe 2
};

void setup()
{ Serial.begin(115200);
  Serial.println(F("Anfang"));
  for (Blumen &b : blumen) b.init();  // alle Feldelemente werden nacheinender mit der Methode init abgearbeitet
}

void loop()
{ jetzt = millis();
  for (Blumen &b : blumen) b.run();
}

Der von mir erwähnte Merker ist notwendig, wenn die Zeit innerhalb des Schrittes abgefragt wird. Bei einer rein zeitgesteuerten Schrittkette kann man aber außerhalb der Schrittkette die Zeit abfragen.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

oldmann

Viel Dank für Deine mühe

Mein Problem ist entstanden durch meinen Denkfehler. Wenn die Schrittekette ohne break Anweisung analysiert wird, kommen eben solche dummen fragen.

MfG

oldmann

Guten Tag

Ich habe jetzt vor das Gießen in der Nacht abstellen und nicht gebrauchte in diese Zeit Hardware abschalten. Dafür soll ein Tag/Nacht Status dienen. Das funktioniert einwandfrei, ich habe aber keine Idee wie kann das Gießen gestoppt sein.

Hat jemand ein Tipp für mich.
Hier der Code:
Code: [Select]
#include <Streaming.h>
const unsigned long pausenIntervall = 1000;  // Pause während des Giessens
unsigned long jetzt;                         // Variable für den aktuellen Zeitpunkt
unsigned long vorBright = 0;                 // Variable fuer Messintervalle Helligkeit
const unsigned long brightIntervall = 10000; // Helligkeit Messungen Intervall
bool tagnachtStatus = true;                  // Tag - Nacht Status

const byte brightness = A0;    // Helligkeit Sensoreingang
const byte powerPin = 4;       // Ausgang fuer Nachtabschaltung
byte brightwert0 = 0;          // Messwert fuer berechnung Helligkeit Mittelwert
byte brightwert1 = 0;          // Messwert fuer berechnung Helligkeit Mittelwert         
byte brightwert2 = 0;          // Messwert fuer berechnung Helligkeit Mittelwert

struct Blumen                            // Struktur mit Konstanten, Variablen und Methoden
{ Blumen(const byte messPin, const byte relaisPin, const unsigned int trockenWert, const unsigned long messIntervall, const unsigned long giessIntervall, const unsigned long nachgiessenIntervall):
    messPin(messPin), relaisPin(relaisPin), trockenWert(trockenWert), messIntervall(messIntervall), giessIntervall(giessIntervall), nachgiessenIntervall(nachgiessenIntervall), messwert(0), vorhin(0), intervall(0), zaehler(0), schritt(0) {}

void init() {
pinMode(relaisPin, INPUT_PULLUP);
    pinMode(relaisPin, OUTPUT);
}

void run() {
if (jetzt - vorhin >= intervall) {
vorhin = jetzt;
        switch (schritt) {
case MESSEN:
            if (trockenWert > analogRead(messPin)) {
schritt = GIESSEN;
                zaehler = 0;
            }
else {
            intervall = messIntervall;
            }
        break;
            case GIESSEN:
            digitalWrite(relaisPin, LOW);
            intervall = giessIntervall;
            schritt = PAUSE;
        break;
            case PAUSE:
            digitalWrite(relaisPin, HIGH);
            if (5 > ++zaehler) {
intervall = pausenIntervall;
                schritt = GIESSEN;
            }
else {
intervall = messIntervall;
    schritt = MESSEN;
            }
        break;
        }
    if (messPin == 15) Serial << "messPin: " << messPin << "  \twert: " << analogRead(messPin) << "  \tintervall: " << intervall << "  \tschritt: " << schritt << "  \tzaehler: " << zaehler << endl;
        }
    }

  const byte messPin, relaisPin;
  const int trockenWert;
  const unsigned long messIntervall, giessIntervall, nachgiessenIntervall;
  unsigned int messwert;
  unsigned long vorhin, intervall;
  byte zaehler, schritt;
  enum {MESSEN, GIESSEN, PAUSE};
};

Blumen blumen[]  // Ein Feld der Struktur Blumen
{ // messPin, relaisPin, trockenWert, messIntervall, giessIntervall, nachgiessenIntervall
  {A1, 2, 200, 3000, 500, 5000},  // Werte für Blume und Pumpe 1
  {A2, 3, 250, 2500, 500, 5000}   // Werte für Blume und Pumpe 2
};

void setup() {
Serial.begin(115200);
    Serial.println(F("Anfang"));
    pinMode(powerPin, OUTPUT);
    for (Blumen &b : blumen) b.init();  // alle Feldelemente werden nacheinender mit der Methode init abgearbeitet
}

void loop() {
jetzt = millis();
    brightwert0 = analogRead(brightness);           // Aktuellen Helligkeit Wert als erste Messwert schreiben   
    if (jetzt - vorBright >= brightIntervall) {     // Messpause fuer Helligkeit messung abgelaufen
vorBright = jetzt;                      // Zeitpunkt für aktuellen Messung
if (((brightwert0+brightwert1+brightwert2)/3) < 160) {  // Wenn Helligkeit Mittelwert kleiner Sollwert
tagnachtStatus = false;                 // Status false - Nacht
brightwert2 = brightwert1;              // Zweiten Helligkeitwert als dritten schreiben
brightwert1 = brightwert0;              // Ersten Helligkeitwert als zweiten schreiben
digitalWrite(powerPin, tagnachtStatus); // Power ausgang EIN
}
    else {                  // Sonst
tagnachtStatus = true;                  // Status true - Tag
brightwert2 = brightwert1;              // Zweiten Helligkeitwert als dritten schreiben       
brightwert1 = brightwert0;              // Ersten Helligkeitwert als zweiten schreiben
digitalWrite(powerPin, tagnachtStatus); // Power ausgang AUS
}
}
if (tagnachtStatus = true) {
for (Blumen &b : blumen) b.run();
}
}

Danke in voraus.

MfG


agmue

Abkürzung (ungetestet):

Code: [Select]
void loop() {
  jetzt = millis();
  brightwert0 = analogRead(brightness);           // Aktuellen Helligkeit Wert als erste Messwert schreiben
  if (jetzt - vorBright >= brightIntervall) {     // Messpause fuer Helligkeit messung abgelaufen
    vorBright = jetzt;                        // Zeitpunkt für aktuellen Messung
    tagnachtStatus = ((brightwert0 + brightwert1 + brightwert2) / 3) < 160; // Wenn Helligkeit Mittelwert kleiner Sollwert; Status false - Nacht, Status true - Tag
    brightwert2 = brightwert1;              // Zweiten Helligkeitwert als dritten schreiben
    brightwert1 = brightwert0;              // Ersten Helligkeitwert als zweiten schreiben
    digitalWrite(powerPin, tagnachtStatus); // Power ausgang EIN
  }
  if (tagnachtStatus = true) {
    for (Blumen &b : blumen) b.run();
  }
}
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Go Up