Forum: Mikrocontroller und Digitale Elektronik der ADC will sich nicht entscheiden!


von stift (Gast)


Lesenswert?

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 :)

von Mike (Gast)


Lesenswert?

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.

von stift (Gast)


Lesenswert?

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?

von dirk h. (Gast)


Lesenswert?

Nein die Auflösung bleibt gleich, nur es hat halt nicht mehr die gleiche 
Genauigkeit. +-1

von Peter II (Gast)


Lesenswert?

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?

von PittyJ (Gast)


Lesenswert?

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.

von TriHexagon (Gast)


Lesenswert?

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.

von stift (Gast)


Lesenswert?

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 :(

von stift (Gast)


Lesenswert?

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

von Peter II (Gast)


Lesenswert?

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.

von Mike (Gast)


Lesenswert?

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.

von stift (Gast)


Lesenswert?

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

von TriHexagon (Gast)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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.

von stift (Gast)


Lesenswert?

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!

von TriHexagon (Gast)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Mach mehrere Messungen und bilde den Mittelwert. Das wird das "Gezappel" 
etwas beruhigen.

von TriHexagon (Gast)


Lesenswert?

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.

von dirk h. (Gast)


Lesenswert?

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.

von Udo S. (urschmitt)


Lesenswert?

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
von Tippsi (Gast)


Lesenswert?

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

von Jens P. (picler)


Lesenswert?

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.

von Fred (Gast)


Lesenswert?

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.

von Zappel-Schnappel (Gast)


Lesenswert?

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.

von dirk h. (Gast)


Lesenswert?

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.

von Mike (Gast)


Lesenswert?

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 ;-(

von Mike (Gast)


Lesenswert?

... oder so ähnlich ;-)

von Ulrich H. (lurchi)


Lesenswert?

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.

von stift (Gast)


Lesenswert?

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

von hystel (Gast)


Lesenswert?

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

von Mike (Gast)


Lesenswert?

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

von stift (Gast)


Lesenswert?

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.

von stift (Gast)


Lesenswert?

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!

von stift (Gast)


Lesenswert?

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

von короткое троль (Gast)


Lesenswert?

Ich tendiere 256 zu addieren, und dann durch 16 zu teilen. Macht 4 bit 
zusaetzlich.

von Dussel (Gast)


Lesenswert?

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.

von Jonas B. (jibi)


Lesenswert?

>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

von stift (Gast)


Lesenswert?

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

von c-hater (Gast)


Lesenswert?

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.

von stift (Gast)


Lesenswert?

короткое троль 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

von stift (Gast)


Lesenswert?

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

von Mike (Gast)


Lesenswert?

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 ;-)

von stift (Gast)


Lesenswert?

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!

von Jürgen S. (starblue) Benutzerseite


Lesenswert?

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)

von Mike (Gast)


Lesenswert?

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

von stift (Gast)


Lesenswert?

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

von stift (Gast)


Lesenswert?

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 :)

von W.S. (Gast)


Lesenswert?

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.

von Ulrich H. (lurchi)


Lesenswert?

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.

von stift (Gast)


Lesenswert?

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!

von Michael S. (rbs_phoenix)


Lesenswert?

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.

von Nobby Nic (Gast)


Lesenswert?

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.

von c-hater (Gast)


Lesenswert?

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.

von W.S. (Gast)


Lesenswert?

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.

von Simpel (Gast)


Lesenswert?

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.

von dirk h. (Gast)


Lesenswert?

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.

von Simpel (Gast)


Lesenswert?

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

von Simpel (Gast)


Lesenswert?

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

von dirk h. (Gast)


Lesenswert?

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
}

von Rolf Magnus (Gast)


Lesenswert?

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.

von Udo S. (urschmitt)


Lesenswert?

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.

von Rast (Gast)


Lesenswert?

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

von Simon K. (simon) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.