Go Down

Topic: Zwei parallele Programme laufen lassen (Read 2068 times) previous topic - next topic

my_xy_projekt

Zu 1.
Die Idee war, die beiden Bauteile erstmal auf den Zustand high, also nicht aktiv zu zwingen.

Die Anlage steht nun und wird getestet. Da ich mit dem Code leider nicht weiterkomme, greife ich für Testzwecke auf meine erste Variante zurück.
Du versuchst mit einer Krücke (delay) Deinen Fehler zu verwischen.
Kann man machen.

Was war denn an den Coden #6 #12 #14 #17 und schliesslich #20 nicht verständlich?
Gerade #12 ist doch genau das, was Du jetzt versuchst.


Was meinst Du denn, wie lange ein Durchlauf von loop() dauert?
Mit jedem Durchlauf schreibst Du - egal was da vorher passiert:

void loop() {
digitalWrite(relais1Pin, HIGH);

Du hörst nicht mal einen Ansatz eines Klacken von Deinem Relais - das Ding ist ständig HIGH!

In #23 schreibst Du:
Quote
In meinem Nachbau hab ich allerdings das Problem, dass das Relais nach Einschalten des Arduino permanent schaltet (1s aus, 5s an) Was läuft falsch?
Mach ein Bild vom Aufbau. Das man alle Kabel und Verbindungen erkennt.
Wenn permanent geschalten wird, ist der ir-INPUT ständig auf HIGH.

Wenn Du 1Sek aus und 5s an hast, beschreibt es das, auf was ich Dich in #5 ganz fett hingewiesen habe!

noiasca

#31
Jul 01, 2020, 07:15 am Last Edit: Jul 01, 2020, 07:18 am by noiasca
hast du die Seriell Ausgaben ergänzt so wie in #26 empfohlen?
Welche neue Erkenntnis hast du daraus?

Hast du verstanden was dir Combie in #27 mitgeteilt hat?

Darauf aufbauend vieleicht noch ein Tipp: so lange du dein Programm nicht nachvollziehen kannst:
vermeide die langen If Bedingungen. Zerteile diese

aus

if ((i1 == LOW) && (r1 == HIGH) && (millis() - pausemillis1 > pausezeit1))

mach

Code: [Select]

if ((i1 == LOW)
{
  Serial.println("i1==LOW");
  if (r1 == HIGH)
  {
     Serial.println("r1==HIGH");
     if (millis() - pausemillis1 > pausezeit1))
     {
       Serial.println("Zeitablauf")
      ...



dann siehst du auch genau welche deine Bedinungen nicht das machst was du bisher geglaubt hast, was sie macht. In einer Kette von 3 UND ist es für dich offenbar schwierig rauszufinden, was an der  Logik nicht passt. Also zerlege es in kleine Teilschritte!

In aller Deutlichkeit: Nutze Serial Ausgaben um den Ablauf deines Programms zu verfolgen und Logikfehler zu erkennen!(!!!)
how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

kahmui

#32
Jul 01, 2020, 08:16 am Last Edit: Jul 01, 2020, 08:41 am by kahmui
@ My_xy

Ich versuche nicht meine Fehler zu vertuschen. Ich brücke lediglich die Zeit bis mein Programm so funktioniert wie es gewünscht ist.

Die Codes sind super. Sie funktionieren in der Simulation auch wunderbar. In der Praxis sieht es alledings anders aus!

Muss man den Status der Bauteile überhaupt festsetzen? Ich meine irgendwo gelesen zu haben, das undefinierte Zustände PingPong spielen "können".

digitalWrite(relais1Pin, HIGH); vom loop in setup packen? Wenn ich mich recht erinnere, wird setup ja nur einmalig beim Start des Arduino ausgeführt.


Der Aufbau funktioniert mit der delay Variante ohne Probleme. Daher wäre es mir ein Rätsel, wenn es letztendlich an der Schaltung liegt. Habe trotzdem mal ein paar Bilder gemacht. Der Teufel ist ja bekanntlich ein Eichhörnchen :))



@noiasca

Ja das habe ich gemacht. Und nein ich hatte gestern keine Zeit mehr alles umzusetzen was mir emfpohlen wurde. Zudem kommt ehrlich gesagt auch ein wenig Ratlosigkeit und Unwissenheit meinerseits dazu :) Ich versuche mein betses. Allerdings fehlt mir im Gegensatz zu euch einfach die Erfahrung, um alles umzusetzen was ihr so von euch gebt.

Die Zerteilung werde ich gleich definitiv mal vornehmen. Eine einfache Verkettung von if Bedingungen, richtig?


---> Mehr Bilder kommen gleich. Bin noch forentechnisch begrenzt was die Menge angeht :)

noiasca

Eben die UND Verkettungen auflösen und geschachtelte If hinschreiben (eins nach dem anderen) um die Serial.print Ausgaben zu ermöglichen.
how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

kahmui

#34
Jul 01, 2020, 09:59 am Last Edit: Jul 01, 2020, 10:28 am by kahmui
Code: [Select]

[...]
10:01:19.748 -> Zeitablauf Pause
10:01:19.748 -> Zeitablauf Pause
10:01:19.788 -> Zeitablauf Pause
10:01:19.788 -> Zeitablauf Pause
10:01:19.828 -> irPin[i]==LOW               (Sensor erkennt Bewegung)
10:01:19.828 -> Zeitablauf Laufzeit         (Laufzeit beginnt....
10:01:19.868 -> pumpPin[i]==HIGH          ..... Pumpe soll hier auf LOW schalten....
10:01:19.868 -> Sensor 1: Objekt erkannt!
10:01:21.828 -> Zeitablauf Pause            (Laufzeit vorbei, Timer der Pause beginnt...
10:01:21.868 -> Pumpe aus!                   ... und die Pumpe wird abgeschaltet)
10:01:21.868 -> pumpPin[i]==HIGH
10:01:21.868 -> Zeitablauf Pause            (Wartezustand)
10:01:21.908 -> Zeitablauf Pause
10:01:21.948 -> Zeitablauf Pause
10:01:21.948 -> Zeitablauf Pause
10:01:21.948 -> Zeitablauf Pause

[...]


So... die If´s mal ein wenig aufgebröselt.

Code: [Select]

// Anzahl Kreise
const int Kreise = 1;

// Pin-Belegung
const int irPin[] = {2, 3};
const int pumpPin[] = {5, 6};

// Zeitangaben
const int laufzeit[] = {2000, 2000};      // Laufzeit Pumpen
const int pausezeit[] = {3000, 3000} ;    // Zwangspause Pumpen

// Zeit- / Zählervariablen
unsigned long laufmillis[] = {0, 0};
unsigned long pausemillis[] = {0, 0};


// Programm
void setup()
{
  Serial.begin(9600);
  for (int i = 0; i < Kreise; i++)
  {
    pinMode(irPin[i], INPUT);
    pinMode(pumpPin[i], OUTPUT);
    digitalWrite(irPin[i], HIGH);
    digitalWrite(pumpPin[i], HIGH);
  }
}
void loop()
{
  for (int i = 0; i < Kreise; i++)
  {
    if (digitalRead(irPin[i]) == LOW)
    {
      Serial.println("irPin[i]==LOW");
      if (millis() - pausemillis[i] > pausezeit[i])
      {
        Serial.println("Zeitablauf Laufzeit");
        if (!digitalRead(pumpPin[i]) == HIGH)
        {
            Serial.println("pumpPin[i]==HIGH");
            Serial.print("Sensor ");
            Serial.print(i+1);
            Serial.println(": Objekt erkannt!");
            digitalWrite(pumpPin[i], HIGH);
            laufmillis[i] = millis();
        }
      }
    }
    if (millis() - laufmillis[i] > laufzeit[i])
    {
      Serial.println("Zeitablauf Pause");
      if (digitalRead(pumpPin[i]))
      {
        Serial.println("Pumpe aus!");
        digitalWrite(pumpPin[i], LOW);
        Serial.println("pumpPin[i]==HIGH");
        pausemillis[i] = millis();
      }
    }
  }
}


Funktioniert schonmal ganz gut!

Das einzige Problem was vorliegt ist, dass das Relais direkt nach Einschalten des Arduino die Laufzeit startet und anschließend das Relais auf LOW (betätigt) setzt. Wechsel ich die Zustände im Code, reagiert das Relais allerdings nicht mehr.

Soll:
1. Arduino Ein / Reset -> Wartezustand (Sensor und Relais auf HIGH)
2. Programm wartet auf Erfüllung der Bedingung. Das heißt die Pumpe ist aus und der Sensor erkennt eine Bewegung (Sensor == LOW, Pumpe == HIGH, Zwangspause vorbei))
2. Hand vor Sensor -> Relais schaltet ein (also auf LOW)
3. Relais bleibt gemäß der festgelegten Dauer von "Laufzeit" betätigt und schaltet danach ab
4. Timer der Zwangspause läuft ab -> Neubeginn des Zyklus möglich

Ist:
1. Arduino Ein / Reset -> Relais ist aus (HIGH), Laufzeit läuft ab (2s) und Relais schaltet direkt auf LOW (also Pumpe betätigt) -> Wartezustand
2. Warten auf Erfüllung der Bedingung (wie oben)
3. Hand vor Sensor -> Relais schaltet ab (also auf HIGH)
4. Relais bleibt gemäß der festgelegten Dauer von "Laufzeit" UNbetätigt und schaltet danach wieder ein
5. Timer der Zwangspause läuft ab -> Neubeginn des Zyklus möglich

Ist, wenn Zustände gewechselt werden:
1. Arduino Ein / Reset -> Stillstand (Relais auf HIGH, also aus)
Code: [Select]

10:24:39.321 -> Pumpe aus!
10:24:39.321 -> pumpPin[i]==HIGH
10:24:39.361 -> Zeitablauf Pause
10:24:39.361 -> Pumpe aus!
10:24:39.401 -> pumpPin[i]==HIGH
10:24:39.401 -> Zeitablauf Pause
10:24:39.401 -> Pumpe aus!
10:24:39.441 -> pumpPin[i]==HIGH
10:24:39.441 -> Zeitablauf Pause
10:24:39.481 -> Pumpe aus!
10:24:39.481 -> pumpPin[i]==HIGH
10:24:39.521 -> Zeitablauf Pause
10:24:39.521 -> Pumpe aus!
10:24:39.521 -> pumpPin[i]==HIGH
10:24:39.561 -> Zeitablauf Pause
10:24:39.561 -> Pumpe aus!

2. Wenn hand vor Sensor
Code: [Select]
10:25:45.719 -> pumpPin[i]==HIGH
10:25:45.759 -> irPin[i]==LOW
10:25:45.759 -> Zeitablauf Pause
10:25:45.799 -> Pumpe aus!
10:25:45.799 -> pumpPin[i]==HIGH
10:25:45.799 -> irPin[i]==LOW
10:25:45.839 -> Zeitablauf Pause
10:25:45.839 -> Pumpe aus!

3. keinerlei Reaktion



Wo übersehe ich etwas? Rein theoretisch müsste ich doch nur die beiden digitalWrite(pumpPin) Zustände im Code wechseln?  :o

Code: [Select]

// Anzahl Kreise
const int Kreise = 1;

// Pin-Belegung
const int irPin[] = {2, 3};
const int pumpPin[] = {5, 6};

// Zeitangaben
const int laufzeit[] = {2000, 2000};      // Laufzeit Pumpen
const int pausezeit[] = {3000, 3000} ;    // Zwangspause Pumpen

// Zeit- / Zählervariablen
unsigned long laufmillis[] = {0, 0};
unsigned long pausemillis[] = {0, 0};


// Programm
void setup()
{
  Serial.begin(9600);
  for (int i = 0; i < Kreise; i++)
  {
    pinMode(irPin[i], INPUT);
    pinMode(pumpPin[i], OUTPUT);
    digitalWrite(irPin[i], HIGH);
    digitalWrite(pumpPin[i], HIGH);
  }
}
void loop()
{
  for (int i = 0; i < Kreise; i++)
  {
    if (digitalRead(irPin[i]) == LOW)
    {
      Serial.println("irPin[i]==LOW");
      if (millis() - pausemillis[i] > pausezeit[i])
      {
        Serial.println("Zeitablauf Laufzeit");
        if (digitalRead(pumpPin[i]) == HIGH)
        {
            Serial.println("pumpPin[i]==HIGH");
            Serial.print("Sensor ");
            Serial.print(i+1);
            Serial.println(": Objekt erkannt!");
            digitalWrite(pumpPin[i], LOW);              Hier auf LOW schalten, damit das Relais eingeschaltet wird
            laufmillis[i] = millis();
        }
      }
    }
    if (millis() - laufmillis[i] > laufzeit[i])
    {
      Serial.println("Zeitablauf Pause");
      if (digitalRead(pumpPin[i]))
      {
        Serial.println("Pumpe aus!");
        digitalWrite(pumpPin[i], HIGH);          Hier auf HIGH wechseln, damit das Relais abgeschaltet wird
        Serial.println("pumpPin[i]==HIGH");
        pausemillis[i] = millis();
      }
    }
  }
}

my_xy_projekt

Wo übersehe ich etwas? Rein theoretisch müsste ich doch nur die beiden digitalWrite(pumpPin) Zustände im Code wechseln?  
Die Relais sind LOW-aktiv.
Das heisst, wenn der Output-PIN LOW ist, zieht das Relais an.

Wenn Du willst, das das Relais mit dem Start etwas macht, ohne das der IR-PIN einen Durchgang bemerkt, dann musst Du im Setup:
a) Den PumpenPIN setzen (LOW)
UND
b) Die Lauzeitvariable setzen (laufmillis=millis())

Die Frage ist, ist der IR-Sensor HIGH oder LOW aktiv?
Steht da irgendeine Bezeichnung drauf?

Im Normalfall sind die eigentlich HIGH-aktiv, Dein Code prüft auf LOW.
Las das:     digitalWrite(irPin, HIGH); mal komplett weg.

Und das:       Serial.println("Zeitablauf Pause");
wird ständig gemacht, weil Du nicht prüfst, ob der PIN auch den dementsprechenden Zustand hat.
 

kahmui

#36
Jul 01, 2020, 10:54 am Last Edit: Jul 01, 2020, 10:55 am by kahmui
Das ist das genutze Relais: 2-Relais Modul 5V
Das ist der Sensor: E18-D80NK

Wenn ich richtig gelesen habe, ist der Sensor LOW-aktiv (Whendistance of Sensor <= the specified distance detection, LED Status is ON and OUTPUT = 0)

Wenn ich dich richtig verstanden habe, müsste es folgendermaßen aussehen:

Code: [Select]
// Anzahl Kreise
const int Kreise = 1;

// Pin-Belegung
const int irPin[] = {2, 3};
const int pumpPin[] = {5, 6};

// Zeitangaben
const int laufzeit[] = {2000, 2000};      // Laufzeit Pumpen
const int pausezeit[] = {3000, 3000} ;    // Zwangspause Pumpen

// Zeit- / Zählervariablen
unsigned long pausemillis[] = {0, 0};
unsigned long laufmillis[] = {0, 0};

// Programm
void setup()
{
  Serial.begin(9600);
  for (int i = 0; i < Kreise; i++)
  {
    pinMode(irPin[i], INPUT);
    pinMode(pumpPin[i], OUTPUT);
    const int pumpPin[] = {5, 6};
    digitalWrite(pumpPin[i], LOW);
    unsigned long laufmillis[] = {millis(), millis()};
  }
}
void loop()
{
  for (int i = 0; i < Kreise; i++)
  {
    if (digitalRead(irPin[i]) == LOW)
    {
      Serial.println("irPin[i]==LOW");
      if (millis() - pausemillis[i] > pausezeit[i])
      {
        Serial.println("Zeitablauf Laufzeit");
        if (!digitalRead(pumpPin[i]) == HIGH)
        {
            Serial.println("pumpPin[i]==HIGH");
            Serial.print("Sensor ");
            Serial.print(i+1);
            Serial.println(": Objekt erkannt!");
            digitalWrite(pumpPin[i], LOW);
            laufmillis[i] = millis();
        }
      }
    }
    if (millis() - laufmillis[i] > laufzeit[i])
    {
      if (digitalRead(pumpPin[i]) == HIGH) {
        Serial.println("Zeitablauf Pause");
        if (digitalRead(pumpPin[i]))
        {
          Serial.println("Pumpe aus!");
          digitalWrite(pumpPin[i], HIGH);
          Serial.println("pumpPin[i]==HIGH");
          pausemillis[i] = millis();
        }
      }

    }
  }
}



Funktioniert weiterhin wie vorher.

my_xy_projekt

#37
Jul 01, 2020, 11:58 am Last Edit: Jul 01, 2020, 11:59 am by my_xy_projekt
Das ist das genutze Relais: 2-Relais Modul 5V
Das ist der Sensor: E18-D80NK

Wenn ich richtig gelesen habe, ist der Sensor LOW-aktiv (Whendistance of Sensor <= the specified distance detection, LED Status is ON and OUTPUT = 0)

Funktioniert weiterhin wie vorher.
Ich hab das mal nachgebaut. Wenn der Sensor LOW-aktiv sein soll, braucht es einen Pullup am ir-PIN.

Zudem habe ich im Setup festgelegt, das die Laufzeit dort gesetzt wird.
Ohne setzen:
Code: [Select]
11:51:48.540 -> Starte Setup
11:51:48.540 -> PumpenPIN 1 hat jetzt Status: 0
11:51:51.573 -> Pumpe aus!
11:51:51.573 -> PumpenPIN 1 hat jetzt Status: 1

mit setzen:
Code: [Select]
11:52:35.089 -> Starte Setup
11:52:35.089 -> PumpenPIN 1 hat jetzt Status: 0
11:52:38.087 -> Pumpe aus!
11:52:38.087 -> PumpenPIN 1 hat jetzt Status: 1

Wenn Du die millis also nicht in die Variable übernimmst, läuft die Pumpe 30ms länger im ersten Durchlauf.

Code: [Select]

/*
    Code für Topic https://forum.arduino.cc/index.php?topic=692478
    1.7.2020 - Post #37
*/


// HIER DIE ANZAHL DER KREISE ANGEBEN
const int Kreise = 1;
// Für jeden Kreis ab hier einen Wert angeben!
// Hier die Angabe der PIN
const int irPin[] = {2, 3};
const int pumpPin[] = {5, 6};
// Hier die Angabe für die Zeiten
const unsigned int laufzeit[] = {3000, 3000};
const unsigned int pausezeit[] = {5000, 5000} ;
// Zeitvariablen init immer 0
unsigned long laufmillis[] = {0, 0};
unsigned long pausemillis[] = {0, 0};
// Ende Eintrag Werte
void setup()
  {
  Serial.begin(115200);
  Serial.println("Starte Setup");
  for (int i = 0; i < Kreise; i++)
    {
    pinMode(irPin[i], INPUT_PULLUP);
    pinMode(pumpPin[i], OUTPUT);
    digitalWrite(pumpPin[i], LOW);
    serielleAusgabe(i);
    laufmillis[i] = millis();
    }
  }
void loop()
  {
  for (int i = 0; i < Kreise; i++)
    {
    if ((!digitalRead(irPin[i])) && (millis() - pausemillis[i] > pausezeit[i]) && (digitalRead(pumpPin[i])))
      {
      Serial.print("Sensor ");
      Serial.print(i + 1);
      Serial.println(": Objekt erkannt!");
      digitalWrite(pumpPin[i], LOW);
      serielleAusgabe(i);
      laufmillis[i] = millis();
      }
    if ((!digitalRead(pumpPin[i])) && (millis() - laufmillis[i] > laufzeit[i]))
      {
      Serial.println("Pumpe aus!");
      digitalWrite(pumpPin[i], HIGH);
      serielleAusgabe(i);
      pausemillis[i] = millis();
      }
    }
  }

void serielleAusgabe(int y)
  {
  Serial.print("PumpenPIN ");
  Serial.print(y+1);
  Serial.print(" hat jetzt Status: ");
  Serial.println(digitalRead(pumpPin[y]));
  }


kahmui

#38
Jul 01, 2020, 12:30 pm Last Edit: Jul 01, 2020, 12:32 pm by kahmui
Okay... das leuchtet ein. Von alleine wäre ich da aber niemals hingekommen. Danke für deinen Hinweis!

Ich habe das ganze jetzt mal getestet und es funktioniert soweit gut. Das einzige Problem das bestehen bleibt ist, dass die beiden Relais beim Start / Reset noch kurzzeitig betätigt werden und somit die Pumpen schon arbeiten. Lässt sich das noch irgendwie vermeiden?

Ansonsten funktioniert es genau so wie es sein soll. Tausend dank!

my_xy_projekt

Okay... das leuchtet ein. Von alleine wäre ich da aber niemals hingekommen. Danke für deinen Hinweis!
Dafür ist so'n Forum da.... ;)

Quote
Das einzige Problem das bestehen bleibt ist, dass die beiden Relais beim Start / Reset noch kurzzeitig betätigt werden und somit die Pumpen schon arbeiten. Lässt sich das noch irgendwie vermeiden?
Aehm.. Ich versteh das jetzt nicht. Sinn der Übung war doch mit laufender Pumpe zu starten.
Nach dem Reset starten die Pumpen einmal, weil im Setup so festgelegt.
Wenn Du das unterbinden möchtest, musst Du Zeile 28:
    digitalWrite(pumpPin, LOW);
ändern und ein HIGH rein schreiben.
Dann soll auch Zeile 30 auskommentiert werden.

Und nochwas: tausche mal bitte die Zeilen 29 gegen 30 , 43 gegen 44 und 50 gegen 51.
(serielleAusgabe(i); gegen den millis()-Merker)
Damit werden die Zeiten genauer, da sonst erst nach der Ausgabe der Startpunkt gesetzt wird.

kahmui

#40
Jul 01, 2020, 02:39 pm Last Edit: Jul 01, 2020, 02:51 pm by kahmui
Dafür ist so'n Forum da.... ;)

Aehm.. Ich versteh das jetzt nicht. Sinn der Übung war doch mit laufender Pumpe zu starten.
Nach dem Reset starten die Pumpen einmal, weil im Setup so festgelegt.
Wenn Du das unterbinden möchtest, musst Du Zeile 28:
    digitalWrite(pumpPin, LOW);
ändern und ein HIGH rein schreiben.
Dann soll auch Zeile 30 auskommentiert werden.

Und nochwas: tausche mal bitte die Zeilen 29 gegen 30 , 43 gegen 44 und 50 gegen 51.
(serielleAusgabe(i); gegen den millis()-Merker)
Damit werden die Zeiten genauer, da sonst erst nach der Ausgabe der Startpunkt gesetzt wird.

Zuallererst: Entschuldige wenn ich das falsch rübergebracht habe. Die Pumpe soll nicht direkt betätigt werden wenn das System mit Saft versorgt wird.

Zweitens: Hab ich gemacht. Funktioniert wunderbar! Vielen Dank!!

Drittens: Eine Frage zum Abschluss. Wo und womit platziere ich am besten die Funktion zur manuellen Betätigung der Pumpe mit einem normalen Schließ-Taster für einen Dauerlauf? (hier geht es darum, die Pumpe manuell zu "füttern" bis die Flüssigkeit dort ist wo sie hingehört (oder zum entlüften). Also solange der Taster betätigt wird, soll das Relais schalten. Mit if, while, do while, was ganz anderes?

Ganz grob:
Code: [Select]

if ((digitalRead(buttonPin[i]) == HIGH) && (digitalRead(irPin[i]) == HIGH))
  {
    digitalWrite(pumpPin[i], LOW);
   }

Habe ein wenig Sorge, dass ich den bestehen Code streife und das Relais nen Zappelkasper macht.


Ansonsten nochmal - Tausend Dank!

combie

#41
Jul 01, 2020, 03:02 pm Last Edit: Jul 01, 2020, 03:27 pm by combie
Hattest du diese Zusatzanforderung schon mal erwähnt?

Ist mir zumindest nicht aufgefallen...

Übrigens:
Salamitaktik ist mit der einfachste Weg, die Helfer zu frustrieren.
Denn bei jeder Scheibe ist klar/möglich/wahrscheinlich, dass alles/einiges vorherige für die Tonne produziert wurde.

Ist nicht immer alles für die Tonne. Aber viel zu oft, eben doch.
Gefährlich, was Theorien aus Menschen machen können.
Schlimmer, was Menschen aus Theorien machen.

noiasca

Quote
Drittens: Eine Frage zum Abschluss. Wo und womit platziere ich am besten die Funktion zur manuellen Betätigung der Pumpe mit einem normalen Schließ-Taster für einen Dauerlauf? (hier geht es darum, die Pumpe manuell zu "füttern" bis die Flüssigkeit dort ist wo sie hingehört (oder zum entlüften). Also solange der Taster betätigt wird, soll das Relais schalten. Mit if, while, do while, was ganz anderes?

na jetzt überleg mal ganz scharf.
Hast du nicht schon ein if, dass deine Pumpe einschaltet?
Was spricht dagegen in diese IF Kette auch noch ein ODER digitalRead(meinManuellerEingangsPin)== zu ergänzen?

läuft halt dann vermutlich die Nachlaufzeit nach.
Stört das? Dann mit weiteren Ifs auch den Nachlauf beenden.

Spätestens jetzt wären wir bei einem Zustandsautomaten / FSM und einem weiteren Status.
Das kommt davon wenn man Anforderungen so Scheibchenweise rauslässt, dann muss man in einer späteren Phase doch wieder mehr Umbauen.
how to react on postings:
- post helped: provide your final sketch, say thank you & give karma.
- post not understood: Ask as long as you understand the post
- post is off topic (or you think it is): Stay to your topic. Ask again.
- else: Ask again.

kahmui

#43
Jul 01, 2020, 03:26 pm Last Edit: Jul 01, 2020, 03:59 pm by kahmui
na jetzt überleg mal ganz scharf.
Hast du nicht schon ein if, dass deine Pumpe einschaltet?
Was spricht dagegen in diese IF Kette auch noch ein ODER digitalRead(meinManuellerEingangsPin)== zu ergänzen?

läuft halt dann vermutlich die Nachlaufzeit nach.
Stört das? Dann mit weiteren Ifs auch den Nachlauf beenden.

Spätestens jetzt wären wir bei einem Zustandsautomaten / FSM und einem weiteren Status.
Das kommt davon wenn man Anforderungen so Scheibchenweise rauslässt, dann muss man in einer späteren Phase doch wieder mehr Umbauen.
Hattest du diese Zusatzanforderung schon mal erwähnt?

Ist mir zumindest nicht aufgefallen...

Übrigens:
Salamitaktik ist mit der einfachste Weg, die Helfer zu frustrieren.
Denn bei jeder Scheibe ist klar/möglich/wahrscheinlich, dass alles/einiges vorherige für die Tonne produziert wurde.

Ist nicht immer alles für die Tonne. Aber viel zu oft, eben doch.
Wie ich das umsetzen kann ist mir bewusst. Nur stelle ich mir immer die Frage, ob es elegantere / zweckmäßigere Lösungen gibt :)
Die Anforderung stand bisher nicht zu Debatte. Bei den Versuchen hat sich bloß gezeigt, dass die Pumpe bei der ersten Inbetriebnahme nur schlecht das Medium anzieht, wenn nur kurze Stöße getätigt werden. Ich will hier niemanden frustrieren oder nerven. Sollte das so sein, verzeiht mir bitte.

Ich hab es wie folgt gelöst und es erfüllt seinen Zweck.

Code: [Select]

   const int buttonPin[] = {8, 9};

  -> setup

  pinMode(buttonPin[i], INPUT);

  -> loop

    if ((digitalRead(buttonPin[i]) == LOW) && (digitalRead(irPin[i]) == HIGH) && (digitalRead(relPin[i]) == HIGH))
    {
      while (digitalRead(buttonPin[i]) == LOW)
      {
        digitalWrite(irPin[i], HIGH);
        digitalWrite(relPin[i], LOW);
        delay(250);
      }
    }
    else
    [...]


Ich habe eine weitere if- und whileAnweisung geschrieben. Solange ich den Taster gedrückt halte, läuft die Pumpe. Durch delay erzeuge ich nach dem Lösen einen bewussten minimalen Nachlauf. Zusätzlich blockiert die Betätigung des Tasters die Infrarotsensoren und verhindern somit eine ungewollte Auslösung.


Ich bedanke mich bei allen Helfern. Dickes Karma+ und vielen Dank an euch alle! :)


kahmui

#44
Jul 01, 2020, 03:51 pm Last Edit: Jul 01, 2020, 04:01 pm by kahmui
Abschließend nochmal der gesamte Code, falls mal jemand etwas ähnliches brauch oder die Geeks ihn tunen wollen :)


Code: [Select]
// Anzahl Kreise
const int Kreise = 2;

// Angabe PIN-Belegung
const int irPin[] = {2, 3};
const int relPin[] = {5, 6};
const int buttonPin[] = {8, 9};

// Zeitangabe
const unsigned int laufzeit[] = {1000, 2000};
const unsigned int pausezeit[] = {2000, 3000} ;

// Zeitvariablen init immer 0
unsigned long laufmillis[] = {0, 0};
unsigned long pausemillis[] = {0, 0};


void setup()
{
  Serial.begin(9600);
  Serial.println("Starte Setup");
  for (int i = 0; i < Kreise; i++)
  {
    pinMode(irPin[i], INPUT_PULLUP);
    pinMode(relPin[i], OUTPUT);
    pinMode(buttonPin[i], INPUT);
    digitalWrite(relPin[i], HIGH);
    laufmillis[i] = millis();
    serielleAusgabe(i);
  }
}

void loop()
{
  for (int i = 0; i < Kreise; i++)
  {
    if ((digitalRead(buttonPin[i]) == LOW) && (digitalRead(irPin[i]) == HIGH) && (digitalRead(relPin[i]) == HIGH))
    {
      while (digitalRead(buttonPin[i]) == LOW)
      {
        digitalWrite(irPin[i], HIGH);
        digitalWrite(relPin[i], LOW);
        delay(250);
      }
    }
    else
    {
      if ((!digitalRead(irPin[i])) && (millis() - pausemillis[i] > pausezeit[i]) && (digitalRead(relPin[i])))
      {
        Serial.println(digitalRead(buttonPin[i]));
        Serial.print("Sensor ");
        Serial.print(i + 1);
        Serial.println(": Objekt erkannt!");
        digitalWrite(relPin[i], LOW);
        laufmillis[i] = millis();
        serielleAusgabe(i);
      }
      if ((!digitalRead(relPin[i])) && (millis() - laufmillis[i] > laufzeit[i]))
      {
        Serial.println("Pumpe aus!");
        digitalWrite(relPin[i], HIGH);
        pausemillis[i] = millis();
        serielleAusgabe(i);
      }
    }
  }
}

void serielleAusgabe(int y)
{
  Serial.print("PumpenPIN ");
  Serial.print(y + 1);
  Serial.print(" hat jetzt Status: ");
  Serial.println(digitalRead(relPin[y]));
}

Go Up