Pflanzengießanlage Problem bei Errorcheck

Hallo,

die Idee ist folgende:
Wenn ein Timer (aktuell 10 Minuten) abgelaufen ist misst er die Feuchtigkeit im Topf (2 parallele Nägel, die wegen Elektrolyse nur zur Messung Strom kriegen (siehe Routine ReadSens).

Wenn diese unter der Kalibration liegen die gehalten werden soll, merkt er sich die Feuchtigkeit und gießt.
Falls bei der nächsten Messung (nach weiteren 10 Minuten) noch immer zu trocken, muss die gemessene Feuchtigkeit zumindest höher sein als die vor dem letzten Gießen.

Wenn es 3x hintereinander zu trocken ist und die Feuchtigkeit nicht gestiegen ist, ist davon auszugehen ein Schlauch ist nicht mehr am Topf und das Gießen wird gestoppt (ErrSchwelle ist 3, wenn die erreicht stoppt er das Gießen).
Sollte nachdem es vorher zu trocken war bei der nächsten Messung die Feuchtigkeit ok sein, ist der Schlauch noch dran und der "LastSense1" wird auf 0 gesetzt, damit von vorne begonnen wird, falls es wieder mal zu trocken wird.

Nun habe ich irgendwie scheinbar ein Problem mit dem LastSense1 speichern/vergleichen etc.
Irgendwie bricht er vor dem 4. Gießen (also nach 3 Fehlern) immer wieder mit Error ab.

Anfangs hatte ich den LastSense1 wenn die Feuchtigkeit beim Nächsten Messen ok war nicht auf 0 gesetzt und dachte den Fehler gefunden zu haben, aber er macht es immer noch.

Auch die +5 beim Vergleich hatte ich später hinzugefügt, weil er sonst wegen minimaler Schwankungen des ADC teilweise Err1 (Fehlercounter) auf 0 gestellt hat und dann erst nach 5-7 Fehlern statt 3 aufgehört hat zu gießen. Dies geht aber damit wie es soll.

Als ich das im Topf mit Erde getestet hab und zum simulieren der Feuchtigkeit den Sensor weiter rein oder raus gezogen habe klappte alles wie es soll.
Nur wenn ich es im mit Pflanzen laufen lasse, bricht er immer wieder nach der Anzahl Gießen ab die der Fehlerschwelle entsprechen (selber Sensor).

Eigentlich sollte er ja wenn es mal feucht genug ist LastSense wieder auf 0 setzten und daher nicht den Errorcounter hochzählen, er tut es aber scheinbar, da er nach 3x gießen (max. Fehlerschwelle) abbricht.
Er scheint nicht in die entsprechende if zu springen, die den Errorcounter resettet.

Ich hab das im EEprom aufgezeichnet. Graph diehe Anhang. Der Graph ist aber runter gemappt, damit ich es als byte ins EEprom schreiben kann (Calib +- 250 auf 0-255 gemappt), daher sind das natürlich andere Zahlen an der Skala. Aber den Verlauf sieht man gut. Im Graph ist die rote Linie der Kalibrationswert der gehalten werden soll, das blaue ist das Wasser.

Ich weiß einfach nicht weiter was ich übersehen hab!
Ich hab keine Ahnung, was das Problem ist und schon stundenlang gesucht und komme nicht weiter....

Ich hab die relevanten Teile des Codes mal rauskopiert und die unwichtigen wie LEDs und Kalibration etc weggelassen, da das alles geht wie es soll.

Achso das Gießen wird in der MessGiess Routine gestartet, abgeschaltet wird die Pumpe durch die PumpOFF Routine nach 20 Sekunden, oder durch die PumpOFFWet Routine (misst alle 3 Sekunden beim Gießen) wenn es feuchter ist als Calib+100. Dann wird auch der Messtimer für die nächsten 10 Minuten neu gestartet.

void loop() {

  // Wenn Wasser voll, keine Fehler, dann messen und giessen starten (Errorcheck in Routine)
  if ((WaterOK == 1) && (millis() - MessTimer1Start >= MessZeit) && (digitalRead(Pump1) == LOW) && (digitalRead(Pump2) == LOW)) {        // Wenn Wasserstand OK, Messtimer 1 abgelaufen und alle Pumpen aus Giessen 1
    MessGiess1();
  }
  if ((WaterOK == 1) && (millis() - MessTimer2Start >= MessZeit) && (digitalRead(Pump1) == LOW) && (digitalRead(Pump2) == LOW)) {        // Wenn Wasserstand OK, Messtimer 2 abgelaufen und alle Pumpen aus Giessen 2
    MessGiess2();
  }
}

void MessGiess1() {
  if ((Calib1 > 0) && (Err1 < ErrSchwelle)) {           // Wenn Sensor kalibiert und Errorschwelle nocht nicht erreicht
    int Messwert = ReadSens1();                         // Feuchtigkeit messen
    if (Messwert < MinCalib) {                          // Bei Sensorfehler Error setzen und nicht giessen
      Err1 = ErrSchwelle;
    }
    else if (Messwert >= Calib1) {                      // Ansonsten, wenn kein Fehler Feuchtigkeit OK Messtimer und Fehlermessung resetten
      LastSens1 = 0;                                    // Fehlermessung resetten
      MessTimer1Start = millis();
    }
    else if (Messwert < Calib1) {                       // Ansonsten, wenn kein Fehler und zu trocken
      if (Messwert > LastSens1 + 5) {                   // Wenn seit letztem giessen feuchter geworden (+5 wegen ADC-Schwankungen)
        LastSens1 = Messwert;                           // Fehlermessung auf aktuellen Wert setzen
        Err1 = 0;                                       // Fehler löschen
        GiessTimer1Start = millis();                    // Giesstimer starten
        WetTimerStart = millis();                       // Feuchtigkeitstimer starten
        digitalWrite(Pump1, HIGH);                      // Pumpe 1 an
      }
      else {                                            // Wenn seit letztem giessen nicht feuchter geworden
        LastSens1 = Messwert;                           // Fehlermessung auf aktuellen Wert setzen
        Err1++;                                         // Fehlercounter eins hoch
        GiessTimer1Start = millis();                    // Giesstimer starten
        WetTimerStart = millis();                       // Feuchtigkeitstimer starten
        digitalWrite(Pump1, HIGH);                      // Pumpe 1 an
      }
    }
  }
}

void PumpOFF() {
  if ((digitalRead(Pump1) == HIGH) && (millis() - GiessTimer1Start >= GiessZeit)) {       // Wenn Pumpe 1 an und Giesstimer 1 abgelaufen
    digitalWrite(Pump1, LOW);
    digitalWrite(Sens1LED, HIGH);
    MessTimer1Start = millis();                                                           // Messtimer 1 resetten
  }
  if ((digitalRead(Pump2) == HIGH) && (millis() - GiessTimer2Start >= GiessZeit)) {       // Wenn Pumpe 2 an und Giesstimer 2 abgelaufen
    digitalWrite(Pump2, LOW);
    digitalWrite(Sens2LED, HIGH);
    MessTimer2Start = millis();                                                           // Messtimer 2 resetten
  }
}

void PumpOFFWet() {
  if (millis() - WetTimerStart >= WetTime) {
    if (digitalRead(Pump1) == HIGH) {
      if (ReadSens1() > Calib1 + MaxFeuchtigkeit) {
        digitalWrite(Pump1, LOW);
        digitalWrite(Sens1LED, HIGH);
        MessTimer1Start = millis();                                                       // Messtimer 1 resetten
      }
    }
    if (digitalRead(Pump2) == HIGH) {
      if (ReadSens2() > Calib2 + MaxFeuchtigkeit) {
        digitalWrite(Pump2, LOW);
        digitalWrite(Sens2LED, HIGH);
        MessTimer2Start = millis();                                                       // Messtimer 2 resetten
      }
    }
    WetTimerStart = millis();                                                             // Feuchtigkeit Messstimer neu starten
  }
}

int ReadSens1() {
  digitalWrite(SensPower1, HIGH);
  delay(1);
  int Sens = analogRead(Sens1);
  digitalWrite(SensPower1, LOW);
  return Sens;
}

Gorkde:
die Idee ist folgende:
Wenn ...

Ja, bei diesem verschachtelten if()-Gedöns kann man ab und zu den Überblick verlieren.

Zeichne dieses Gedöns als Programmablaufplan. Mache Deinen Code übersichtlicher (kurze Kommentare, kurze Zeilen).

Außerdem fällt mir dazu nur ein: Ausdrucken, mit Zeichnung vergleichen, Kaffee trinken ...

Gruß

Gregor

Ich weiß einfach nicht weiter was ich übersehen hab!

Serial.print - Ausgaben!
Statte deinen Code mit Serial.print Debug-Ausgaben aus und beobachte was dein Sketch tut.
Tief runter in jedes deiner If's.

P.S.: das posten von nicht lauffähigen Code bringt nichts. Wir sehen keine Definitionen/Deklarationen und Erfahrungsgemäß ist der Fehler in Abschnitten, die nicht gepostet wurden. Stelle einen kompilierbaren Sketch - reduziert auf das nötigste ein, nach dem du entsprechende Serial.print Ausgaben ergänzt hast.

Ich rate dazu, das Programm umzubauen.

Es ist offensichtlich eine Ablaufsteuerung, oder soll eine werden.
Also sollte man auch konsequent auf das Konzept "Endlicher Automat" oder "Schrittkette" setzen, und die Zustände klar als solche benennen.

Ich sehe min 3 Automaten.

  1. Pumpenabhandlung
  2. Messen
  3. Fehlerüberwachung
    Diese kann man getrennt erstellen.
    Klare Schnittstellen zwischen ihnen schaffen.

Das dürfte das IF Gewussel deutlich reduzieren und helfen, die Angelegenheit übersichtlich zu gestalten.

HI

Und ganz nebenbei - zwei Nägel zur Feuchte-Messung dürften suboptimal sein.
Nicht nur, daß Diese weggammeln und somit keinen einheitlichen Messwert über die Zeit bringen - die Pflanzen haben gleich auch noch was davon.

Zur Fehler-Einkreisung wurden Serial.print schon genannt.
Zur Übersicht State-Maschine und Kommentare.

Durch das If-Gewusel habe ich mich Mal nicht durchgekämpft.

MfG

Naja es geht ja nur um die Lastsens Geschichte in der Messgiess Routine.Der ganze Rest geht ja.

Wenn Feuchtigkeit höher oder gleich Calib soll er LastSense zurücksetzen, wenn niedriger als Calib soll er
Und auch das geht beim testen, nur leider eben scheinbar nicht im Topf, daher vermute ich ich hab nen Denkfehler gemacht oder irgendwo in der Routine nen Flüchtigkeitsfehler den ich einfach nicht sehe.

Die Serial.Print hatte ich immer drin wenn was nicht lief, aber es ging dann ja mit ner Tasse voll Erde, nur sobald es im Topf ist eben scheinbar nicht.

Und das mal eben alles aufzeichnen wenns im Topf steht würde bedeuten ne Woche den PC im Dauerlauf, nur damit er die Serial.print aufzeichnen kann. Was ohne Ende Strom kostet.
Daher dachte ich vielleicht sieht einer den Fehler, denn ich finde den nicht, hab schon 5 Milliarden mal gesucht.

Gorkde:
hab schon 5 Milliarden mal gesucht.

So alt kannst Du überhaupt noch nicht sein.

Wenn man für 1 Mal suchen 10 Minuten veranschlagt (und das ist schon knapp bemessen) kommt man auf 95129 Jahre (wenn ich mich nicht verrechnet habe - dann möge man mich korrigieren).

Deine Aussage ist also garantiert falsch. :wink:

Gruß Tommy

also in 1 x 10 Minuten hättest auch Serial.print einbauen können.

Und jetzt überleg mal, wenn der Code "in der Tasse" funktioniert, aber "nicht im Topf"
... warum glaubst du, ist der Fehler im Code?
... Verkabelung Tasse vs. Topf ist ident?

Ansonsten:

  • kein kompilierbarer Sketch
  • keine Bilder
  • kein Schaltplan
  • Kein Mitleid

Gorkde:
…….Was ohne Ende Strom kostet.
Daher dachte ich vielleicht sieht einer den Fehler, denn ich finde den nicht, hab schon 5 Milliarden mal gesucht.

Wo sollen wir deine Fehler finden ?
Im unvollständigen Sketch ?
Im nicht vorhanden Schaltbild ?
Oder in den nicht vorhandenen Bildern ?
Ok....sollte funktionieren, wenn wir Hellseher wären.

Wenn du jetzt schon über Stromkosten jammerst, was ist denn, wenn dein Projekt in Dauerbetrieb geht ?

Hi

uptime
 21:30:07 up 11 days,  4:42,  2 users,  load average: 0,39, 0,40, 0,39

Ich sehe ja ein, daß ich ein Umwelt-Rüpel bin - aber irgendwie muß ja auch ich meine Heizungssteuerung testen :wink:
Das ist ja gerade das Spannende: Ob mein heutiges Wirken den Erfolg zeigt, Den ich erhoffe, sehe ich erst Morgen Abend - ok, Tagsüber könnte ich Das wohl auch sehen - nur da muß ich halt arbeiten ...

MfG

Ich hab die Daten mal in Excel gepackt und genau analysiert.

Er hat scheinbar nicht, wie ich dachte nach den 3x unter der Schwelle seit Beginn abgeschaltet, sondern hatte zum Ende tatsächlich 4 Messungen wo es nicht feuchter wurde und wie er sollte abgeschaltet (Bild angehängt).

Nun frage ich mich nur, warum er keine höhere Feuchte gemessen hat, obwohl der Topf beim letzten Gießen klitschnass war und sogar unten was raus lief....

Scheint also garkein Problem im Programm zu sein, sondern mit dem Sensor vermute ich mal....

Bisher hatte ich +5V an einem Nagel (eingeschaltet vom Arduino), den 2. Nagel an den ADC und von da 1k gegen Masse (als Spannungsteiler).

Da bekomme ich werte zwischen 500 und 900 ungemappt. Dachte das ist genau genug, aber irgendwie scheint das nicht zu funktionieren so....

Meint ihr es macht Sinn den Bereich zu verändern, indem ich den Bereich mit kleinerem Widerstand nach unten schiebe und per OP verstärke?

Hat einer von euch sowas ohne kapazitiver Messung schonmal gebaut und kann mir nen Tip geben wie er das vor dem ADC aufgebaut hat, sofern es anders ist?

Und nur mal nebenbei:
Ich hatte nur die in Frage kommenden Teile des Codes gepostet, weil wenn ich bisher alles gepostet habe, egal in welchen Forum, hatte niemand Lust hatte durchzusehen, also hab ich es so kurz wie möglich gehalten.
Und selbst bei der recht kurzen MessGiess-Routine war es ja den meisten schon zu lang um drauf zu gucken. Den Rest hab ich nur dazu gepostet falls jemand den Ablauf der Timer oder das Abschalten nachvollziehen möchte.

"moisture sensor 1.2" beim zuverlässigen Chinesen für ca 1 Komma 3 Euronen.....

Gorkde:
Hat einer von euch sowas ohne kapazitiver Messung schonmal gebaut und kann mir nen Tip geben wie er das vor dem ADC aufgebaut hat, sofern es anders ist?

Wenn du es weiterhin einfach halten willst, dann verwende folgende Schaltung am Arduino mit zwei V2A-Drähten als Sensor.

Wassersensor1_PNP.png

Ich nutze diese zwar nicht zum Ertränken von Pflanzen, sondern prüfe ich an bestimmten Stellen im Keller auf Feuchtigkeit. Und das schon über Jahre.

Wassersensor1_PNP.png

Hi

Wo ich gerade Keller lese - Da hatte ich Mal was Tolles gelesen!
Als Meldung von Feuchtigkeit im Keller wurde ein 08/15 Baumarkt-Rauchmelder (billig) umgebastelt auf Mikro-Taster.
Dieser wird von einem Stück Würfelzucker betätigt.
Solange keine flüssige Feuchtigkeit an den Zucker kommt, ist Alles ok - sobald auch nur ein Tropfen den Zuckerwürfel benetzt, wird Dieser von dem Mikro-Taster zerdrückt und der Alarm geht los.

Aktuell hier halte ich Es, wie bereits in #4 beschrieben:
Zwei Nägel gammeln im Erdreich, gerade mit DC beaufschlagt, binnen kurzer Zeit weg, während dieser Zeit sind die Messwerte wohl mehr Hausnummern, als einheitlich und nebenbei verrecken die Pflanzen an einer Eisen Überdosis.

MfG

und nebenbei verrecken die Pflanzen an einer Eisen Überdosis

Och, Eisen mögen sie ja noch gut weg stecken ...
Gibt genug Gegenden der Welt wo die Erde (Rost) Rot ist.

Aber wenn das mit den Chrom und Nickel Ionen, des Edelstahls, los geht.....
Die Tomaten möchte ich dann doch nicht unbedingt essen.

Sowohl eisen als auch Schwefel Chrom etc brauchen Pflanzen, C/N etc. allerdings in geringen Dosen, wie es in der Erde vorkommt.
Wenn ich Den Strom für 1ms alle 10 Minuten einschalte dauert es vermutlich millionen Jahre ehe der dicke nagel weg ist.....
Darum mache ich mir also keine Gedanken. Es geht mehr um die Genauigkeit der Messung.

Und ich würde gerne dabei bleiben, die Sensoren Bei Ali kenne ich.

Die Schaltung mit dem Transistor hilft mir vielleicht.... Ich stehe mit Transistoren schon seit der FOS auf Kriegsfuß!

Die verstärkt nicht, sondern liefert nur mehr strom richtig?

Achso:
Ich hab mal die Messwerte ohne delay angehängt und die Schaltung des Sensors....
Der erste Messwert ist hoch, bis er sich dann irgendwann auf einem Wert einpendelt.

Wenn ich einen dieser Sketches rauf lade hat er von Beginn die richtige Messung, aber warum?

Both of these give the same good results:

----------------------------------------------------

void setup() {
Serial.begin(115200);
pinMode(A0, INPUT);
pinMode(2, OUTPUT);
digitalWrite(2, LOW);
analogRead(A0);
}

void loop() {
delay(0);
digitalWrite(2, HIGH);
delay(10000);
Serial.println(analogRead(A0));
digitalWrite(2, LOW);
}

----------------------------------------------------

void setup() {
Serial.begin(115200);
pinMode(A0, INPUT);
pinMode(2, OUTPUT);

digitalWrite(2, HIGH);
analogRead(A0);
digitalWrite(2, LOW);
delay(20000);    					// Needs to be 20000 instead of 10000 to be the same accuracy (tested even after 4 min of waiting before readong the second time)
}

void loop() {
digitalWrite(2, HIGH);
Serial.println(analogRead(A0));
digitalWrite(2, LOW);
}

ADC Verlauf - Schaltung.png

Gorkde:
.....
Die verstärkt nicht, sondern liefert nur mehr strom richtig?
.....

So was nennt man auch Stromverstärkung.

Grad noch mal deinen Sketch angesehen.

Was stört dich daran, wenn die Messwerte sofort stimmen ?

HotSystems:
So was nennt man auch Stromverstärkung.

Ja, ich meinte damit die Spannung wird nicht verändert oder?

Grad noch mal deinen Sketch angesehen.
Was stört dich daran, wenn die Messwerte sofort stimmen ?

Meinst Du "wenn die Messwerte NICHT sofort stimmen?"

Ganz einfach bei der Kalibration nehme ich sofern ich EEPromaufzeichnung an hab ja den ersten Messwert als Kalibration und daher dachte ich das wäre vielleicht für mein Problem verantwortlich, dass er immer abbricht.