Umsetzung Problem - Regelung Durchflussmesser + Pumpe

Hallo zusammen :-). Mein erster Beitrag und meine erste "verzweifelte" Tat irgendwie meine Blockade im Kopf zu lösen.

Hardware:
1x ESP8266
4x YF-S301 (Durchflussmesser)
4x Schlauchpumpe
4x Relais zum Schalten der Schlauchpumpe

Ablauf:
Am ESP soll per Webserver ein Link aufgerufen werden, der eine Variable auf 1 setzt (Als Startsignal zu sehen). Daraufhin sollen z.B. Relais 1 und Relais 2 geschaltet werden. Diese schalten dann Pumpe 1 und Pumpe 2 an. Die Pumpen sollen solange laufen, bis durch Durchflussmesser 1 z.B. 200ml gelaufen sind und durch Durchflussmesser 2 z.B. 500ml gelaufen sind. Also verschiedene Mengen pro Pumpe und im Idealfall gleichzeitig.

Nun habe ich schon verstanden, dass der Durchflussmesser pulst und man diese Pulse zählen muss und dann damit rechnen kann.

Mein Problem:
Ich habe immer im Kopf, dass ich hierfür etwas wie "Multitasking" brauche, um diese beide Bedingungen (Durchflussmesser von den Pumpen) recht gleichzeitig abzufragen. Ich habe viele Lösungen mit "interrupt" schon hier im Forum gefunden, wo mir aber nicht ganz schlüssig ist, wie das zeitgleich mit zwei Pumpen und zwei unterschiedlichen Durchflussmessern funktionieren soll bzw. ob das überhaupt möglich ist.

Am liebsten wäre mir, sobald das Signal kommt die Pumpe einzuschalten und ab dann die Pulse solange zu zählen, bis diese einen Vorgabe-Wert erreicht haben ( IF PulsVorgabe > PulsAktuell = Pumpe weiterhin an). Hier denke ich meistens an eine "While"-Schleife. Die kann jedoch nicht zwei Mal gleichzeitig stattfinden (lt. meinem aktuellen Stand).

Im wahrsten Sinne des Wortes stehe ich hier auf den Schlauch und habe noch nicht Mal einen Ansatz, wie der Code aussehen sollte.... Ich wäre sehr dankbar über einen schlauen Tipp! :slight_smile:

Gruß Johannes

Wenn gut gemacht = nicht blockierend, ist der ESP schnell genug dass das fast gleichzeitig statt findet.

Was hindert Dich daran?
Du brauchst ja nur nicht blockierend programmieren.

Das ist falsch

Was hindert Dich diesen Ansatz zu verwenden?

Grüße Uwe

Hallo Jotobic,

herzlich willkommen im Arduino-Forum

Interrupts sind da schon die richtige Idee.

Es kommt jetzt darauf an was ist die maximale Impulszahl pro Sekunde die von deinen Durchflussmessern kommen kann. Dabei würde ich ersten Ansatz den wirklichen Maximalwert den der Durchflussmesser leisten kann nehmen.

Wenn es damit funktioniert wird es mit kleineren Impuls-Frequenzen auch funktionieren.
Dann kommt es darauf an wie lange dauert ein Impuls bei dieser maximalen Impulsfrequenz?

In einer Interrupt-routine eine 4byte variable um 1 zu erhöhen dauert vielleicht geschätzt 50 Microsekunden.

Wenn nehmen wir an die Impulse sind bei maximaler Impulszahl pro Sekunde
80 Mikrosekunden lang.

Impuls 1 beginnt bei 140 Mikrosekunden => In Mikrosekunde 191 ist die ISR abgearbeitet
Impuls 2 beginnt bei 143 Mikrosekunden da der Impuls 80 µS lang ist geht er bis 223 µS
wird also sicher detektiert.

Hallo Stefan,

danke für die Antwort & für das herzliche Willkommen.

Die Maximale Impulszahl pro Minute müssten 210Hz sein. (Lt. Beschreibung: F(Hz) = 21 * Q, Q= L/Min, Max. 10 L/Min). Würde für mich heißen, dass in der Sekunde 3,5 Impulse kommen, bei Q-Max.

Ich muss auch ehrlich gestehen, dass das für mich ziemliches Neuland ist und ich wahrscheinlich deshalb auch auf dem Schlauch stehe.

Wenn meine Berechnung oben Richtig ist, würde jeder Impulse 285ms dauern, oder? (1000ms / 3,5 Pulse / Sek.).

Was du mir wahrscheinlich mit deinem unteren Beispiel sagen willst: Bei so kurzen "Unterbrechungen" wird das ganze quasi in Echtzeit laufen, korrekt?

Ich wäre dir noch sehr dankbar, wenn du meine Rechnung oben prüfen könntest und mir noch kurz erklären kannst (gerne auch per Link) was passiert, wenn der Durchfluss z.B. auf 0,03L / Min sinkt.

Im Großen Ganzen möchte ich nachher 40ml relativ genau dosieren (Cocktailmaschine) und die Schlauchpumpe hat einen Q-Max von 300ml / Min.

Danke für deine Bemühungen!

Gruß

poste das Datenblatt zu deinem Durchflussensor.
Aus der Angabe

Bin ich mir da noch nicht 100% sicher
10 L/Min = 0,167 L/Sekunde

Aber in was für einer Einheit wird jetzt Q in diese Berechnung eingesetzt?
Liter/Minute oder Liter pro Sekunde

Wenn die Angaben mathematisch korrekt (was sie wahrscheinlich nicht sind)
dann wären 21 Impulse * 10 Liter / Minute = 210 Impulse pro Minute
= 3,5 Impulse pro Sekunde.

Aber dem traue ich nicht ganz.

Impuls bedeutet Schaltkontakt ist eine gewisse Zeit geschlossen dann wieder auf.
Das wird sich in der Zeit eher nicht 50 zu 50 aufteilen.
Sondern der Impuls wird deutlich kürzer sein. Aber wie viel kürzer.

Nun ja da die maximale Frequenz 3,5 Hz ist wird es wohl funktionieren.
Aber mich interessiert das schon.

Hast du ein Oszilloskop zur Verfügung ? Damit könnte man das wunderbar messen.

Andere Möglichkeit Testprogramm schreiben dass den Impulseingang pollt und dann die Zeiten (function micros() ) wann der Impulseingang umschaltet in verschiedene Variablem schreibt

"quasi in Echtzeit" ist ganz sicher KEINE Echtzeit.

Echtzeit erfordert eine Angabe über die maximal erlaubte Reaktionszeit
10 nanosekunden?
1 Mikrosekunde?
100 Mikrosekunden?

Wenn man das ganze Programm nicht blockierend programmiert dann läuft es so schnelldurch dass es alle Sensor-Ereignisse mitbekommt.

Hey,

hier ein Mal das Datenblatt für den Sensor:

Dort habe ich nun auch einen Wert 1L = 1260Hz (siehe Bild).

Tatsächlich spielt bei dem Vorhanden die Zeit nicht die Große Rolle sondern die ml. und das alle Pumpen gleichzeitig agieren sollen.

Hallo,
Bei einer Schlauchpumpe schwankt der Durchfluss sehr stark. Das kann dazu führen daß der Sensor prellt.
Du solltest eventuell eine Hardware Entprellung , RC Glied vorsehen damit Impulse nicht doppelt gezählt werden können.

Bei Interrupt Auswertung der Impulse kann man ja keine Software Entprellung verwenden.

Ansonsten in der ISR die Impulse zählen, und im Loop den Vergleich durchführen und mittels Vergleich die Pumpe ausschalten ist ok.

Auf der anderen Seite sind Schlauchpumpe sehr genau. Da könnte man eventuell auch über Zeit dosieren. Eventuell ist das genauer als mit dem Durchflussmesser. Aber das kommt auf die Baugröße der Pumpe an.

Aha. Mit was für Motoren werden die Schlauchpumpen angetrieben?
Sind die Motoren fest mit der Pumpe verbunden?
Mit Schrittmotoren könnte man ebenfalls sehr genau dosieren.
Bei DC-Motoren könnte man auch die Umdrehungen mit einem Encoder erfassen

Du hast erwähnt es geht um eine Cocktailmaschine.
Noch eine Variante wäre die Gewichtszunahme zu messen. Es gibt Wiegesensoren im Preisbereich 20 Euro die auf ein Gramm genau messen.

Wie Stefan schreibt wäre die gravimetrische Dosierung die genaueste wenn es wirklich genau werden soll.
Mit Durchflussmessern kannst du einen kontinuierlichen Durchfluss gut messen, aber zum dosieren taugen die nix. Du hast im Anlauf und Auslauf des Rades ungenauigkeiten drin.
Mit Schrittmotoren könntest du auch gut dosieren.

Hallo jotonic

Willkommen im besten Arduinoforum der Welt.

Mal eine Schlauchbrücke rüberreich :slight_smile:

Das Projekt lässt sich prima über das EVA-Prinzip wie folgt abstrahieren:

Eingabe: INTERRUPT -> Zähler++;
Eingabe: Webserver -> Variable = 1;
Verarbeitung: Wenn Variable auf 1 gesetzt worden ist, dann Pumpe =an, Zähler=0 und Timer=Start.
Wenn Timer==ausgelöst, dann Zähler lesen, Volumen berechnen.
Ausgabe: Wenn Volumen>=gewünschtes Volumen, dann Relais=aus und Timer=Halt.

Ein Timer, mit einer start() und stop() Funktion, läßt sich prima aus dem IDE Beispiel BlinkWithOutDelay ableiten.

Das Projekt kann entweder im prozess- oder objektorientierten Paradigma programmiert werden.
Da hier vier identische Hardwarekomponenten verwendet werden, empfehle ich eine OOP-Lösung, die hier aber nicht erwünscht ist, weil OOP Arduino-Neulinge vergrault.

Ich habe keinen ESP8266 in der Schublade liegen und kann dir leider kein Beispiel geben.

Ich wünsche einen geschmeidigen Tag und viel Spass beim programmieren in C++.

p.s.
Ich denke, daß bei einem erwarten Volumen von ~400ml ist ein Fehler von +/- 10*(1/1260 Liter) nicht relevant ist. Es ist ein Cocktailmixer und keine medizinische Anwendung.

Hallo,
in der Regel ist der Motor fest verbaut. DC Motor mit Getriebe da die Pumpen langsam laufen. Da da seitens des Mediums kein Druck aufgebaut werden muss, ist sicher das Drehmoment hauptsächlich dadurch bestimmt das der Schlauch zusammen gdrückt werden muss. Damit ist das Drehmoment weitgehend konstant, und somit die Drehzahl ebenso.
ich würde das auf jeden Fall erst mal testen und über Zeit dosieren.

Cocktail Maschinen gibt es sicher reichlich , hier im Forum kommt das Thema ja alle paar Monate mal vor.

Heinz

Hallo,
ich habe mal in meiner Bastelkiste gewühlt was gefunden und ein wenig umgebaut.
Zu deinem Durchflussmesser habe ich keine Impulszahl Imp/L gefunden. Das musst Du also selbst ermitteln und umrechnen.
Du benötigst das ja für 4 Pumpen+Durchflussmesser. Ich hab das jetzt nur für einen gemacht. Am einfachsten für Dich wird es sein die entsprechende Teile zu kopieren und die Variablen umzubenennen. Ich würde da eine Klasse draus machen und ein Arry anlegen für alle Pumpen. Aber das wird für Dich dann sicher nicht mehr nachvollziehbar sein.

Du kannst alles mit einem Taster starten und es kann dann bei mehreren Pumpen auch gleichzeitig laufen. Allerdings weiß ich nicht genau wie viele ISR "gleichzeitig" genutzt werden können. Der Uno kann zwei. Ich denke ein ESP kann da sicher mehr. Eventuell weiß das jemand anderes hier.

Vermutlich willst Du ja noch irgendwo die Sollwerte für die einzelnen Mengen eingeben wollen. Bei einem ESP bietet sich eine Weboberfläche an. Aber das ist ja ein ganz anderes Thema.

Um das testen und messen zu können habe ich mit tone() eine Frequenz erzeugt. Das muss natürlich letztlich dann raus.

Also hier mein Beispiel Sketch.

/* Beispiel
    mit einem Taster wird eine Pumpe eingeschaltete. Ein
    Drchflussmesser misst die dosierte Menge und schaltete die Pumpe
    wieder aus.
    Zum Teste wird eine Frequenz mittels Tone ausgegeben
    bei Anschluss des Durchflussmesser Brücke entfernen
    und Tone zeile entfernen.
    Hardware ESP8266 Node Modul V1
*/


const byte isrpin = D1;     // Frequenzeingang Durchflussmesser
const byte btnstart = D3;   //Taster Start gegen GND

volatile unsigned int i_count;// counter für ISR
unsigned int count;           // counter zur Nutzung
unsigned int maxcount = 500;  // Anzahl Pulse Füllmenge erste Pumpe
const byte pumppin = D4;      // Ausgang Relais Pumpe Low aktiv  
                              // hier interne LED die ist LOW aktiv

bool btnstate;    // status Taster
bool pumpOn;      // starus Pumpe ein

uint32_t startZeit;   // millis() beim starten


// ============ ISR Function ============
ICACHE_RAM_ATTR void myISR() {
  i_count++;
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  pinMode(btnstart, INPUT_PULLUP);
  pinMode(isrpin, INPUT_PULLUP);
  pinMode(pumppin, OUTPUT);
  digitalWrite(pumppin, true);
  
  // zum Testen säter entfernen
  tone(D2, 100); // testfrequenz Brücke von D2 auf D1
}

void loop() {
  // put your main code here, to run repeatedly:

  btnstate = !digitalRead(btnstart);

  if (btnstate && !pumpOn) { // erste Pumpe einschalten
    pumpOn = true;  // Pumpe 1 ein
    i_count = 0;    // counter 1 reset
    attachInterrupt(digitalPinToInterrupt(isrpin), myISR, FALLING);
    startZeit = millis();
    Serial.println("Start Pumpe");
  }

  if (pumpOn) {  // abfrage erste Pumep ein
    count = i_count; // ISR counter umladen

    if (count >= maxcount) { // erste Pumpe ausschalten
      pumpOn = false;
      detachInterrupt(digitalPinToInterrupt(isrpin));
      uint32_t lzeit = millis() - startZeit;
      Serial.printf("Pumpe aus / Laufzeit %d ms \n", lzeit);
    }
  }
  digitalWrite(pumppin, !pumpOn); // invertiert ausgeben

}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.