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
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.
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
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.
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
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.
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
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?
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
>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?
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.
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
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
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
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
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
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.
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?
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