Liebe Gemeinde. hab da so ein kleines problem wo ich dachte das ist in 5min weg programmiert. dachte ich! Folgendes: hab ein schiebepoti (10k) am ADC. Referenz is Vcc und ein Co is auch mit dran. auflösung muss 8bit sein. soweit funktioniert alles gut. ABER: wenn man mit dem poti genau zwischen zwei werte fahrt dann zappeln der wert logischerweise zischen zB 127 und 128. und genau diese situation kann ich gar nicht gebrauchen. leider hilft da auch kein anderer prescaler oder gleitende bzw. exponentielle mittelwertberechnungen. diese mölichkeiten verlangsamen natürlich das zappeln aber es ändert ja nichts an der situation dass das poti genau zwischen zwei werte eingestellt ist. und wenn ich versuche mit div. „if(blabla)" alles in den griff zu bekommen dann halbiere ich mir entweden die auflösung bzw. schaff es nicht immer auf 255 bzw. 0! ausserdem hab ich nicht viel zeit dafür, ein paar usec. (@16MHz ATmega328) Mein bauchgefühl sagt mir da gibts ne ganz einfache lösung dafür aber ich will sie einfach nicht find. ich denk sicher schon viel zu kompliziert. ich hab den wert aus der letzten messung in ner variable also hier könnte man auch ansetzten. bzw. könnte man den vorletzten wert auch noch buffern und in einen vergleich bzw. einer formel einsetzen. timer laufen keine und stehen nicht zur option! ich drau mich fast wetten da gibts ne super simple lösung! Herzlichsten dank schon mal :)
stift schrieb: > ich drau mich fast wetten da gibts ne super simple lösung! Hysterese heißt das Zauberding. Erst wenn der Wert um mehr als 1 vom aktuellen Ausgangswert abweicht, wird der Ausgang geändert.
Mike schrieb: > Hysterese heißt das Zauberding. Erst wenn der Wert um mehr als 1 vom > aktuellen Ausgangswert abweicht, wird der Ausgang geändert. Ja stimmt, Hysterese ist der richtige ansatz. Aber dann hab ich das problem das ich mir die auflösung mind. halbiere da ja der "Ausgang" immer nur aktiv wird wenn sich am eingang der wert um mehr als 1 ändert. oder denk ich da jetzt falsch?
Nein die Auflösung bleibt gleich, nur es hat halt nicht mehr die gleiche Genauigkeit. +-1
stift schrieb: > denk ich da jetzt falsch? ja. Man kann ja von 1 auf 3 ändern, nur nicht von 1 auf 2. Hast du mal überlegt wie lang dein Poti ist? wie viel mm ist dann da ein adc-wert?
So ist das nun mal. So ein AD-Wandler zappelt immer. Entweder macht man den Analogteil besser, oder man muss damit leben. Bei einem 10-Bit Atmel lass ich immer gleich 2 weg. Ich hatte auch mal einen 24 bittigen Wandler. Da zappelten die letzten 4 Bit auch nur herum. Also gleich ma 4 Bit weg. Wenn du die Genauigkeit brauchst, dann nimm einen 16 Bit Wandler, der hat genug Reserven.
Die Lösung ist, wie du schon ahnst, sehr einfach. Denke doch mal auf Bit-Ebene, was zappelt da? Das ist mit einer Bitoperation gelöst.
Peter II schrieb:
> Man kann ja von 1 auf 3 ändern, nur nicht von 1 auf 2.
Das wär ja ok aber leider folgendes problem:
wenn der neue wert die 3 ist und die änderung mind. 2 sein muss dann
komm ich weder auf die 4 noch auf die 2!
usw. als halbierte auflösung :(
TriHexagon schrieb:
> Denke doch mal auf Bit-Ebene
Danke aber ich denk seit 24h fast an nichts anders mehr. Micht lässt es
einfach nicht in ruhe weil die lösung sicher simpl ist. ich denk ich bin
festgefahren
stift schrieb: > wenn der neue wert die 3 ist und die änderung mind. 2 sein muss dann > komm ich weder auf die 4 noch auf die 2! > usw. als halbierte auflösung :( doch wenn du vorher auf 10 änderst.
PittyJ schrieb: > Entweder macht man den Analogteil besser, oder man muss damit leben. Besser machen nützt da nichts, es gibt immer eine Schaltschwelle zwischen zwei Anzeigewerten.
PittyJ schrieb:
> dann nimm einen 16 Bit Wandler...
ich kann auch einen 100Bit wandler nehmen und die hinteren 99 Bit
abschneiden. auflösung werte hab ich dann nur mehr 2. Also 0 und 1.
ändert leider gar nichts daran wenn das poti dann genau bei 50% steht
stift schrieb: > TriHexagon schrieb: >> Denke doch mal auf Bit-Ebene > > Danke aber ich denk seit 24h fast an nichts anders mehr. Micht lässt es > einfach nicht in ruhe weil die lösung sicher simpl ist. ich denk ich bin > festgefahren Naja dann. Also wenn der ADC-Wert sich ständig um eins verändert, bedeutet dass das lowest bit, also das erste Bit, zappelt. Das ist bei einer ADC Wandlung ganz normal und wenn du diese Zappelei nicht haben möchtest, ignorierst du einfach das Bit.
TriHexagon schrieb: > Das ist bei > einer ADC Wandlung ganz normal und wenn du diese Zappelei nicht haben > möchtest, ignorierst du einfach das Bit. das geht nicht!!!! wenn der wert zwischen 3 und 4 pendelt, hilft es überhaupt nicht das letzte Bit zu ignorieren.
TriHexagon schrieb:
> ignorierst du einfach das Bit.
Hehe leider nicht! dann wär ich auf 7Bit. sprich hab dann eine auflösung
von 0 bis 127. und wenn ich das poti wieder genau auf 50% stelle zappelt
das 7te Bit. soll ich das dann auch abschneiden? :P
Ich schneid einfach alle 8 ab dann kann nix mehr zappeln!
Peter II schrieb: > TriHexagon schrieb: >> Das ist bei >> einer ADC Wandlung ganz normal und wenn du diese Zappelei nicht haben >> möchtest, ignorierst du einfach das Bit. > > das geht nicht!!!! > > wenn der wert zwischen 3 und 4 pendelt, hilft es überhaupt nicht das > letzte Bit zu ignorieren. Dann liest du das zweite Bit halt auch nicht ein. Das ist mit einem AND erledigt. Falls es noch schlimmer pendelt, liegt es an der Hardware und du musst das Signal stabilisieren, z.B. mit einem Kondensator.
Mach mehrere Messungen und bilde den Mittelwert. Das wird das "Gezappel" etwas beruhigen.
stift schrieb: > Hehe leider nicht! dann wär ich auf 7Bit. sprich hab dann eine auflösung > von 0 bis 127. und wenn ich das poti wieder genau auf 50% stelle zappelt > das 7te Bit. soll ich das dann auch abschneiden? :P > Ich schneid einfach alle 8 ab dann kann nix mehr zappeln! Nein du bist nicht auf 7Bit, weil du das LOWEST Bit abschneidest. Gewöhn dich an den Gedanken, dass du mindestens ein Bit ignorieren musst. Nicht umsonst kann man nicht 24Bit Wandeln ohne auf das Layout zu achten.
du musst den ADC wert auf eine andere variable speichern und dann mit dem neuen ADC wert vergleichen ob die differenz größer als 2 ist und dann erst dann wenn das zutrifft den neuen wert auf die variable speichern.
Und lass die völlig doofe Unsitte Vcc als Referenz zu nehmen. Die hat einen Haufen Brumm wegen dem Digitalteil und ist sowiezo 10 mal ungenauer als dein letztes Bit. Nimm also eine externe oder die interne Referenz, sonst kannst du gleich die letzten 3 Bits wegwerfen. Ausserdem würde es mich nicht wundern wenn der eine oder andere Kondensator in der Stromversorgung fehlen würde. Also nimm das Datenblatt und mache da wo es im Datenblatt angegeben ist auch einen Kondensator hin, und zwar so nahe wie möglich an die µC Pins.
:
Bearbeitet durch User
Eine Frage an den TO: Was willst du erreichen. Wenn das Poti genau zwischen zwei Werten liegt, also auch der ADC-Wert, dann wird es immer zappeln. Aber dann ist weder der Wert z. B. 4 noch der Wert 3 richtig. Ich würde in deinem Fall wahrscheinlich über 4 Werte einen Mittelwert bilden und dann runden. Vielleicht macht es dann besser. Zusätzlich dann eine Hysterese, aber nicht den Wert 1 verwenden, sondern meinetwegen 0.5. Du schreibst zwar, dass du nur ein paar us zur Berechnung Zeit hast, aber nicht wie kritisch der zeitliche Wert vom Poti ist. Wenn dies eine Benutzereingabe ist, dann hast du "ewig" Zeit für die Berechnung eines Mittelwerts. Grüße
stift schrieb: > ich kann auch einen 100Bit wandler nehmen und die hinteren 99 Bit > abschneiden. auflösung werte hab ich dann nur mehr 2. Also 0 und 1. > ändert leider gar nichts daran wenn das poti dann genau bei 50% steht Der nächste Denkfehler. Bei einem ADC arbeitet man immer mit einem Oversampling. Entweder in Hardware, wo man für 8 Nutzbits einen 10bit ADC nimmt und zwei Bits weglässt, oder man macht das ganze in Software. Also einfach 16x den ADC-Wert addieren und dann durch 16 teilen. Normalerweise hat das Zappeln der Bits eine Tendenz. Diese macht man sich hier zu nutze. Wenn du von deinem 100bit-ADC 99 Bits weg läßt verschenkst du natürlich gewaltig Auflösung. Läßt du aber nur 10 Bit weg hast du vermutlich das gewünschte Ergebnis. Sollte es dann immer zappeln ist möglicherweise die Eingangsbeschaltung suboptimal. Oftmals hilft ein kleiner C um das zappeln schon etwas zu beruhigen.
stift schrieb: > Mein bauchgefühl sagt mir da gibts ne ganz einfache lösung dafür aber > ich will sie einfach nicht find. ich denk sicher schon viel zu > kompliziert. Nö. Dein Bauchgefühl ist sehr naiv. +/- 1 LSB ist schon ganz schön gut.
Jens PICler schrieb: > stift schrieb: >> ich kann auch einen 100Bit wandler nehmen und die hinteren 99 Bit >> abschneiden. auflösung werte hab ich dann nur mehr 2. Also 0 und 1. >> ändert leider gar nichts daran wenn das poti dann genau bei 50% steht > > Der nächste Denkfehler. Bei einem ADC arbeitet man immer mit einem > Oversampling. Entweder in Hardware, wo man für 8 Nutzbits einen 10bit > ADC nimmt und zwei Bits weglässt, oder man macht das ganze in Software. > Also einfach 16x den ADC-Wert addieren und dann durch 16 teilen. > Normalerweise hat das Zappeln der Bits eine Tendenz. Diese macht man > sich hier zu nutze. Wenn du von deinem 100bit-ADC 99 Bits weg läßt > verschenkst du natürlich gewaltig Auflösung. Läßt du aber nur 10 Bit weg > hast du vermutlich das gewünschte Ergebnis. Sollte es dann immer zappeln > ist möglicherweise die Eingangsbeschaltung suboptimal. Oftmals hilft ein > kleiner C um das zappeln schon etwas zu beruhigen. Das Zappeln zwischen zwei Werten kann man auch nicht dadurch vermeiden indem man Bits weglässt. Es gibt immer eine Schaltschwelle. Und immer wenn es eine Schaltschwelle ohne Hysterese gibt, gibt es auch das Zappeln zwischen zwei Werten.
1 | ADC_new=ADCH; |
2 | if(((ADC_value-ADC_new)>1)||((ADC_value-ADC_new)<1)) |
3 | {
|
4 | ADC_value=ADC_new; |
5 | }
|
Somit kannst du halt nicht ganz auf 0 drehen sonder Minimum ist 1.
Rufus Τ. Firefly schrieb: > Mach mehrere Messungen und bilde den Mittelwert. Das wird das "Gezappel" > etwas beruhigen. Was meinst du, was der Mittelwert macht, wenn der ADC-Wert zwischen 1 und 2 zappelt? Richtig - der Mittelwert zappelt um 0.5 und wird - du ahnst es schon - bei der Ausgabe mal auf und mal abgerundet ;-(
Es besteht immer die Möglichkeit dass das unterste Bit schwankt. Dabei hilft es auch nichts wenn man ein paar der unteren Bits ignoriert auch dann kann es schwanken, wenn auch weniger Wahrscheinlich. Was hilft ist Hysterese - damit man dann nicht nur jeden 2. Wert erhalten kann, macht man die Hysterese (oder Totband) mit der vollen (10 Bit) Auflösung und schneidet dann auf 8 Bit runter. Also den neuen Wert nur übernehmen wenn der ADC wert (bei 10 Bit Auflösung) um mehr als etwa 2 geändert hat, und erst dann auf 8 Bit runden. Damit ist jeder 8 Bit wert möglich, aber es kommt praktisch nicht mehr zu sichtbaren Schwankungen oder deutlichen Abweichungen bei der Anzeige. Falls man von der Hardware zu viele Störungen hat, hilft ggf. zusätzliche eine Filterung (Mittelwert oder besser wohl Median), die kostet aber relativ viel Zeit. So zeitkritisch wird es kaum sein, denn der ADC liefert maximal etwa alle 30 µs einen neuen Wert, und so schnell bewegt man einen mechanischen Poti auch nicht.
Zappel-Schnappel schrieb: > Das Zappeln zwischen zwei Werten kann man auch nicht dadurch vermeiden > indem man Bits weglässt. Danke! genau das meine ich! hier denken alle an ein analogproblem! dem ist nicht so! ALSO HIER NOCHMAL FÜR ALLE!!!!: ich nem den internen 10bit wandler! ich brach sowieso nur 8 bit also les ich die letzten zwei bits erst gar nicht aus. Folgendes szenario: das poti steht genau zwischen wert 191 und 192 (von 8bit = 0 bis 255). Da zappelt NICHT NUR DAS LETZTE BIT!!! 191 = b10111111 192 = b11000000
Ich bin auch für Hysterese. Pseudocode:
1 | Schleifenstart |
2 | |
3 | ADCneuwert := ADC (Poti mit 10 Bit messen und nach ADCneuwert zuweisen) |
4 | ist absolut(ADCneuwert - ADCaltwert) größer 3 (Hysterese) |
5 | dann |
6 | ADCaltwert wird zu ADCneuwert (Altwert für neuen Vergleich belegen) |
7 | ADCneuwert zweimal nach rechts shiften (macht 8 Bit Wert) |
8 | Ergebnis = ADCneuwert (entzappelter Wert steht zur Verfügung) |
9 | ende Bedingung |
10 | . |
11 | . |
12 | Schleifenende |
Ulrich H. schrieb: > Filterung (Mittelwert oder besser wohl Median), die kostet aber relativ > viel Zeit. Wenn man ein IIR-Filter verwendet, braucht man, i.e. der µC, nur ein paar Schiebeoperationen und Addition/Subtraktion für die Mittelwertbildung, z.B.
1 | y[i+1] = (k * y[i] - y[i] + x[i]) / k |
2 | |
3 | mit k=2^m, y[] Mittelwert, x[] Abtastwert |
Ulrich H. schrieb: > Was hilft ist Hysterese - damit man dann nicht nur jeden 2. Wert > erhalten kann, macht man die Hysterese (oder Totband) mit der vollen (10 > Bit) Auflösung und schneidet dann auf 8 Bit runter. Danke Ulich!!! ich habs befürchtet dass ich mehr als 8bit auswerten muss um das mit der Hyterese ordentlich hin zu bekommen. Mal schaun ab sich das dann noch mit meinem zeitraster von 44usec ausgeht.
hystel schrieb: > Ich bin auch für Hysterese. mal schaun ob das noch in mein 44usec raster passt. aber es wäre der richtige ansatz/lösung!
Mike schrieb: > Wenn man ein IIR-Filter verwendet, braucht man, i.e. der µC, nur ein > paar Schiebeoperationen... Mike kannst du mir das bitte genauer erklären!? es klingt vielversprechend wenn es schlank ist! Weil ich alle 44usec eins von 20 potis + taster und noch einiges andere erledigen muss
Ich tendiere 256 zu addieren, und dann durch 16 zu teilen. Macht 4 bit zusaetzlich.
stift schrieb: > Das wär ja ok aber leider folgendes problem: > wenn der neue wert die 3 ist und die änderung mind. 2 sein muss dann > komm ich weder auf die 4 noch auf die 2! > usw. als halbierte auflösung :( Soweit ich gelesen habe, hat das noch niemand verständlich richtig gestellt. Du kommst von der 3 nicht direkt auf die 2 oder 4, also wenn du das Potentiometer um 'eine Stelle' weiterstellst. Allerdings hast du bei dieser Lösung nicht nur die halbe Auflösung, weil du jeden Wert erreichen kannst, wenn er nur mehr als 1 vom vorherigen Wert abweicht. Die 4 erreichst du zum Beispiel, wenn du von 3 auf 56 springst und dann wieder auf 4. Damit hast du die volle Auflösung von 256 Werten. Ich nehme an, dass du dein Potentiometer sowieso nicht um so kleine Beträge verstellen wirst, dass der Wert direkt von 3 auf 4 springen müsste. Wenn doch, löst das dein Problem natürlich nicht.
>So ist das nun mal. So ein AD-Wandler zappelt immer. >Entweder macht man den Analogteil besser, oder man muss damit leben. >Bei einem 10-Bit Atmel lass ich immer gleich 2 weg. Ich hatte auch mal >einen 24 bittigen Wandler. Da zappelten die letzten 4 Bit auch nur >herum. Also gleich ma 4 Bit weg. Gratuliere, dann hast du schon einen sehr ordentlichen Signalpfad auf der analogen Seite desigend - hab nur knapp 18/19 bit erreicht. :D Gruß Jonas
Dussel schrieb: > stift schrieb: >> Das wär ja ok aber leider folgendes problem: >> wenn der neue wert die 3 ist und die änderung mind. 2 sein muss dann >> komm ich weder auf die 4 noch auf die 2! >> usw. als halbierte auflösung :( > Soweit ich gelesen habe, hat das noch niemand verständlich richtig > gestellt. Du kommst von der 3 nicht direkt auf die 2 oder 4, also wenn > du das Potentiometer um 'eine Stelle' weiterstellst. Allerdings hast du > bei dieser Lösung nicht nur die halbe Auflösung, weil du jeden Wert > erreichen kannst, wenn er nur mehr als 1 vom vorherigen Wert abweicht. > Die 4 erreichst du zum Beispiel, wenn du von 3 auf 56 springst und dann > wieder auf 4. Damit hast du die volle Auflösung von 256 Werten. Ich > nehme an, dass du dein Potentiometer sowieso nicht um so kleine Beträge > verstellen wirst, dass der Wert direkt von 3 auf 4 springen müsste. Wenn > doch, löst das dein Problem natürlich nicht. ja ich muss auf so kleine werte reagieren können
stift schrieb: > ja ich muss auf so kleine werte reagieren können Dann benutze, verdammt noch mal, die ganzen zehn Bit, die die ADC liefert, um die Hysterese zu realisieren. Dann hast du eine Hysterese, die das LSB-Wackeln verhindert und trotzdem deine urprüngliche 8-Bit-Auflösung. Das gilt natürlich nur, wenn auch bei 10 Bit nur das Bit 0 wackelt, also die das Teil immer nur zwischen zwei benachbarten Meßwerten hin- und herschwankt. Ist die Schwankung also größer 1, mußt du entweder den Hardware-Aufbau verbessern oder Mittelwert bilden, um das Rauschen soweit runterzudrücken, daß auch bei 10 Bit nur noch das LSB wackelt. Wenn du das geschafft hast, dann implementierst du eine Hysterese von 2. Und dann schiebst du das Ergebnis zwei Bits nach rechts. Damit hast du du genau die Auflösung, die du jetzt auch hast und bemerkst von der Hysterese exakt garnix mehr, weil die nämlich kleiner ist, als du mit dieser Auflösung überhaupt darstellen kannst. Bezogen auf das 8Bit-Ergebnis ist sie effektiv dann nämlich nur noch 0,5.
короткое троль schrieb: > Ich tendiere 256 zu addieren, und dann durch 16 zu teilen. Macht 4 > bit > zusaetzlich. das macht leider gar keinen sinn! siehe: x *= 256 ist das selbe wie x<<8 x /= 16 ist das selbe wie x>>4 das lustiges hin und her geschiebe :) man hat zwar hinten 4bits mehr die aber genau so aussagekräftig sind wie ein stein. du hast nur den wertebereich verschoben. von 1-255 auf 16-271
c-hater schrieb: > stift schrieb: > >> ja ich muss auf so kleine werte reagieren können > > Dann benutze, verdammt noch mal, die ganzen zehn Bit! oh ja verdammt du hast recht. ist sicher die schlankste und profesionellste lösung. aber das ergebniss wird gut sein. ich wollt ja vermeiden mit 16bit variablen zu arbeiten. ausserdem hab ich ja 20 potis und muss dadurch auch 20 "altwerte" a 2byte = 40 byte buffern. ich werd mir mal die beiden LSBits ansehn und hoffen das sie ned zu sehr zappeln :P
stift schrieb: > Mike kannst du mir das bitte genauer erklären!? Stimmt, da habe ich eine Zwischenvariable z für die Summe unterschlagen, die einen Faktor k größer als y[i] bzw. x[i] skaliert ist. Also noch mal:
1 | z[i+1] = z[i] - y[i] + x[i] |
2 | y[i+1] = z[i+1] / k |
3 | |
4 | mit k=2^m, y[] Mittelwert, x[] Abtastwert |
So sollte das passen, sorry ;-)
Mike schrieb: > stift schrieb: >> Mike kannst du mir das bitte genauer erklären!? > > Stimmt, da habe ich eine Zwischenvariable z für die Summe unterschlagen, > die einen Faktor k größer als y[i] bzw. x[i] skaliert ist. > > Also noch mal: z[i+1] = z[i] - y[i] + x[i] > y[i+1] = z[i+1] / k > > mit k=2^m, y[] Mittelwert, x[] Abtastwert > > So sollte das passen, sorry ;-) danke aber sorry i raffs voll nicht! kannst du mir die variablen k, y, m, z durch was aussagekräftiges ersetzen. zB altWert, neuWert... ersetzen!? es geht nicht ums stumpfe abschreiben, ich möchts nachvollziehen können was da passiert. Danke nochmals!
stift schrieb: > > ja ich muss auf so kleine werte reagieren können Was soll das überhaupt werden? Davon hängt ab, wie du am besten vorgehst (Hysterese, Entprellen, so langsam Aktualisieren, dass der Mensch mitkommt, Mittelwerte bilden, etc etc)
stift schrieb: > kannst du mir die variablen k, y, m, z durch was > aussagekräftiges ersetzen. Zum Initialisieren setzt du y_alt auf den ersten Messwert x und z_alt auf x*k, wobei k immer eine ganze Zweiterpotenz ist, also 2, 4, 8, ... Dann rechnest du mit jedem neu reinkommenden x z_neu = z_alt - y_alt + x y_neu = z_neu / k z_alt = z_neu y_alt = y_neu Das entsprich der IIR-Gleichung y = (k-1)/k * y + 1/k * x
Jürgen S. schrieb: > stift schrieb: >> >> ja ich muss auf so kleine werte reagieren können > > Was soll das überhaupt werden? > > Davon hängt ab, wie du am besten vorgehst (Hysterese, Entprellen, so > langsam Aktualisieren, dass der Mensch mitkommt, Mittelwerte bilden, etc > etc) ein lichtstellpult. im unteren bereich ist es wichtig das hier jedes bit aufgelöst wird und auf keinen fall zappelt wenn der user nur ein paar mm den fader hochzieht und dann vlt auch noch da stehen lässt. keines falls darf es zwischen den werten 0 und 1 zappeln da viel scheinwerfer eine 1 als „mach was" verstehen und eine 0 als "stop" verstehend. die werte ab 2 bist ca. 30 sollten auch noch brav steppen da hier einen step oft schon vom publikum wargenommen wird. alles darüber ist nicht mehr so tragisch. die 255 muss halt auch zuverlässig angefahren werden. ist oft ein "full" befehl für angeschlossene geräte
Mike schrieb: > stift schrieb: >> kannst du mir die variablen k, y, m, z durch was >> aussagekräftiges ersetzen. > > Zum Initialisieren setzt du > y_alt auf den ersten Messwert x und > z_alt auf x*k, > wobei k immer eine ganze Zweiterpotenz ist, also 2, 4, 8, ... > > Dann rechnest du mit jedem neu reinkommenden x > > z_neu = z_alt - y_alt + x > y_neu = z_neu / k > z_alt = z_neu > y_alt = y_neu > > Das entsprich der IIR-Gleichung y = (k-1)/k * y + 1/k * x DANKE dir! habs im ansatz schon mal verstanden und werd mich damit spielen :)
Ach, ein Lichtstellpult mit echten, LINEAREN 256 Helligkeiten. Dein Problem ist nicht der ADC, auch nicht die Auflösung, sondern ungenügendes Nachdenken deinerseits. Nimm die vollen 10 Bit, mach nen gleitenden Mittelwert über z.B. 16 Samples, bau dir die vorgeschlagene Hysterese um 2..3 Bit Differenz ein und mach dann zum Schluß eines: Geh damit (als Index, nach Bitreduktion) in eine Tabelle, die eine gekrümmte Kennlinie dir macht: also am Anfang ganz sachte und dann mit zunehmender Steigung, zum Schluß wieder sachte, damit deine Grobmotoriker am Steuerpult zuverlässig Null und Full hinkriegen. W.S.
Der Teil mit der Hysterese und dem Mitteln sind getrennte Bereiche. Der eine kann den anderen nicht ersetzen ! Das Mitteln oder ggf. auch einen Medianfilter kann man nutzen, falls die analoge Schaltung zu viel Rauschen hat, die Schwankungen da also deutlich mehr als 2 LSB ausmachen. Wenn der analoge Teil gut ist, braucht man die Mittelung nicht. Die Hysterese kann das hin und her schwanken des beseitigen. Der Angezeigte Wert bleibt dann halt bevorzugt beim alten kleben. Diese Funktion kann das Mitteln oder ein höher auflösender AD Wandler nicht erreichen. Ein genügend geringes Rauschen ist aber Voraussetzung damit es mit einer sehr kleine Hysterese geht.
W.S. schrieb: > Ach, ein Lichtstellpult mit echten, LINEAREN 256 Helligkeiten. > Dein Problem ist nicht der ADC, auch nicht die Auflösung, sondern > ungenügendes Nachdenken deinerseits. > > Nimm die vollen 10 Bit, mach nen gleitenden Mittelwert über z.B. 16 > Samples, bau dir die vorgeschlagene Hysterese um 2..3 Bit Differenz ein > und mach dann zum Schluß eines: Geh damit (als Index, nach Bitreduktion) > in eine Tabelle, die eine gekrümmte Kennlinie dir macht: also am Anfang > ganz sachte und dann mit zunehmender Steigung, zum Schluß wieder sachte, > damit deine Grobmotoriker am Steuerpult zuverlässig Null und Full > hinkriegen. > > W.S. meines wissens arbeiten alle einfachen pulte linear. da werd ich dem lichttechniker sicher keine andere dimmerkurve / arbeitsweise aufzwingen!! ausserdem stellt man die dimmerkurven in den dimmern bzw. lampen ein sofern das gewünscht. Ausserdem ist eine Dimmerkurve bei LTP kanälen nachteilig!
stift schrieb: > короткое троль schrieb: >> Ich tendiere 256 zu addieren, und dann durch 16 zu teilen. Macht 4 >> bit >> zusaetzlich. > > das macht leider gar keinen sinn! siehe: > x *= 256 ist das selbe wie x<<8 > x /= 16 ist das selbe wie x>>4 > das lustiges hin und her geschiebe :) > man hat zwar hinten 4bits mehr die aber genau so aussagekräftig sind wie > ein stein. du hast nur den wertebereich verschoben. von 1-255 auf 16-271 Addieren ist "Plusrechnen", also nicht <<8, sondern +256 ;) Den sinn kann ich dennoch nicht nachvollziehen. stift schrieb: > c-hater schrieb: >> stift schrieb: >> >>> ja ich muss auf so kleine werte reagieren können >> >> Dann benutze, verdammt noch mal, die ganzen zehn Bit! > > oh ja verdammt du hast recht. ist sicher die schlankste und > profesionellste lösung. aber das ergebniss wird gut sein. > ich wollt ja vermeiden mit 16bit variablen zu arbeiten. ausserdem hab > ich ja 20 potis und muss dadurch auch 20 "altwerte" a 2byte = 40 byte > buffern. > ich werd mir mal die beiden LSBits ansehn und hoffen das sie ned zu sehr > zappeln :P Sind 40Byte so viel? Das is doch nichts. Und die beiden unteren Bits müssen auch wackeln, wenn selbst das 2^2 Bit wackelt, was im Moment das LSB bei deinen 8Bit ist. Du meintest ja, dass du nen 10bit Wandler hast und nur die höchsten 8 Bit nimmst.
Michael Skropski schrieb: > Addieren ist "Plusrechnen", also nicht <<8, sondern +256 ;) Den sinn > kann ich dennoch nicht nachvollziehen. Wobei hier sicherlich gemeint war: 256 Werte addieren, dann durch 16 teilen. Software-Oversampling, siehe u.a. Atmel Appnote irgendwas.
Michael Skropski schrieb: > Und die beiden unteren Bits müssen auch wackeln, wenn selbst das 2^2 Bit > wackelt, was im Moment das LSB bei deinen 8Bit ist. Du hast das offensichtlich nicht wirklich begriffen. Mit "Wackeln im LSB" ist nicht gemeint, daß tatsächlich nur das unterste Bit wackelt, es können dabei durchaus auch alle Bits wackeln, z.B., wenn die Analogspannung genau an der Grenze liegt, an dem bei 8Bit-Auflösung ständig zwischen dem Wert 127 und 128 umgeschaltet wird. Dann wackeln natürlich alle Bits im Ergebnis: 127 -> 0111 1111 128 -> 1000 0000 Bei 10Bit analog an der Grenze zwischen 511 und 512: 511 -> 01 1111 1111 512 -> 10 0000 0000 Tatsächlich gewackelt hat aber in beiden Fällen nur das LSB. Was tatsächlich wackelt, bekommt man übrigens raus, indem man bei konstanter Eingangsspannung eine bestimmte Zahl Meßwerte aufzeichnet, daraus den höchsten und niedrigsten wählt und dann die Differenz aus diesen beiden bildet. Das höchste gesetzte Bit dieser Differenz zeigt an, was wackelt, nämlich dieses Bit und alle die kleiner sind. In beiden obigen Beipielen würde 1 rauskommen, also nur Bit0, das LSB wackeln. Und dieses Wackeln im LSB ist unvermeidbar, weil es immer irgendwo eine Grenze zwischen zwei benachbarten ADC-Werten gibt und der Mittelwert der analogen Eingangsspannung beliebig nahe an dieser Grenze liegen kann. Damit kann das Rauschen, welches dann zu diesem Wackeln führt, beliebig klein werden. Und das es durch den Quantencharakter der Ladungsträger kein völlig rauschfreies Eingangssignal geben kann, ist dieses LSB-Wackeln eben unvermeidbar. Dagegen hilft auch keine Mittelwertbildung (mit einer endlichen Zahl von Einzelmessungen), auch da kann prinzipiell immer noch das LSB wackeln, es wird nur seltener wackeln, die Mittelwertbildung ist nämlich nichts anderes als ein Tiefpaß, der die höheren Frequenzanteile des Rauschens wegfiltert, aber nicht das Rauschen insgesamt entfernen kann. Das kann nur eine Hysterese, die größer ist als das "Wackeln". Da, wie oben dargestellt, Wackeln um 1 absolut unvermeidbar ist, muß die Hysterese mindestens 2 sein.
stift schrieb: > meines wissens arbeiten alle einfachen pulte linear. da werd ich dem > lichttechniker sicher keine andere dimmerkurve / arbeitsweise > aufzwingen!! OK, dann lebe eben mit dem was du grad hast - aber ärgere die anderen nicht damit, daß du dich über das Schwanken von 7Fh auf 80h und zurück beklagst, wenn der Schleifer grad auf der Grenze zwischen beiden steht. Genügend Vorschläge zum Lösen des Problems gab es ja bereits. W.S.
Die Lösung ist simpel: "ADC" sei der aktuelle ADC-Wert "ADC_alt" sei der vorangegangene ADC-Wert "Noise" sei die Variable, mit der die Filterbreite (Hysterese) nach Belieben festgelegt wird. Prinzip: If (ADC - ADC_alt > Noise) OR (ADC_alt - ADC > Noise) Then Wert_ok=1 Else Wert_ok=0 End if ADC_alt=ADC Mit ADC_alt kannst du dann weiterarbeiten, wenn Wert_ok=1 ist. Er enthält den letzten aktuellen Wert, der die Hysterese mit dem Betrag "Noise" über- oder unterschritten hatte.
Simpel schrieb: > Die Lösung ist simpel: > > "ADC" sei der aktuelle ADC-Wert > "ADC_alt" sei der vorangegangene ADC-Wert > "Noise" sei die Variable, mit der die Filterbreite (Hysterese) nach > Belieben festgelegt wird. > > Prinzip: > > If (ADC - ADC_alt > Noise) OR (ADC_alt - ADC > Noise) Then > Wert_ok=1 > Else > Wert_ok=0 > End if > > ADC_alt=ADC > > Mit ADC_alt kannst du dann weiterarbeiten, wenn Wert_ok=1 ist. Er > enthält den letzten aktuellen Wert, der die Hysterese mit dem Betrag > "Noise" über- oder unterschritten hatte. Die If Abfrage wird so nicht richtig funktionieren, denn wenn z.B. bei (ADC - ADC_alt > Noise) ADC_alt größer ist, kommt ne negative Zahl raus, oder du bekommst einen Underflow je nach Variablentyp. Und wenn er einen underflow bekommt geht er immer rein, denn dann ist der Wert ja bei unsigned char z.b. wenn der unterschied 1 ist auf 254 und das ist bestimmt größer als "Noise" Man muss die beiden Variablen vorher subtrahieren und den Betrag bilden, dann erst die IF.
Sonntagmorgen-Effekt... Gäähn... :-) So natürlich: If (ADC - ADC_alt > Noise) OR (ADC_alt - ADC > Noise) Then Wert_ok=1 ADC_alt=ADC Else Wert_ok=0 End if
@dirk ja klar, das mit dem Under- Overflow und die richtige Variablenauswahl muss nat. separat gechecked werden. Es ging mir nur um die variable Hysterese, die nicht einfach durch weglassen von Bits erreicht werden kann.
1 | ADC_neu=ADC; |
2 | |
3 | diff=ADC_alt-ADC_neu; |
4 | |
5 | diff &= ~(1<<15); //Betrag Bilden (signed int) |
6 | |
7 | if(diff>=2) |
8 | {
|
9 | ADC_alt=ADC_neu; |
10 | }
|
Udo Schmitt schrieb: > Und lass die völlig doofe Unsitte Vcc als Referenz zu nehmen. Die hat > einen Haufen Brumm wegen dem Digitalteil und ist sowiezo 10 mal > ungenauer als dein letztes Bit. Das ist aber völlig egal, wenn am Eingang ein Poti angeschlossen ist, das auch daraus versorgt wird. > Nimm also eine externe oder die interne Referenz, sonst kannst du gleich > die letzten 3 Bits wegwerfen. Dann muß er aber auch das Poti mit an die Referenz hängen, was wohl eher nicht geht.
Rolf Magnus schrieb: > Das ist aber völlig egal, wenn am Eingang ein Poti angeschlossen ist, > das auch daraus versorgt wird. Ratiometrisch, ist schon richtig, aber: Das ist nur dann egal, wenn er darauf achtet, daß sowohl Masse als auch Aref Anschluss des Potis und des µCs an der gleichen Stelle sind. Sonst fängt man sich jede Menge Schmutz vom Digitalteil ein. Ausserdem hat man nicht immer nur ein Poti dran, aber man sieht hier immer wieder Threads wo die Leute 12 oder 16 Bit messen wollen und völlig unbedarft die Versorgungsspannung als Referenz nehmen.
Hab nicht mehr alles gelesen und es kann sein das es hier schon jemand geschrieben hat. Wenn nur der relative Wert des Potis interressiert kann man doch die Betriebsspannung = Eingangsspannung ADC machen. Damit (falls es an der nicht konstanten Spannung liegt) beide gleich schwanken. Hat damals gut funktioniert
dirk h. schrieb: > diff &= ~(1<<15); //Betrag Bilden (signed int) Äh, ich bezweifle gerade, dass das funktioniert. Schau mal nach Zweier Komplement. diff = diff < 0 ? -diff : diff klappt da schon eher, ist sicherer, klappt bei jeder typgröße und kann der compiler schön optimieren.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.