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