Forum: Mikrocontroller und Digitale Elektronik ADC Rauschen beim Bitwechsel


von Henning (Gast)


Lesenswert?

Hallo,

ich war scheinbar ausreichend geschickt, und habe bei meinem ADWandler 
(im ATMega128) ein Rauschen von unter einem Digit erreicht.

Aber anstatt, das ich es jetzt geschafft hätte: Beim Wechsel des 
Eingangssignals über die Grenze zwischen zwei Digit kommt das restliche 
Rauschen zum Tragen.

Das schaut dann z.B. so aus:
_______ ___  __   
           __  ___ ______

Wenn man's sich anguckt, kann man prima erkennen, das es sich angenähert 
um eine Gerade handelt, und im Grenzbereich, das Rauschen halt zum hin 
und Herr springen führt.

Wie kann ich das vermeiden? Was sind da die üblichen Techniken?

Mein Gedanke: Eine Grenze an der dieser Effekt auftritt wird es immer 
geben. Ob es nun ein 1 Bit oder 100-Bit AD-Wandler ist, irgendwo ist 
nunmal eine Grenzen.

Einen Mittelwert zu bilden führt auch nicht zum erfolgt, wenn sich das 
Signal längere Zeit im Grenzbereich aufhält, führt das auch am Ausgang 
des Mittelwertes zum springen.
(Es geht um einen Temperatursensor --> alles ist langsam.)

Die Lösung währe wohl eine Hysterese, per SW konstruiert, geht jedoch 
ein Bit des ADW dafür drauf. :-/ Das müsste ich mir dann wieder durch 2 
oder 4 Wandlungen oder -ergenisse erkaufen kaufen.

Jemand eine bessere Idee?

evtl. Abtastrate senken?

Was mir noch nicht ganz klar ist: FIR und IIR Filter. Kann man mit 
erträglichem Aufwand die Grenzfrequenz eines Filters bis unter 10Hz 
ziehen?
Aber würde das tatsächlich das Problem lösen? Im Grenzfall (Eingang = 
exakt die Grenze zwischen 2 Digits + Rauschen) würde am Ende ja auch ein 
(geglättetes) Rauschen übrig bleiben.

Danke für jeden Hinweis,

Grüße Henning

von Henning (Gast)


Lesenswert?

Sauber, die unterspreichenfunktion hat meine Skizze gefressen:
ich probiere es nochmal mit punkten:
....... ...  ..   .
       .   ..  ... .........

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Das Rauschen um ein LSB kannst Du nicht vermeiden. Was Du tun kannst, 
ist einen Tiefpaß zu programmieren, indem Du eine größere Anzahl 
Messungen aufaddierst und das Ergebnis dann durch die Anzahl der 
Messungen teilst. Geht besonders einfach bei 256 Messungen, da dann das 
Ergebnis um genau eine Registerbreite von 8Bit verschoben ist und nur 
noch aus den höherwetigen Übergaberegistern gelesen zu werden braucht 
ohne noch die Division ausführen zu müssen.

von neeeee (Gast)


Lesenswert?

Das bereits erreichte Resultat ist sehr gut. Ich wuerd's so lassen. 
Ausser man haette zuviel Bandbreite und koennte mitteln. Aber was 
bringt's ?

von eProfi (Gast)


Lesenswert?

Du kannst das Umkippen des letzten Bits auch zeitabhängig machen.
Wenn nur das letzte Bit klappert, über 5 Sekunden mitteln und dann 
Runden.
Falls die Änderung mehr als 1 Bit ist, sofort durchgeben.

von Hennin G. (Gast)


Lesenswert?

Danke schonmal für die Beiträge.

Wie oben beschrieben hilft ein Filter nur bedingt:
Wenn ein Mittelwert aus 5,6,5,6,5,6,5,6,5,6,5,6,5,6, gebildet wird, 
kommt dabei 5,5 raus --gerundet--> 6
kommt als nächstes eine 5, ist der mitterwert aber 5,47 raus --> 5
ein Rauschen bleibt also auch wenn die Messzeit länger wird, nur die 
Warscheinlichkeit, das sich das Eingangssignal um 5,5+Rauschen bewegt, 
sinkt dabei.

Es ist tatsächlich nur das letzte Bit, welches sich bewegt. Und das auch 
nur, wenn der zu wandelnde Wert in den Bereich um eine Grenze zwischen 
zwei Digits bewegt.

Ich denke der Tip von eProfi ist schon richtig:
Ich werde wohl die Änderungsrate bestimmen müssen, und bei wenig 
Änderungen die Abtastrate künstlich senken.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Die Abtastrate muß nur so hoch sein, daß Du inklusive Filter noch eine 
effektive Messung auf 1...10 Sekunden machst. Schneller ändern sich 
Temperaturen meistens nicht oder es wäre nicht von Belang. Den ADC 
kannst Du somit alle beispielsweise 1...10 ms 1x single shot messen 
lassen. Die ADC-Wandelfrequenz kannst Du in dem Fall auch bis auf 50kHz 
senken.

von Route_66 (Gast)


Lesenswert?

Alles schön und gut...
Den digitalen Restfehler kann man mit keiner Methode vermeiden.
Wie ja bereits aus dem Beispiel um den Wert 5,5 gezeigt wurde ist immer, 
auch bei Mittelwertbildung, Rundung, geringer Abtastrate usw. bei 
digitaler Signalverarbeitung ein Restfehler durch Kippen des LSB 
vorhanden.
Alle Kurvenglättungsmaßnahmen bringen sicher eine Besserung. In der 
Praxis wird aber der beste Weg sein, die Auflösung des AD-Umsetzers 
midestens ein oder zwei Digit höher zu wählen, als das gewünschte 
Messergebnis. Ebenso ist die Kenntnis über einen Erwartungswert manchmal 
hilfreich. Unerwartete Werte können dann verworfen werden. z.B. ist bei 
Aufheizvorgängen eine ansteigende Kurve zu vermuten. Aber gerade in 
Grenzbereichen, wo der Messwert relativ konstant bleibt, muss man mit 
dem digitalen Restfehler leben.
Es gibt keinen Ausweg.

von koe (Gast)


Lesenswert?

Das sauberste Verfahren:
Kombination von Integration über möglichst mind. 8 Werte, dann
Hysterese auf die 'Nachkommawerte' z.B.
letzter an die Anwendung übertragener W. 135
solange neuer Mittelwert nicht um mehr als 0,6 ... 1,1 abweicht, wird 
kein neuer Wert
an die Anwendung übergeben, d.h. volle Auflösung , aber stark 
reduziertes Pauschen.
Die Hysterese bestimmt das 'Restrauschen' das natürlich nicht ganz zu 
vermeiden ist, zumal ja nicht alle Schritte eines Wandlers gleich sind
(vgl Datenblatt)

von Hennin G. (Gast)


Lesenswert?

Mein Ergebnis, mit dem ich sehr zufrieden bin:
Wenn man zusätzlich die Abtastrate senkt, wird weiter die 
Wahrscheinlichkeit gesenkt, mit der sich der Messwert im Grenzbereich 
zwischen 2 Digits befindet (wie oben beschrieben).

Danke an koe.
1
  #define MaxIBit 3
2
//---Anzahl der Bit, mit der die Auflösung erhöht und wieder gefilter wird
3
  #define MaxI 1<<MaxIBit
4
  static uint16_t arr[MaxCh][MaxI] = { {0,0,0,0,0,0,0,0},
5
                                       {0,0,0,0,0,0,0,0},
6
                                       {0,0,0,0,0,0,0,0},
7
                                       {0,0,0,0,0,0,0,0} };
8
  static uint16_t arrsum[MaxCh] =      {0,0,0,0};
9
  static uint8_t i = 0;
10
11
  uint8_t Ch;
12
13
  i = (i+1) % MaxI;
14
  for (Ch=0; Ch<MaxCh; Ch++)
15
  {
16
    arr[Ch][i] = ReadChannel(Ch) + eeprom_read_word(&eeChXOffset[Ch]);
17
    uint16_t tmp;
18
    tmp = 0;
19
    uint8_t k;
20
    for (k=0; k<(sizeof(arr[Ch])/sizeof(arr[Ch][0])); k++)
21
      tmp += arr[Ch][k];
22
    if (abs(arrsum[Ch]-tmp) > MaxI)
23
    {  
24
      arrsum[Ch] = tmp;
25
      TempChX[Ch] = tmp>>MaxIBit;
26
    }
27
  }

Irgendjemand verbesserungsvorschläge?

von Thomas S. (df1po)


Lesenswert?

Schau dir doch mal die Funktionsweise von Delta-Sigma-Wandlern an. Mit 
der entsprechenden Filterung wird die Auflösung erhöht (wenn im 
Eingangssignale "echtes weisses" Rauschen drinne wäre, dann hackst du 
die unnötigen Bits ab und das Ergebnis steht wie eine 
"1.000000000"...:o)))
Der eogentliche Wandler hat dabei oftmals nur 1 Bit. Da hilft doch die 
Mathematik ein wenig weiter. Ansonsten wäre die Frage, welche 
Genauigkeit überhaupt nötig ist bzw. prinzipiell möglich wäre. Mit 1% 
Fehler im Sensor machen schon 8 Bit oftmals keinen Sinn. Und echte 12 
Bit sind oftmals schon eine unüberwindliche Hürde, wenn reale Bauteile 
zum Einsatz kommen.
Viel Spaß

Thomas

von Hennin G. (Gast)


Lesenswert?

Nach meinem Wissen gibt es keine Möglichkeit, das Wandlungsprinzip eines 
Delta-Sigma-Wandlers per Software zu erweitern, den schließlich wird in 
HW durch den Bitstream eine entsprechende Ladungsmenge in die 
Charge-Balance zurückgeführt, was man per Software nicht ersetzen kann.

Mir geht es nur darum Temperaturänderungen zu erfassen (hohe Auflösung). 
Ob der Gemessene wert wirklich den physikalischen 22°C entspricht 
(Genauigkeit) ist für mich zwar wünschenswert aber nur zweitrangig.

Grüße Henning

von Thomas S. (df1po)


Lesenswert?

Es geht um die statistischen Methoden bei der Delta-Sigma-Wandlung, die 
sehr wohl in Software umgesetzt werden können. Welche 
Temperaturänerungen willst du denn erfassen und welche Sensoren 
verwendest du ? Temperaturmessung ist eine recht heikle Angelegenheit, 
wenn es wirklich kleine Änderungen bzw. hohe Genauigkeit betrifft. Evtl. 
eine passende Differenz-Vorverstärkung einsetzen. Ansonsten sieht das 
ganze doch schon recht ordentlich aus (+- 1 Bit)....

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Mit Oversampling kann das Bitrauschen sogar zur Genauigkeitssteigerung 
ausgenutzt werden. TI beschreibt in einer Appnote (slaa323), wie mit dem 
ADC_12 der MSP430-Familie durch Oversampling mehr effektiv nutzbare Bits 
Auflösung gewonnen werden können.

Ich nutze so etwas mit 256-fach-Oversampling, was mir vier zusätzliche 
Bits einbringt, die erfreulich stabil sind.
Natürlich ist ein anständiges Schaltungsdesign hier erforderlich, auf 
einem "breadboard" wird das nicht funktionieren.

von Hennin G. (Gast)


Lesenswert?

Thomas:
Es geht mir eigentlich nur um den Lerneffekt. Das ganze ist eine 
Schaltung, mit der die Raumtemperatur gemessen wird, und darauf hin über 
ein Ventil der Fußbodenheizung der Regelkreis geschlossen wird.
Die erreichte Auflösung ist also absolut unnötig, wenn man ehrlich ist! 
Alleine die Luftbewegungen im Raum haben einen erheblichen Einfluss auf 
den Messwert so, dass auch bei einer hohen Güte in der 
Signalverarbeitung eigentlich nix gescheites dabei raus kommen kann.
Mir geht es eher darum möglichst viel über die Techniken und 
Möglichkeiten dahinter zu lernen, um für das nächsten Projekt neue 
Freiheitsgrade zu gewinnen.

Aber zurück zum Delta-Sigma-Wandler: Das Prinzip basiert doch auf dem 
Vergleich des Messwertes mit einer Referenz. Das Ergebnis wird 
aufsummiert und dann über einen Komparator (1-Bit ADW) auf größer und 
kleiner entschieden. Dann entweder eine Ladungsmenge der Referenz zu- 
oder abgeführt. Eben dieser Informations-Stream hinter dem Komparator 
kann durch einen Decoder ausgewertet werden, und daraus der Messwert 
bestimmt werden. Am Ausgang (von HW zu SW in der MCU) ist dann aber doch 
eine Binärzahl, und kein Bitstream mehr. Wie meinst du, könnte man dort 
noch eine weiteren Dekodereinheit anschließen? Nocheinmal der Kreislauf? 
Mit einer Referenz2 verrechnen, aufintegrieren, Schwellwert prüfen, 
inc/dec(Referenz2). Man hätte wieder einen Bitstream, den man dekodieren 
könnte. Aber gewinnt man dadurch wirklich Auflösung?

Rufus:
Danke für den Hinweis auf das AppNote. Das gleitende Oversampling 
verwendet ich ja im Code bereits; doch im AppNote wird klar, das die 8 
Samples effektiv 1.5bit bringen.
Es müsste also eigentlich ausreichen, mit 4 Samples zu arbeiten. Dadurch 
würde eff. 1 bit gewonnen, das dann in der Hysterese wieder verbraucht 
werden kann.

von Hennin G. (Gast)


Lesenswert?

Hier das neue Stück Code
Die Geschwindigkeit bei größerem Oversampling Buffer wird erheblich 
Beschleunigt. Pro Kanal kostet das einen weiteren Speicherplatz (in 
diesem Fall uint16_t)
1
  #define MaxIbit 2
2
  #define MaxI (1<<MaxIbit)
3
  static uint16_t arr[MaxCh][MaxI] = { {0},{0},{0},{0} };
4
  static uint16_t arrsumA[MaxCh] =     {0};
5
  static uint16_t arrsumB[MaxCh] =     {0};
6
  static uint8_t i = 0;
7
  uint8_t Ch;
8
9
  i = (i+1) % MaxI;
10
  for (Ch=0; Ch<MaxCh; Ch++)
11
  {
12
    arrsumB[Ch] -= arr[Ch][i];
13
    uint16_t ADCVal;
14
    ADCVal       = ReadChannel(Ch) + eeprom_read_word(&eeChXOffset[Ch]);
15
    arrsumB[Ch] += ADCVal;
16
    arr[Ch][i]   = ADCVal;
17
    if (abs(arrsumA[Ch]-arrsumB[Ch]) > (MaxI/2))
18
    {  
19
      arrsumA[Ch] = arrsumB[Ch];
20
      TempChX[Ch] = arrsumB[Ch]>>MaxIbit;
21
    }
22
  }

von Thomas S. (df1po)


Lesenswert?

Eine recht gute Erklärung verschiedener Techniken ist bei Luminary in 
der AN01239 zu finden.

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.