Forum: Mikrocontroller und Digitale Elektronik Oversampling berechnung


von Matthias (Gast)


Lesenswert?

Ich versuche gerade meinen 12 Bit A/D Wandler mit oversampling zu 
betreiben.

Nun mache ich eine Blockbildung von 256 10 Bit Werten und benötige als 
Zwischenspeicher ein mindestens 20 bit Variable. Ich verwende das 
unsigned long Format.

Nach der 256 x 10 Bit Addition muss ich nun eine 4 Bit right Shift 
operation durchführen.

block = block >> 4;

Ist das korrekt so, werden nun 4 Nullen von links eingeschoben?

Danach muss eine konvertierung von 32 Bit long auf 16 Bit int erfolgen.

Kann das der atmel automatisch, wenn der Wert der 32 Bit long Variable 
den Zahlenbereich der 16 Bit Variable nicht überschreitet oder wie 
schreibt man solch eine konvertierung?

Vielen Dank für die Hilfe,  ich habe da große Defizite in Sachen 
richtiger Syntaxschreibweise.

von rechen (Gast)


Lesenswert?

Musst du nicht durch 256 teilen - also 8 nach rechts shiften?

Abgesehen davon sind 256 Messungen relativ viel. Bei wenig Rauschen 
reicht es wenn du über z.B. 16 mittelst.

von Matthias (Gast)


Lesenswert?

Laut Atmels Application Notes nicht und es macht auch sinn 4 Bit zu 
shiften.

Nehmen wir 256 * 12 Bit maximale zahl = 256 * 4096 = 1048576
Dies entspricht einer 20 Bit Zahl: 2^20 = 1048576

Um nun nach dem Oversampeln meine gewünschte 16 Bit Auflösung zu 
erhalten, muss ich um 4 Bit shiften und in eine 16 Bit Zahl wandeln.

von Bernd N. (Gast)


Lesenswert?

Auf 16 BIT zu skalieren halte ich für sehr optimistisch. Für 2 BIT mehr 
sind die ADC's ok aber ich mittel dann über 512 Messungen.

Du gibst leider den MC Typ nicht an... wäre hilfreich wenn man sich da 
hinein denken soll. Du sagst 12 BIT ADC ist "an Board".

>> Nun mache ich eine Blockbildung von 256 10 Bit Werten

Verstehe ich nicht.

von Matthias (Gast)


Lesenswert?

Es gibt eine Atmel application Note

http://www.atmel.com/dyn/resources/prod_documents/doc8003.pdf

an die ich versucht habe mich zu halten.

>> Auf 16 BIT zu skalieren halte ich für sehr optimistisch. Für 2 BIT mehr
>> sind die ADC's ok aber ich mittel dann über 512 Messungen.

In dieser Note wird die Auflösung eines 10 Bit AD Wandlers auf bis zu 16 
Bit erhöht.

Dort wird das Oversampling erklärt, indem eine Blockbildung von 4^(Bit 
zur höheren Auflösung) Werten aufaddiert wird und dann ein right shift 
um die Anzahl der erhöhten Auflösung durchgeführt wird.

Dann kann man noch zur Noiseunterdrückung ein normales Average von z.B. 
25 Werten durchführen.

Bei mir habe ich nun die Auflösung deutlich steigern können und mein 
Sensorsignal wurde deutlich genauer.

von Mr Engineer (Gast)


Lesenswert?

In dem Text steht aber auch, dass durch "normales Averaging" die 
Auflösung nicht erhöht werden kann!!!! (Mit averaging bekommst du 
vermutlich kein Filter hin, das die nötige Flankensteilheit im Spektrum 
hat um das Quantisierungsrauschen gut raus zu bekommen)

von Karl H. (kbuchegg)


Lesenswert?

Matthias schrieb:

>>> Auf 16 BIT zu skalieren halte ich für sehr optimistisch. Für 2 BIT mehr
>>> sind die ADC's ok aber ich mittel dann über 512 Messungen.
>
> In dieser Note wird die Auflösung eines 10 Bit AD Wandlers auf bis zu 16
> Bit erhöht.

Die Frage ist allerdings:
Was haben die untersten Bits noch mit der tatsächlich zu messenden 
Spannung gemeinsam, oder sind die nur noch zufälliges Rauschen.

Wenn ich will kann ich auch durch Aufsummieren von beliebig vielen 
Werten auf 32 Bit Werte kommen. Nur werden die untersten ~20 Bits nichts 
mehr mit der tatsächlich zu messenden Spannung zu tun haben.

Irgendwann macht es einfach keinen Sinn mehr, noch mehr Bits 
rauszuquetschen.

von Karl H. (kbuchegg)


Lesenswert?

> Nach der 256 x 10 Bit Addition muss ich nun eine 4 Bit right Shift
> operation durchführen.
>
> block = block >> 4;
>
> Ist das korrekt so, werden nun 4 Nullen von links eingeschoben?

Kann man so nicht sagen, wenn man die Datentypen nicht kennt.

Im übrigen: Lass den Compiler entscheiden ob das mittels Shift gemacht 
wird oder nicht. Konzeptionell ist das für dich eine Division, also 
schreib das auch als Division.

Du hast 256 Werte aufsummiert.
Wenn du die Summe dann nicht durch 256, sondern durch 128 dividierst, 
hast du 1 Bit gewonnen
Dividierst du durch 64, hast du 2 Bit gewonnen.
etc.

Und noch was: Bring erst mal deine Bitzahlen in deiner Beschreibung auf 
die Reihe.
Am Anfang hattest du einen 12 Bit ADC
Dann sprichst du von 10 Bit ADC Werten
Dann willst du 4 Bits gewinnen (bei 10 Bit ADC Werten kommen daher 14 
Bit Zahlen raus). Urplötzlich tauchen dann 16 Bit Zahlen auf
etc.

von Stefan W. (Firma: WhyLee) (whylee)


Lesenswert?

Hallo Karl Heinz!

Erst mal kurz was theoretisches, damit man den Sinn von Oversampling am 
Analogeingang vielleich etwas besser versteht:
Wenn du am Analogeingang ein ideales (nicht verrauschtes Signal hast mit 
z.B. 0-255mV und du willst alleine durch das Oversampling eine 
verbesserte Genauigkeit erzielen um z.B. Spannungen von 10,0mV und 
10,25mV unterscheiden zu können, dann wirst du scheitern.
Denn bei einem Eingangssignal von exakt 10,25mV (unverrauscht!) wird ein 
8-Bit Wandler der von 0 bis 255mV geht immer 10mV einlesen.
Auch wenn du 100 Messwerte zusammenzählst und dann durch 100 dividierst.
==> (100*10mV)/100 = 10mV

Aber - und jetzt kommt der wichtige Teil:
Es gibt Rauschen (kann dein Freund oder dein Feind sein).
Wenn dieses Rauschen im Beispiel von oben einen Hub von +/-1mV hat, dann 
haben wir eine Addition des Rauschens von +/-1mV zu dem zu messenden 
Wert von 10,25mV.
D.h. wir haben eine reale Schwankung zwischen 09,25mV und 11,25mV.

Jetzt können wir die gewandelten A/D-Werte mitteln, einige davon sind 
bei 10mV, einige davon 11mV und einige davon 9mV. Bei der Mittelung über 
unendlich lange Zeit kommen dann exakt 10,25mV raus.

Man sieht also hier, daß man zum Messsignal eine Rauschen braucht, das 
mindestens 1LSB hoch ist um das Einangssignal um ein LSB 'herum heben' 
kann.

Es gibt aber auch noch viel bessere Methoden Mittelwerte zu berechnen.
z.B.
neuer_Mittelwert = (neuer_Mittelwert * 63 + neu gewandelter Wert)/64

Da braucht man eine höhere Auflösug und man kann das umformen:

neuer_Mittelwert_64 = neuer_Mittelwert_64 - (neuer_Mittelwert_64/64) + 
neu gewandelter Wert

Mittelwert = neuer_Mittelwert_64/64

Wenn dein Rauschen nicht so groß ist, dann mußt du entweder ein Rauschen 
hinzufügen, oder ein Sägezahnsignal hinzufügen, wo du synchon mehmals 
pro Sägezahnperiode abtastest.

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.