Forum: Mikrocontroller und Digitale Elektronik Impulse zählen / sliding window


von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Hallo zusammen,

ich glaub ich steh grad wieder mal auf dem Schlauch....

ich möchte einen Durchfluss-Messer (der im Kreis der Fussbodenheizung 
hängt) mit einem AVR "beobachten" und den momentanen Durchfluss 
ermitteln.

Das Ding hat einen Impuls-Ausgang, und liefert 50 Impulse pro Liter. 
Laut Datenblatt wird die Messung jede Sekunde ausgeführt, der Impuls ist 
recht konstant und zwischen 2 und 5 msec (ich weiss das widerspricht dem 
"konstant" aber so stehts nun mal geschrieben) und die Pausenzeit wird 
dem Durchfluss angepasst (ist aber dann innerhalb dieser Sekunde 
konstant, zumindest verstehe ich das so). Es gibt allerdings keine 
"Sekundenmarker", zumindest konnte ich keine feststellen.

Ich habe maximal um die 1000 Liter pro Stunde, das entspricht etwa 14 
Impulsen pro Sekunde. Nun ist 14 etwas wenig, um einigermaßen genau zu 
messen. ich müsste also die Messzeit erhöhen, gefühlsmäßig hätte ich an 
eine Minute gedacht, das wären dann ~8000 Impulse, genau genug für meine 
Anforderung.

Da mich allerdings auch das dynamische Verhalten (Start/Stopp der Pumpe, 
bzw. Drehzahländerungen) interessiert, ist mir die Minute wieder zu 
grob.

Deshalb dachte ich an ein "gleitendes Minutenfenster", damit hätte ich 
die Minute für die Genauigkeit, aber zumindest etwas dynamischere 
Reaktion auf Änderungen.

Allein - wie mach ich das? ich kann mir ja nicht zu allen 8000 Impulsen 
den Zeitstempel merken, dafür reicht das RAM bei weitem nicht....

von xfr (Gast)


Lesenswert?

Du kannst Dir in einer Variable die Summe aus x Messungen speichern. 
Jede Sekunde addierst Du den aktuellen Messwert und ziehst (summe/x) ab. 
Der aktuelle, gemittelte Wert, den Du anzeigst ist ebenfalls (summe/x).

Du kannst noch die Genauigkeit erhöhen, wenn Du statt 14 
Impulsen/Sekunde z.B. den Wert 1400 speicherst. Dann ist der 
Rundungsfehler bei der Division kleiner (bei Integern, siehe 
Festkommaarithmetik). Für die Ausgabe rechnest Du gleich in Liter/Stunde 
o.ä. um und machst alle Divisionen am Ende, dann ist das auch recht 
genau.

von Stefan (Gast)


Lesenswert?

Finde erstmal heraus, wie der Sensor GENAU funktioniert. Denn davon 
hängt alles ab. Wenn der Sensor Änderungen schnell erkennt und meldet, 
kannst Du prinzipiell drauf reaieren. Wenn der Sensor Messergebnisse nur 
in größeren Zeitintervallen liefert, kannst Du Dein Vorhaben vergessen.

von Stefan (Gast)


Lesenswert?

Beschäftige Dich mal mit der Thematik der PID Regler, da sind passende 
Lösungen bei.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

@xfr: integer-arithmetik usw. ist nicht mein problem, damit komm ich 
klar.

Deine Lösung klingt Verdächtug gut und einfach, aber ich versteh sie 
nicht :-(

@Stefan: Der Sensor liefert jede Sekunde ein Messergebnis, welches aber 
(vom Sensor selbst) über 8 Sekunden gemittelt wurde.

Ich bin weiss Gott kein Regeltechniker, was aus der PID-Theorie könnte 
auf meine Anforderung passen?

von Tom P. (booner)


Lesenswert?

Hei,

@Stefan: der Tipp ist ungefähr wie: Studier erstmal 
Informationstechnik... Da ist dann schon was passendes dabei! ;-) Wohl 
ein wenig zu umfangreich um einen simplen Impulsgeber auszuwerten.

@Michael: Ist das vielleicht (wie üblich) eine simple S0-Schnittstelle?
Die spuckt einfach nur Impulse aus. Da kannst Du einfach einen 
Mittelwert für Deine Genauigkeit bilden und Du kannst zusätzlich die 
Impulslänge messen und daraus schließen ob Pumpe An oder Aus ist...
Das geht dann relativ schnell.


Grüße,

Tom

von Peter D. (peda)


Lesenswert?

Nimm einfach ein Array aus 60 Byte und speichere darin die Impulse/s.
Der neue Wert überschreibt immer den ältesten.
Die Summe über das Array sind dann die Impules/min.


Peter

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

@booner: ja, ähnlich wie S0, aber doch anders. Bei S0 ist die "Frequenz" 
ziemlich proportional zur Messgröße, hier leider nicht wirklich.

peter: Dein Tipp hat glaub ich den knoten in meinem Hirn gelöst:

Ringbuffer mit 60 Elementen.

Den "Index" per Timer alle Sekunde hochzählen (modulo 60) und den 
aktuellen Wert auf null setzen.

Im Pin Change Interrupt des Sensors den Ringpuffer am aktuellen Index 
inkrementieren.

zum Auswerten einfach den Mittelwert über alle 60 Werte (der aktuelle 
index ist da gar nicht mal wichtig)

Warum ist es im Endeffekt immer so einfach?

Vielen Dank!

von Wolfgang (Gast)


Lesenswert?

Michael Reinelt schrieb:
> @Stefan: Der Sensor liefert jede Sekunde ein Messergebnis, welches aber
> (vom Sensor selbst) über 8 Sekunden gemittelt wurde.

Dann sollte doch der Impulsabstand ein vernünftiges Maß sein, was dir 
auch Daten mit dieser Zeitauflösung liefert.
Ein Reziprokzähler macht dir daraus eine Frequenz.
http://www.mikrocontroller.net/articles/Frequenzz%C3%A4hlermodul
Für die Gesamtwärmemenge kannst du zusätzlich die Impulse aufintegrieren

von xfr (Gast)


Lesenswert?

Wenn Du jetzt nochmal über meinen Tipp nachdenkst, siehst Du vielleicht, 
dass das für x = 60 ziemlich ähnlich funktioniert. Nur dass Du pro 
Sekunde nicht den ältesten gespeicherten Wert, sondern den aktuellen 
Durchschnitt abziehst.

Der Vorteil ist, es braucht weniger Speicher, das Auswerten geht 
schneller (besonders wenn man für x eine Zweiterpotenz wählt, dann kann 
man Shiften statt Dividieren). Und das beste: Die Genauigkeit der 
Ausgabe hängt nur von der Arithmetik ab. Mit dem Faktor x kann man 
unabhängig von der Genauigkeit vorgeben, wie schnell die Anzeige 
reagiert. Der kann also ruhig deutlich niedriger als 60 sein.

Probiers einfach mal auf dem Papier oder in Excel aus.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

@xfr: ok, habe nachgedacht. But I failed :-(

ich hab einen Pin Change Interrupt: hier inkrementiere ich einen (den) 
Zähler

ich hab einen Timer Interrupt, nehmen wir mal an jede Sekunde: Im Zähler 
steht wieviele Impulse ich in der letzten Sekunde hatte.

Diesen Wert addiere ich zu einem globalen Zähler, und setze den ersten 
Zähler wieder auf null.

Nun bilde ich den Mittelwert vom globalen Zähler.... und hier steig ich 
aus: da ist nur einer. Der Mittelwert von einem Wert ist... naja der 
Wert selbst. Den kann ich natürlich abziehen. Nur bleibt dann nicht 
wirklich viel übrig...

wäre nett wenn du mir nochmal auf die Sprünge helfen könntest...

von rene (Gast)


Lesenswert?


von Tom P. (booner)


Lesenswert?

Hei xfr,

Deinen Tipp werde ich mir auch merken, wenn ich darf! ;-)
Muss den gleich mal ausprobieren.

Grüße,

Tom

von xfr (Gast)


Lesenswert?

Okay, dann ein kleines Beispiel:
x = 2 (legen wir fest)
summe = 0 (zu Beginn)
m ist die Anzahl der Impulse in der letzten Sekunde

Pro Sekunde (also im Timer Interrupt rechnen wir):
summe = summe + m - (summe / x)

Die aktuelle Anzeige beträgt:
a = summe / x

Hier die ersten Schritte, bei konstantem m:
m = 8   summe = 0  + 8 - (0 / 2)  = 8    a = 8 / 2  = 4
m = 8   summe = 8  + 8 - (8 / 2)  = 12   a = 12 / 2 = 6
m = 8   summe = 12 + 8 - (12 / 2) = 14   a = 14 / 2 = 7
m = 8   summe = 14 + 8 - (14 / 2) = 15   a = 15 / 2 = 7,5

Du siehst, bei konstantem Durchfluss näherst sich die Anzeige dem 
konstanten Wert an. Wenn die Werte jetzt etwas schwanken, sieht man das 
in der Anzeige:

m = 6   summe = 15   + 6 - (15 / 2)   = 13,5   a = 13,5  / 2  = 6,75
m = 8   summe = 13,5 + 8 - (13,5 / 2) = 14,75  a = 14,75 / 2  = 7,375

Mit x = 2 reagiert die Anzeige also sehr schnell auf Änderungen. Mit 
einem höherem x ändern sich die Werte langsamer. Die Genauigkeit hängt 
dagegen nur davon ab, wie viele Nachkommastellen Du speicherst. Wie 
gesagt, am besten einfach mal in Excel damit rumspielen. :-)

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

xfr, du bist genial, und das ist genial!

Thank you very many!

von xfr (Gast)


Lesenswert?

Danke, Danke. Ist aber nichts anderes als im Link von rene unter 
"exponential average" beschrieben ist, also nicht meine Erfindung. ;-)

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

@xfr: jetzt habe ich nochmal nachgedacht, und bin wieder am 
Zweifeln...

Der Durchflussmesser liefert einen Impuls pro 1/50 liter, bzw. 50 
Impulse pro Liter. Wenn ich den Durchfluss bzw. die Wassermenge pro 
Zeiteinheit wissen will, muss ich die Impulse zählen. Also wirklich 
zählen, und nicht glätten / Mittelwert bilden.

Wenn ich in einer Minute z.B. 800 Impulse gezählt habe, heisst das 
800/50 = 16 Liter pro Minute. Und den Wert brauch ich, möglichst genau.

Meine Anforderung war dann noch, nicht starr jeweile eine Minute lang zu 
zählen, sondern die "Zählminute" gleitend zu schieben. Genau das würde 
ich mit der von peter beschriebenen Lösung (Array mit 60 
Sekunden-Zählwerten) erreichen.

Ich fürchte mit deiner Methode krieg ich zwar einen sehr guten 
Durchschnittswert, aber keinen genauen Absolutwert. Oder siehst du das 
anders?

Ich denke ich werd erstmal beide Methoden implementieren und 
vergleichen. Zum Glück habe ich ja auch noch das sauteure originale 
Rechenwerk vom Wärmemengenzähler, nachdem das ein geeichtes Werks ist, 
sollte das recht gut als Referenz taugen.

von xfr (Gast)


Lesenswert?

Es kommt halt drauf an, was Du haben möchtest. Bei dem Array mit den 60 
Messwerten bekommst Du auch nur einen Durchschnittswert angezeigt. Der 
ist nicht richtiger oder falscher als der Wert mit "meiner" Methode. Es 
ist immer ein Durchschnittswert, in den eine bestimmte Anzahl 
vergangener Messungen mit einer bestimmten Gewichtung eingeht.

Es gibt ja im Prinzip zwei Extreme: Du bildest gar keinen 
Durchschnittswert, sondern zeigst jede Sekunde an, was in der Sekunde 
durchgeflossen ist. Das ist aber recht ungenau, weil Du nur kleine 
Ganzzahlen hast und Du die Zwischenwerte nicht siehst. Wenn der 
Durchfluss also genau 7,5 Impulse pro Sekunde betragen würde, sieht Du 
immer nur abwechselnd 7 und 8.

Das andere Extrem wäre, den Mittelwert seit Inbetriebnahme anzuzeigen. 
Also immer den aktuellen Durchfluss aufsummieren und durch die Anzahl 
aller Messungen teilen. Dann hast Du irgendwann den ganz exakten 
Durchschnitt von mehreren Jahren, aus dem Du aber überhaupt nicht sehen 
kannst, was gerade passiert, weil sich die Zahl kaum noch bewegt.

Du musst Dich also immer entscheiden zwischen Genauigkeit der Anzeige 
und Änderungsgeschwindigkeit. Von dem her war meine Aussage, dass 
Genauigkeit und Änderungsgeschwindigkeit bei der Methode unabhängig 
wären, vielleicht etwas unglücklich. Denn je mehr Du mittelst, desto 
genauer wird der angezeigte Wert, weil er sich weniger bewegt. Egal mit 
welcher Methode. Die empirische Vorgehensweise wäre also, den 
Glättungsfaktor so einzustellen, dass Du so viele Nachkommastellen 
anzeigen kannst, wie Du sehen möchtest, ohne dass sie sich von Sample zu 
Sample ändern.

Das ganze übrigens immer vorausgesetzt, dass Du eine Anzeige des 
Momentandurchflusses willst. Wenn Du was anderes möchtest, z.B. den 
Durchfluss längerfristig protokollieren, musst Du natürlich andere Werte 
berechnen. Wenn Du also eine Logdatei mit den Durchflüssen pro Minute 
erstellen willst, dann würde es sich anbieten, immer 60 Messungen zu 
addieren und deren Summe zu speichern. Dann kannst Du aus den Daten den 
Durchfluss auf 1/50 Liter genau erkennen.

Wenn man schon einen Mikrocontroller hat, spricht ja auch nichts 
dagegen, mehrere Anzeigen einzubauen. Zum Beispiel einen 
Momementandurchfluss, der schnell aktualisiert wird und einen, der die 
Summe/Durchschnitt seit dem letzten Reset zeigt. Also so ähnlich wie die 
Spritverbrauchsanzeige im Auto.

von xfr (Gast)


Lesenswert?

Die Spritverbrauchsanzeige ist vielleicht allgemein ein gutes Beispiel: 
Dort wird der Verbrauch in Litern pro 100 km angezeigt. Dieser Wert wird 
aber nicht nur alle 100 km berechnet oder aus einem gleitendem Fenster 
über die Messwerte der letzten 100 km bestimmt, sondern mit einer 
gewissen Glättung aus dem aktuellen Durchfluss bestimmt. Die Einheit des 
angezeigten Wertes hat also nichts damit zu tun, über welchen Zeitraum 
gemessen und gemittelt wurde.

von Toto Loco (Gast)


Lesenswert?

Ich wuerd nicht eine Sekunde messen, das ist Schrott, sondern den 
Abstand der Pulse. Und diesen glaetten, mit den exponential filter, resp 
tiefpass.
Fuer erhoehte Genauigkeit kann man den Abstand von zB 100 Pulsen messen, 
mit einem Ringbuffer.

von xfr (Gast)


Lesenswert?

Warum soll das Schrott sein? Solange kein Impuls verloren geht, hat man 
damit den exakten Durchfluss (Anzahl der Impulse) erfasst.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

An Abstandsmessung hatte ich natürlich auch schon gedacht. Alleine - das 
scheint nicht zu funktionieren. Der Hintergrund dürfte sein: Das Ding 
sendet die Pulse im "Burst", d.h. er entscheidet sich zu Anfang jeder 
Sekunde wieviele Pulse er senden möchte (maximal 128) ermittel daraus 
eine "ungefähre" Pausenzeit (mit etwas Sicherheit), am Ende der Pulse 
ist dann noch etwas mehr als die normale Pausenzeit übrig.

von Udo S. (urschmitt)


Lesenswert?

Michael Reinelt schrieb:
> gefühlsmäßig hätte ich an
> eine Minute gedacht, das wären dann ~8000 Impulse,

Ehe man sich Gedanken um mehrere 1000 Impulse zählen macht, sollte man 
mal schauen wie genau der Sensor überhaupt misst, was nützen dir mehr 
als 100 Impulse plusminus 1 Impuls wenn der Sensor schon 5% Toleranz 
hat.

Merke: Gefühle sind gut fürs flirten, Ingenieursarbeit hat mehr mit 
denken zu tun. :-)

von amateur (Gast)


Lesenswert?

Nimm den Ansatz von "xfr" – wenn er Dir gefällt - und lass parallel 
einen Summenzähler mitlaufen. Du musst ja, nur weil Du den Durchfluss 
messen willst, die Mengenimpulse nicht wegwerfen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.