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!
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.
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.
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.
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.
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.
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
}