Forum: Mikrocontroller und Digitale Elektronik gleitender Mittelwert mittelt nicht sauber


von Uwe (Gast)


Angehängte Dateien:

Lesenswert?

Hi,
bin auf der Suche nach zu schnellem Wertewechsel auf ein Probl.
bei gleitender Mittelwertbildung gekommen.

Sachverhalt:
Sprache: ASM
Langsame Temperaturmessung mit ADC( nur ADCL wird gebraucht).
Man kan wunderbar beobachten wie sich alles einpegelt.
Irgendwann fangen die Werte an schnell zu springen (+/-1) bis es sich
auf den einen oder anderen Wert einstellt.
Um genau dieses "flattern" wegzubekommen wird (sollte) gleitender 
Mittelwert benutzt.
Ist aber nicht, genau im Umschaltpunkt des Inputs wird der 1:1 an den 
Output durchgereicht.
Im Anhang ist das Problem aufs Minimum reduziert und direkt prüfbar.
Es ist eine 32Bit und eine 16Bit Glättung im Programm. Wenn R1 auf
$FF steht wird _2Byte angesprungen sonst 4Byte
In Z(R30/R31) werden dei Durchläufe angezeigt. Werden im Simulator die 
Breakpoints auf die nops vor CLR R30.. gesetzt kann direkt mit F5 
gearbeitet werden.
Werden die ausgeklammerten Behelfsänderungen mit eingefügt geht es 
deutlich besser, aber nicht sauber.

Hat jemand eine bessere Idee???

Besten Dank schon mal und einen schönen Abend noch, Uwe

von berliner (Gast)


Lesenswert?

Oh Mann, warum benutzt du kein C? C ist wie geschaffen für leichte 
Rechenaufgaben.

von Achim H. (anymouse)


Lesenswert?

Uwe schrieb:
> Hat jemand eine bessere Idee???

Mehrere Ideen, ja; ob besser?

Das Probleme sehe ich als leichtes Rauschen um die Sprungstelle.

Als erstes könnte man eine kleine Hysterese einbauen: von 0 auf 1 
springt er bei 0,5+x (z.B. bei 0,6), und von 1 auf 0 erst bei 0,5-x 
(z.B. 0,4). Das hat einen ruhigeren Anzeigewert zur Folge, der aber 
etwas ungenauer ist und die leichten Schwankungen nicht erkennen lässt.

Die zweite Variante wäre es, die Rundungsgrenzen periodisch zu 
verschieben, also um y nach oben oder unten von 0,5: also z.B. die erste 
halbe Sekunde bei 0,6, dann eine halbe Sekunde bei 0,4, danach wieder 
bei 0,6 usw. Noch besser wäre es, wenn man keine Zwei-Stufen-Funktion 
nimmt, sondern einen Sinus oder eine Rampe. Über die Periodendauer kann 
man dann einstellen, wie langsam der Wert schwanken soll.

von Uwe (Gast)


Lesenswert?

Hi Achim ,
>Über die Periodendauer kann
>man dann einstellen, wie langsam der Wert schwanken soll.
Wenn ich mir das richtig überlege sollte man vermutlich alle R/Cs aus 
dem analogen Bereich entfernen damit das Rauschen hoch genug ist.
Allerdings löst es nichut das Problem der Mittelwertbildung.

Einen schönen Abend noch, Uwe

von Achim H. (anymouse)


Lesenswert?

Uwe schrieb:
> enn ich mir das richtig überlege sollte man vermutlich alle R/Cs aus
> dem analogen Bereich entfernen damit das Rauschen hoch genug ist.

Hm, nee, das meinte ich nicht.

Es gibt bei der oben beschriebenen Problemstellung "bin auf der Suche 
nach zu schnellem Wertewechsel auf ein Probl. bei gleitender 
Mittelwertbildung gekommen." zwei Knackpunkte:

Der eine ist das Rauschen, dem kann man über die zeitliche Mittelung 
abhelfen; diese kann elektrisch über R/C-Glieder oder mathematisch über 
gleitende Mittelwertbildung) abhelfen. Beides hat die selbe Wirkung.

Der zweite ist die Unstetigkeit aufgrund der diskreten Wertanzeige. 
Diese ist für die rasche Änderung verantwortlich (in Verbindung mit 
einem ganz klinen Rauschen), aber nur dann, wenn der tatsächliche Wert 
an der Grenze zwischen zwei diskreten Punkten liegt. Und da ist es egal, 
wieviel sonstige Auflösung Du sonst hast -- die hat nur einen Einfluss 
darauf, welcher Wert zum "Flattern" führt: Das kann trotz minimalem 
Rauschen von 1ppm bei 9,5 zum Sprung zwischen 9 und 10 führen, oder bei 
9,9995 zum Springen zwischen 9,999 und 10,000.

von Uwe (Gast)


Lesenswert?

Hi,
>oder mathematisch über
>gleitende Mittelwertbildung) abhelfen. Beides hat die selbe Wirkung.
Eben nicht, das ist ja mein Problem. Von 10 nach 11 ist alles ok, auch 
von
11 nach 12 nur nicht von 11->12->11 oder eben 12->11->12. immer in der 
Richtungsumkehr habe ich nur einen Durchlauf. Da krankt es.

Einen schönen Abend noch, Uwe

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Uwe schrieb:
> Langsame Temperaturmessung mit ADC( nur ADCL wird gebraucht).

Das klingt verdächtig, du hast den ADC Teil aber leider nicht 
mitgepostet. Wenn du aus dem 10-bit ADC nur einen 8-bit Wert brauchst, 
setzt du normalerweise ADLAR und liest ADCH - nicht ADCL.

von Uwe (Gast)


Lesenswert?

Hi,
>Das klingt verdächtig, du hast den ADC Teil aber leider nicht
>mitgepostet. Wenn du aus dem 10-bit ADC nur einen 8-bit Wert brauchst,
>setzt du normalerweise ADLAR und liest ADCH - nicht ADCL.
Das ist richtig, aber der Teil passt schon.
Lasse doch bitte das Prog. aus dem Anhang im Simulator laufen verändere 
mal NeuL um +-1 und beobachte Z.
Nicht vergessen:
>Breakpoints auf die nop's vor CLR R30
Wenn die Anderung von NeuL >1 ist oder die Richtung(fallend/steigend)
beibehält steht Z bei 256. Ist die Änderung aber nur +-1 steht Z bei 1.
Die Dämfung ist also quasi 0. Mit meiner Änderung sind ja wenigstens 128 
Durchläufe vorhanden. Ziel waren aber 256. Die Frage lautete ja auch:
>Hat jemand eine bessere Idee???
Da kommen dann so Antworten wie
>warum benutzt du kein C? C ist wie geschaffen für leichte Rechenaufgaben.
hmmm..? Geht es denn in C richtig? Wennja wie sieht das Listing dazu 
aus.

Einen schönen Tag noch, Uwe

von PittyJ (Gast)


Lesenswert?


von Achim H. (anymouse)


Lesenswert?

Uwe schrieb:
> immer in der Richtungsumkehr habe ich nur einen Durchlauf.

Was meinst Du mit "Durchlauf"?

Uwe schrieb:
> alles einpegelt

Gibt es eine Regelung, die mit dem gleichen Wert arbeitet, wie die 
Anzeige?

--

Zu Deiner Antwort:

Wenn wenn der tatsächliche Wert nah genug an einer Unstetigkeitsstelle 
des ADC-Verfahrens liegt, reichen hier auch kleinste (Rausch)Änderungen, 
um die Anzeige springen zu lassen.

Durch Mittelwertbildung, RC-Glieder etc. kannst Du diese Änderungen zwar 
klein kriegen, aber nicht verhindern; was Du beeinflusst, was für das 
System "nah genug" bedeutet.

Dadurch beeinflusst Du aber nicht die Wirkung der Unstetigkeit. Genau 
auf der Stelle löst beliebig kleines Rauschen die Sprünge aus, auch wenn 
das Rauschen weit unterhalb von 0,001 LSB ist.

Und weil sich der tatsächliche Wert in der Nähe des Umkehrpunktes nur 
langsam ändert, bleibt er längere Zeit in der Nähe der 
Unstetigkeitsstelle.

---

Zur Lösung:

Dein Problem fasse ich wie folgt auf: (a) Du möchtest verhindern, dass 
auf den Schrittgrenzen die Anzeige so schnell springt, dass man sie 
nicht mehr gut ablesen kann. (b) Du möchtest einen recht genauen Wert 
darstellen. (c) Es handelt sich um ein sehr langsam veränderliches 
Signal mit geringem Rauschen.

Folgende Ideen:

- Durch Mittellung kann man den Bereich verkleinern, in welchem die 
Sprünge auftreten; verhindern kan man ihn nicht.

- Der angezeigte Wert ändert sich nur in bestimmten Zeitabständen, z.B. 
jede Sekunde -- dadurch kann man ihn immer gut ablesen.

- Bei Änderungen wird eine konstante Hysterese verwendet, der Wert 
ändert sich erst, wenn tatsächlicher und angezeigter Wert sich um eine 
festgelegt Größe > 1 LSB unterscheiden -- hier könnte man die Größe der 
Hysterese an das Rauschen anpassen.

- Man passt die Diskretisierungsgrenzen der Anzeige dynamisch an das 
Eingangssignal an: Zunächst werden nur gerade Werte angezeigt. Bleibt 
das Signal aber länger als zwei Abtastungen viel näher bei einem 
ungraden Wert stehen (was ein Springen zwischen den beiden benachbarten 
geraden Werten zur Folgen haben könnte), werden nun nur die ungerade 
Werte angezeigt. -- Verständlich?

von Uwe (Gast)


Lesenswert?

Hi PittyJ,
>http://de.wikipedia.org/wiki/Savitzky-Golay-Filter
Naja, der Gedanke ist ja gut. Nur der Aufwand ist deutlich höher was 
aber nicht das Ziel ist. Eine echte Mittelwertbildung mit gespeicherten 
Werten
würde ja vermutlich richtig arbeiten, aber der Aufwand......

Einen schönen Tag noch, Uwe

von spontan (Gast)


Lesenswert?

>würde ja vermutlich richtig arbeiten, aber der Aufwand......

Wow, würde...

Keine Ideen haben und dann würde sagen...

Da waren ziemlich gute Ideen in den Antworten. Was willst Du mehr?

von und nun (Gast)


Lesenswert?

Ein gleitenden mittelwert ist uebrigens dasselbe wie ein Tiefpass, wie 
ein exponentieller Mittelwert. Der funktioniert sehr gut, man muss ein 
paar mehr stellen rechnen und sich dann wieder gleich viele zurueckgeben 
wie man urspruenglich hatte.

von Uwe (Gast)


Lesenswert?

Hi Achim ,
>Uwe schrieb:
>> immer in der Richtungsumkehr habe ich nur einen Durchlauf.

>Was meinst Du mit "Durchlauf"?
Interrationen der Mittelung, also wie oft gemittelt werden muss ehe der 
Input am Output erscheint.

Uwe schrieb:
> alles einpegelt

>Gibt es eine Regelung, die mit dem gleichen Wert arbeitet, wie die
>Anzeige?
Jain, Ich höre/sehe das Relais sehr oft schalten 2-3 mal/sek weil die 
Abarbeitung im 100ms Takt erfolgt. Das Hystereseproblem habe ich ja auch 
garnicht angesprochen, das ist ja meine Baustelle. Aber mein ADC wird 
aller 5ms abgefragt x 256(Interrationen = 1,28s minimale Wertänderung
Also habe ich mich hingesetzt und habe untersucht warum das Rel. so oft 
schaltet. Ursache: "gleitender Mittelwert mittelt nicht sauber"
Ich habe versucht dieses deutlich zu verbessern was aber bei 128 
Interratinen(ohne deutlich höheren Aufwand)ein Ende fand.
Da alle Implementierungen welche ich im Forum finden konnte das gleiche 
Problem haben dürften will ich auch viele an der Lösung teilhaben 
lassen.
Es ist ja eine Lösung da, aber geht es einfacher/besser?

>- Man passt die Diskretisierungsgrenzen der Anzeige dynamisch an das
> Eingangssignal an: Zunächst werden nur gerade Werte angezeigt. Bleibt
> das Signal aber länger als zwei Abtastungen viel näher bei einem
> ungraden Wert stehen (was ein Springen zwischen den beiden benachbarten
> geraden Werten zur Folgen haben könnte), werden nun nur die ungerade
> Werte angezeigt. -- Verständlich?
Das wäre jetzt mal ein Ansatz, aber der Aufwand ist nicht unerheblich.
Eigentlich müsste man nur feststellen wohin der neue Wert wandert und 
dazu
die Startbedingungen der Formel/des Programms anpassen. Daran sitze ich 
nun aber eigentlich schon zu lange.

Einen schönen Tag noch, Uwe

von Uwe (Gast)


Lesenswert?

Hi und nun,
>Ein gleitenden mittelwert ist uebrigens dasselbe wie ein Tiefpass, wie
>ein exponentieller Mittelwert. Der funktioniert sehr gut, man muss ein
>paar mehr stellen rechnen und sich dann wieder gleich viele zurueckgeben
>wie man urspruenglich hatte.
War eigentlich der Meinung das ich das mache und es klappt ja auch bis 
auf diese kleine Ausnahme.

Einen schönen Tag noch, Uwe

von und nun (Gast)


Lesenswert?

Dann reich doch mal eine Tabelle von Inputwerten rueber.

Nur das Lowbyte verarbeiten zu wollen macht nur Sinn wenn die oberen 
Stellen eh Null sind.

von Uwe (Gast)


Lesenswert?

Hi und nun ,
>Dann reich doch mal eine Tabelle von Inputwerten rueber.
Zu was? Starte einfach das Programm und verändere NeuL. NeuL/H stellt 
den Input dar. Aber Bitte:81,81,82,82,83,83,82,82,83,84,
                       Da krankt es   ^^^   ^^^
>Nur das Lowbyte verarbeiten zu wollen macht nur Sinn wenn die oberen
>Stellen eh Null sind.
Glaube mir es macht Sinn.
Sensor LM35
ADC_LSB: 10mV = 1°K
Offset für negative Temp.0,7V = 70 LSB
max zu verarbeitende Temp 100°C = 100 LSB
100+70 = 170 < 256
Noch Fragen?

Einen schönen Tag noch, Uwe

von Uwe (Gast)


Lesenswert?

Mist die Formatierung stimmt nicht
>den Input dar. Aber Bitte:81,81,82,82,83,83,82,82,83,84,
>                       Da krankt es   ^^^   ^^^
Die ersten Pfeile gehören unter 83,82 die zweiten unter 82,83

von und nun (Gast)


Lesenswert?

Das ist ja Bitrauschen, bedarf nicht mal einer Filterung, wo ist das 
Problem?

von Uwe (Gast)


Lesenswert?

Hi,
>Das ist ja Bitrauschen, bedarf nicht mal einer Filterung, wo ist das
>Problem?
Das Problem ist die Geschwindigkeit mit der dieses "Bitrauschen" am 
Ausgang erscheint. Was meinst du für was die Mittelwerbildung gedacht 
ist?


Einen schönen Tag noch, Uwe

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Uwe schrieb:
> Was meinst du für was die Mittelwerbildung gedacht
> ist?

Schlechte Laune?
Du kannst mehrere Ansätze verfolgen:
* Hardware schon mit Mittelung versehen, um etwaige Störeinflüsse auf 
den Messwert zu verringern. Das kann im einfachsten Fall eine RC 
Kombination am ADC Eingang sein. Da wir alle hier nicht wissen, ob du 
evtl. den ADC Eingang mit einer zu hochohmigen Quelle antreibst, kann 
man das nicht ausschliessen. Wenn es dir auch um möglichst genaue 
Messungen geht, überlege, ob du evtl. den ADC Noise Canceler Modus 
benutzen solltest.
* Fifo Speicher für die gewünschte Anzahl Messwerte einrichten und über 
diesen Fifo mitteln. Der ADC schiebt Werte rein, der älteste fliegt 
dabei raus.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Uwe schrieb:
> Also habe ich mich hingesetzt und habe untersucht warum das Rel. so oft
> schaltet. Ursache: "gleitender Mittelwert mittelt nicht sauber"
Mal abgesehen davon, dass dir dein etwas aufgeregter Ton hier sicher 
nicht weiterhilft (und auch im ganzen Leben nicht), hilft dir auch eine 
Mittelwertbildung nicht weiter.
Denn selbst wenn du mittelst und der Eignagnswert schwankt dauernd um 
das LSB dann wird es dir passieren, dass der Ausgang des Filters um die 
letzte Stelle schwankt. Denn eigentlich müsste dann ja z.B. bei 
81,82,81,82,81,82 genau 81,5 herauskommen. Nur: was soll da dann 
angezeigt werden? 81 oder 82? Klar sagst du: Nimm den Interger und zeige 
81 an! Aber was soll denn dann herauskommen wenn du 
82,81,82,...,82,81,82,...,82,81,82 also über einige Abtastungen Zeit 82 
und dann wieder 81,9 hast?

Du brauchst also zwingend eine Auswertung, die erst dann weiterschaltet, 
wenn sich der Wert "wirklich" geändert hat. Aber du hast das ja selbst 
erkannt:
Uwe schrieb:
> Das Hystereseproblem habe ich ja auch garnicht angesprochen, das ist ja
> meine Baustelle.

Uwe schrieb:
> Glaube mir es macht Sinn.
Sei sicher: du hast das noch nicht fertig gedacht!
> Sensor LM35
> ADC_LSB: 10mV = 1°K
> Offset für negative Temp.0,7V = 70 LSB
> max zu verarbeitende Temp 100°C = 100 LSB
> 100+70 = 170 < 256
Was, wenn du deinen Sensor nicht genau auf 1K aulöst, sondern eine 
Sub-Kelvin Auflösung machst und darauf dann die Hysterese?
Denn wenn du deinen Sensor mit dem ADC auf 1K auflöst, dann musst(!) du 
ja jeden Wert ausgeben und kannst(!) nicht ohne Weiteres mal in 
Hintergrund mit höherer Auflösung spielen.
> Noch Fragen?

Uwe schrieb:
>> Gibt es eine Regelung, die mit dem gleichen Wert arbeitet, wie die
>> Anzeige?
> Jain, Ich höre/sehe das Relais sehr oft schalten 2-3 mal/sek weil die
> Abarbeitung im 100ms Takt erfolgt.
Wenn du das Relais zu oft schaltest, warum schaltest du es dann nicht 
einfach weniger oft?

von Uwe (Gast)


Lesenswert?

Hi
Muss mich erstmal für den gestrigen Kommunikationsabbruch entschuldigen, 
aber wenn man Bereitschaft hat muss man einfach manchmal los.
Dafür habe ich mich heute nochmal hingesetzt und vor allem mal meinen 
Lösungsansatz in Echtzeit laufen lassen (bisher nur in der Simmu).
War überrascht über die Ruhe und konnte es erst garnicht glauben bis bei 
mir der Groschen fiel. Die Lösung ist Chaos. Lothar hatte den Finger 
schon am richtigen Drücker 81,82,81,82 müsste eigentlich 81,5 sein. Geht 
aber nicht, also 81 weil 0,5 binär nicht möglich. Mein Problem war ja 
bisher das eine +-1 Änderung sofort am Ausgang erschien und auch eine 
Mittelung über 32 Bit nichts gebracht hätte. Auch wie Vorgeschlagen mit 
FIFO hätte daran nichts geändert weil der FIFO auch nur mit 81,82,81 82 
gefüllt wird.
Jetzt kommt aber die Änderung Der Mittelwert sei 81 der alte ADC-Wert 
ebenfalls 81 sind beide = wird der FIFO zur Hälfte auf 81 vorgeladen.
In der Tabelle(FIFO) stehen 82,81,82,81,82,81 -> 81,81,81,82,81,82
Erst wenn der Mittelwert der nächsten ADC-Werte >81 ist, kippt das 
ganze.
Das Chaos hilft jetzt die Tabelle bei 81 = 81 öfters zu "resetten".
Das dauert solange Bis der ADC wirklich bei 82 steht. Abwärts geht das 
natürlich genauso.
@Matthias Sch
>Schlechte Laune?
naja, meine Frage war ja eigentlich
>Werden die ausgeklammerten Behelfsänderungen mit eingefügt geht es
>deutlich besser, aber nicht sauber.
>Hat jemand eine bessere Idee???
Hast du dir das Prog mal angeschaut? Ich wage zu denken, nein.
Mir ging es eigentlich darum ob es dafür eine bessere Lösung gäbe weil 
ja die Interrationen scheinbar halbiert wurden. Dank Chaos ist das aber 
nur scheinbar so. Wenn sich dann aber fast alle Antworten auf die 
Randbedingungen beziehen und am Kernproblem vorbeischrammen kann man 
schon mal ungeduldig werden, tschuldigung.
@Lothar Miller
>Du brauchst also zwingend eine Auswertung, die erst dann weiterschaltet,
>wenn sich der Wert "wirklich" geändert hat.
> Aber du hast das ja selbst
>erkannt:
>Uwe schrieb:
>> Das Hystereseproblem habe ich ja auch garnicht angesprochen, das ist ja
>> meine Baustelle.
Jo, das Hystereseproblem bezog sich aber nur auf das Relais nicht auf 
den Wert an sich. Machmal ist das eben nicht so einfach.
>Offset für negative Temp.0,7V = 70 LSB
Der Offsetwert wird ja auch gemessen. Wie verpasse ich den dem eine 
Hysterese? Der ist ja an allen Temp. beteiligt. Ok, man könnte sagen der 
Wert wird pro Min.nur 1x erneuert, aber ist das wirklich sinnvoll?

Wenn also tatsächlich mal jemand Lust hat die Lösung zu verbessern bin 
ich stark daran interessiert.

Einen schönen Abend noch, Uwe

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.