Pumpenansteuerung für Elektrolytumwälzung und Raumbelüftung gelöst

meikvr6:

Mal getestet, was der Codeschnipsel aus #57 hergibt?
Immerhin hab ich meiner Annahme nach die Abschaltbedingung mit eingebaut.

Mehrere Bibliotheken wurden für "TaskMacro.h" gefunden
Benutzt: C:\Users\meik\Documents\Arduino\libraries\TaskMacro
Nicht benutzt: C:\Program Files (x86)\Arduino\libraries\TaskMacro

Die alte löschen, die neue behalten!

Oder Task durch void ersetzen.
Ist auch nur ein Alias.

Ich habe die libraries noch mal Alle durch deine ersetzt.

Dann wären doch keine Duplikate da.

@combie
ich konnte deinen Code jetzt ohne Fehler laden.
Leider ist die Funktion nicht gegeben.

@my_xy_projekt
Das Programm von dir läuft aus meiner Sicht ohne Probleme.

Leider ist die Funktion nicht gegeben.

Die Fehlerbeschreibung ist, naja, unzureichend....
Aber was solls, wenn du deine Lösung schon hast, ist mir das natürlich auch recht.

@my_xy_projekt
Ich habe jetzt die Pausenzeit auf 10min geändert.
Leider schaltet das Programm vor Ablauf der Zeit...

const unsigned long pausezeit = 60000;

@combie
ich möchte dein Programm trotzdem gerne zum laufen bringen.
Die LED geht kurz an sobald ich den POTI + - drehe geht die Diode (Pumpe) aus und ich bekomme sie auch nicht mehr an.

drehe geht die Diode (Pumpe) aus und ich bekomme sie auch nicht mehr

Mein InvOutputPin invertiert.

LED aus, bedeutet also: Pumpe an.
Wenn das bei dir andersrum soll, dann OutputPin statt InvOutputPin verwenden.

Ansonsten hat das noch den 10Min an, 10Min aus Takt, bei Anforderung.

meikvr6:
Ich habe jetzt die Pausenzeit auf 10min geändert.
Leider schaltet das Programm vor Ablauf der Zeit...

Wirklich auf 10 und nicht auf 1?
Was? An? Aus?
Kannst Du sicherstellen, das Dein Eingangssignal sauber ist?
Ich habe hier einen UNO am laufen, der nur mit einem Kabel zwischen GND/5V und A0 verbunden ist.
Das Ding läuft noch immer ohne Probleme.

[edit]
Bedingungen zum schalten:

  1. Wert > 520 UND pause gelöscht
  2. Wert < 520 UND PIN gesetzt
  3. Zeit ist um UND pause gesetzt UND PIN gesetzt
  4. Zeit ist um UND pause gesetzt UND PIN gelöscht

Es müssen also um einen Schaltvorgang auszulösen mindestens zwei Bedingungen erfüllt sein.

Geht die Pumpe vorzeitig aus, ist der Grenzwert nicht erreicht
Das löschen von pause geht nur, wenn alle drei Bedingungen (Nr. 4.) erfüllt sind.

my_xy_projekt:
Wirklich auf 10 und nicht auf 1?
Was? An? Aus?
Kannst Du sicherstellen, das Dein Eingangssignal sauber ist?
Ich habe hier einen UNO am laufen, der nur mit einem Kabel zwischen GND/5V und A0 verbunden ist.
Das Ding läuft noch immer ohne Probleme.

Die Pumpe muss ja 10min laufen. Wenn man den Wert erhöht, dann wird zwar der Zyklus länger aber bei weiten nicht 10min. Das Eingangssignal läuft mit Poti stabil, laut Monitor. Ich habe auch gerade 2 neue UNO's bekommen und habe direkt noch mal einen anderen gestestet, das Ergebnis ist leider das gleiche

combie:
Mein InvOutputPin invertiert.

LED aus, bedeutet also: Pumpe an.
Wenn das bei dir andersrum soll, dann OutputPin statt InvOutputPin verwenden.

Ansonsten hat das noch den 10Min an, 10Min aus Takt, bei Anforderung.

Jetzt bleibt die LED komplet an...

#include <TaskMacro.h>

#include <CombieTypeMangling.h>
using namespace Combie::Millis;

#include <CombiePin.h>
using Pumpe = Combie::Pin::OutputPin<6>; // invertierender Output

#include <CombieTools.h>
// 1.0/11.0 entspricht in etwa einem Array mit 11 Zellen fuer die Berechnung des Mittelwertes
Combie::Tools::GleitenderMittelwert<uint16_t> gmw {1.0/11.0};

constexpr uint16_t obereSchwelle  {520};
constexpr uint16_t untereSchwelle {480};
Combie::Tools::SchmittTrigger<uint16_t> st {obereSchwelle,untereSchwelle};


constexpr byte sensor {A0};
bool pumpAnforderung {false}; // Uebergabe Merker

void messen()
{
  taskBegin();
  gmw.setInitial(analogRead(sensor)); // vorbesetzen
  while(1)
  {
    taskPause(100_ms); // pause zwischen den Messungen
    pumpAnforderung = st = gmw = analogRead(sensor);
  }
  taskEnd();
}

void pumpen()
{
  taskBegin();
  Pumpe().init();
  while(1)
  {
    taskWaitFor(pumpAnforderung)
    Pumpe() = 1;
    taskPause(10_min);
    Pumpe() = 0;
    taskPause(10_min);
  }
  taskEnd();
}



void setup()
{
}

void loop()
{
  messen();
  pumpen();
}

my_xy_projekt:
Wirklich auf 10 und nicht auf 1?
Was? An? Aus?
Kannst Du sicherstellen, das Dein Eingangssignal sauber ist?
Ich habe hier einen UNO am laufen, der nur mit einem Kabel zwischen GND/5V und A0 verbunden ist.
Das Ding läuft noch immer ohne Probleme.

[edit]
Bedingungen zum schalten:

  1. Wert > 520 UND pause gelöscht
  2. Wert < 520 UND PIN gesetzt
  3. Zeit ist um UND pause gesetzt UND PIN gesetzt
  4. Zeit ist um UND pause gesetzt UND PIN gelöscht

Es müssen also um einen Schaltvorgang auszulösen mindestens zwei Bedingungen erfüllt sein.

Geht die Pumpe vorzeitig aus, ist der Grenzwert nicht erreicht
Das löschen von pause geht nur, wenn alle drei Bedingungen (Nr. 4.) erfüllt sind.

Der Monitor zeigt komischer weise nach ca. 2min an, dass die Pausenzeit um ist?

Hier ein Plott vom Signal

meikvr6:
Die Pumpe muss ja 10min laufen.

Ja, wenn der Grenzwert nicht unterschritten wird.

Das Eingangssignal läuft mit Poti stabil, laut Monitor.

Nach Deinem Monitor?
Dein Monitor gibt was anderes raus, als Deine Verarbeitung benutzt.

Der selbe Code - nur umgestellt; Allerdings nutze ich ich den selben Messwert sowohl zur Ausgabe auf dem SerMon als auch zur Verarbeitung.
Es wird nur dann eine Ausgabe gemacht, wenn auf dem PIN irgendwas passiert. Oder wenn die Pausenzeit abgelaufen ist.

Einspielen.
Laufen lassen.
Tritt der Fehler auf, will ich das gesamte Protokoll sehen.

const int inputPin = A0;
const int relai = LED_BUILTIN; // Nutzt die ON-Board LED - ggfls. ändern.
int smoothWert = 0;

enum {aus, ein};

int val;
bool pause = aus;
unsigned long lastmillis = 0;
const unsigned long pausezeit = 600000;

void setup ()
{
  Serial.begin (115200);
  Serial.println (F ("Start..."));
  pinMode (relai, OUTPUT);
  digitalWrite (relai, aus);
}

void loop()
{
  schaltung();
}

void schaltung()
{
  val = analogRead (inputPin);
  smoothWert = 0.6 * smoothWert + 0.4 * val;
  if (smoothWert > 520)
  {
    if (pause == aus)
    {
      sermon (1);
      digitalWrite (relai, ein);
      lastmillis = millis();
      pause = ein;
    }
  }
  else
  {
    if (digitalRead (relai) == ein)
    {
      sermon (2);
      digitalWrite (relai, aus);
      lastmillis = millis();
      pause = ein;
    }
  }
  if ((millis() - lastmillis > pausezeit) && (pause == ein))
  {
    sermon (3);
    if (digitalRead (relai) == ein)
    {
      sermon (4);
      digitalWrite (relai, aus);
      lastmillis = millis();
    }
    else
    {
      Serial.println (F ("Gebe pause frei"));
      sermon (5);
      pause = aus;
    }
  }
  delay (1000);
}

void sermon (const int nummer)
{
  Serial.print (F ("Schalte PIN an Nummer "));
  Serial.print (nummer);
  Serial.print (F ("\tAnalogwert ist: "));
  Serial.print (val);
  Serial.print (F ("\tSmoothwert ist: "));
  Serial.print (smoothWert);
  Serial.print (F ("\tPause ist: "));
  Serial.print (pause);
  Serial.print (F ("\tLastmillis ist: "));
  Serial.println (lastmillis);
}

Die Ausgabe sieht dann so aus:

15:46:55.662 -> Schalte PIN an Nummer 1	Analogwert ist: 1023	Smoothwert ist: 654	Pause ist: 0	Lastmillis ist: 0

[edit]
Der analogwert war jetzt seit Start (siehe vorhin) HIGH und ist danach nicht geändert worden.
Das Teil geht um
15:46 in die Pumproutine
15:56 gemerkt, das Pausenzeit abgelaufen
15:56 Pumpe aus
16:06 gemerkt, das Pausenzzeit abgelaufen
16:06 da die Pumpe aus ist: Freigabe
16:06 ist noch immer der Pegel HIGH und das Spiel fängt von vorn an

15:46:54.662 -> Start...
15:46:55.662 -> Schalte PIN an Nummer 1	Analogwert ist: 1023	Smoothwert ist: 654	Pause ist: 0	Lastmillis ist: 0
15:56:56.101 -> Schalte PIN an Nummer 3	Analogwert ist: 1023	Smoothwert ist: 1021	Pause ist: 1	Lastmillis ist: 1002
15:56:56.101 -> Schalte PIN an Nummer 4	Analogwert ist: 1023	Smoothwert ist: 1021	Pause ist: 1	Lastmillis ist: 1002
16:06:56.543 -> Schalte PIN an Nummer 3	Analogwert ist: 1023	Smoothwert ist: 1021	Pause ist: 1	Lastmillis ist: 601106
16:06:56.543 -> Gebe pause frei
16:06:56.543 -> Schalte PIN an Nummer 5	Analogwert ist: 1023	Smoothwert ist: 1021	Pause ist: 1	Lastmillis ist: 601106
16:06:57.576 -> Schalte PIN an Nummer 1	Analogwert ist: 1023	Smoothwert ist: 1021	Pause ist: 0	Lastmillis ist: 601106

@my_xy_projekt
Ich habe jetzt alles getestet .
Das Programm funktioniert.
Vielen Dank für eure Geduld.

Gruß
Meik

meikvr6:
@my_xy_projekt
Ich habe jetzt alles getestet .
Das Programm funktioniert.

Ich freu mich immer über Leute die sich nochmal rückmelden und schreiben, das ihnen geholfen wurde.
Bei Dir bin ich mir aber nicht sicher.

Das es funktioniert habe ich mehrfach dargelegt.
DU hast das negiert.
Kann man machen.
Ich habe hier Deine diesbezüglichen Aussagen versucht zu verifizieren und konnte das nicht.
Dein Kurzsatz - ohne jegliche Erklärung - ist schon sportlich.
Ein einfaches "Ich habe mich vertan" hätte vielleicht ausgereicht.

Im Übrigen läuft das Ganze hier auch ohne pausevariable.
Na dann...
Viel Erfolg!
Noch ne Bitte: In Deinem Ausgangspost - also Deinem Ersten - editiere Deine Betreffzeile und schreib ein [gelöst] rein. Dann kommt es evtl. späteren Nutzern zugute.

Ich freue mich das ich wieder etwas lernen konnte.
Und ja ich hatte mich vertan.
Im Moment überlege ich immer noch wie man sich am besten in die ganze Sache einarbeiten kann.

meikvr6:
Im Moment überlege ich immer noch wie man sich am besten in die ganze Sache einarbeiten kann.

Vollständig antworten. Lesen. probieren. Suchmaschine. Hier fragen. Vollständig antworten

Und danke schon mal im voraus für die nachfolgende Generation, die Schritt 4 macht :wink:

Das werde ich in Zukunft versuchen.
Hier noch die Bilder:

20210205_165749.jpg

20210205_165832.jpg

20210205_165749.jpg

20210205_165832.jpg

meikvr6:
Das werde ich in Zukunft versuchen.

Danke.
Ich hab noch einen Tipp, den ich gerne weiter gebe, weil ich selbst auch mal in Deiner Position war:
https://www.arduinoforum.de/code-referenz
Dort das pdf runterladen und als [.. hier selbst entscheiden ..]-lektüre einfach durchlesen. Dann weisst, was drin steht.

Hier noch die Bilder:

Ach schau! Hab ich nicht genau das in #12 schon gehabt?

PS: Du solltest Dich beim Betrieb in solch einer Umgebung ggfls. über Watchdog und eeprom schlau machen.
Das nur für die Zukunft. Die Anlage wird die nächsten Wochen vermutlich eher unter 20A ..... Naja Du weisst schon.

Ich habe mir überlegt den UNO noch um eine weitere Funktion zu erweitern.
Beim Laden der Batterien entsteht Wasserstoff und Sauerstoff.
In einer gewissen Konzentration kann das zur Explosion führen.
Aus diesem Grund muss der Raum belüftet werden.

Dafür habe ich einen Lüfter instaliert.
Dieser soll folgende Logig verfolgen.

Zustand_1: Wenn Ladestrom erreicht: Dann Lüfter in Dauerbetrieb.
Zustand_2: Wenn Ladestrom nicht erreicht: Dann soll der Lüfter alle 4,8h 10min laufen.
Ich habe den Code entsprechend erweitert.
Mit einer niedrigen Time Line funktioniert auch alles.
Sobald ich aber die tatsächlichen Werte hinterlege geht in Zustand_2 die Test LED nicht mehr aus.

const int inputPin = A0;
const int relai = 6;
const int relai_2 = 7; 
int smoothWert = 0;
int meineEinZeit=60000;
int meineAusZeit=6000;                          //1728000;
int relai_2Status = LOW;
unsigned long LED_timestore;  // Variable Speicher für Systemzeit.

enum {aus, ein};

  int val;
  bool pause=aus;
  unsigned long lastmillis = 0;
  const unsigned long pausezeit = 600000;

void setup ()
{
  Serial.begin (115200);
  Serial.println (F ("Start..."));
  pinMode (relai, OUTPUT);
  digitalWrite (relai, aus);
  pinMode (relai_2, OUTPUT);
}

void loop()
{
  Pumpe();
  Luefter();
}

void Pumpe()
{
  val=analogRead(inputPin);
  smoothWert = 0.7 * smoothWert + 0.3 * val;
  if (smoothWert > 520)
{
  if (pause == aus)
    {
      sermon(1);
      digitalWrite (relai, ein);
      lastmillis = millis();
      pause = ein;
    }
  }
  else
  {
    if (digitalRead (relai) == ein)
    {
      sermon(2);
      digitalWrite (relai, aus);
      lastmillis = millis();
      pause = ein;
    }
  }
  if ((millis() - lastmillis > pausezeit) && (pause == ein))
  {
    sermon(3);
    if (digitalRead (relai) == ein)
    {
      sermon(4);
      digitalWrite (relai, aus);
      lastmillis = millis();
    }
    else
    {
      Serial.println (F ("Gebe pause frei"));
      sermon(5);
      pause = aus;
    }
  }
  delay (1000);
}

void sermon(const int nummer)
{
  Serial.print (F ("Schalte PIN an Nummer "));
  Serial.print (nummer);
  Serial.print (F ("\tAnalogwert ist: "));
  Serial.print (val);
  Serial.print (F ("\tSmoothwert ist: "));
  Serial.print (smoothWert);
  Serial.print (F ("\tLastmillis ist: "));
  Serial.println (lastmillis);
}

void Luefter() 
{
 if (smoothWert > 520) {
  digitalWrite (relai_2, HIGH);
  
   } 
   else 
   {
    
if (relai_2Status == LOW) 
  {
if (millis() - LED_timestore> meineEinZeit ) {
      digitalWrite(relai_2, HIGH);
      LED_timestore = millis();
      relai_2Status = HIGH;
   }
      
   }   
   else 
   {
    
if (millis() - LED_timestore> meineAusZeit) {
      digitalWrite(relai_2, LOW);
      relai_2Status = LOW;
    }
 }
 }
}

meikvr6:
Ich habe mir überlegt den UNO noch um eine weitere Funktion zu erweitern.

Ja, die berühmte Salamitaktik...

Zustand_1: Wenn Ladestrom erreicht: Dann Lüfter in Dauerbetrieb.
Zustand_2: Wenn Ladestrom nicht erreicht: Dann soll der Lüfter alle 4,8h 10min laufen.
Ich habe den Code entsprechend erweitert.
Mit einer niedrigen Time Line funktioniert auch alles.
Sobald ich aber die tatsächlichen Werte hinterlege geht in Zustand_2 die Test LED nicht mehr aus.

Als erstes: Wenn Du Code einstellst drücke vorher STRG-T in der IDE. und lösche die unnützen Leerzeilen - das kann kein Mensch auf einen Blick erfassen.
Neue Funktionen immer soweit wie möglich nach oben - warum soll ich wegen der Handvoll zeilen bis nach unten Scrollen?

Die Aufgabenstellung ist ungenau.
Fangen die 4,8 Stunden an zu zählen wenn der Lüfter das letzte Mal ausgegangen ist?